WPF Binding in ComboBox with UserControl list

前端 未结 2 1694
囚心锁ツ
囚心锁ツ 2021-01-16 02:29

In two combobox A and B. A\'s ItemsSource is Custom list. and B\'s ItemsSource is UserControl list. When manually setting the SelectedItem, A combobox works well, but B comb

2条回答
  •  孤独总比滥情好
    2021-01-16 03:25

    Since you have asked "What is the reason?":

    The reason why the second combo box does not show any selection is that ComboBox handles items of type ContentControl specially. In the read-only selection box, it is not the ContentControl that is used to display the value, but the content of the ContentControl. Since a UserControl is a ContentControl, the content of the UserControl is displayed inside the selection box, and therefore you have lost the data context of the UserControl; in the end, an empty string is displayed even though SelectedItem contains a reference to the UserControl that still has a valid data context. (As far as I know this behavior is undocumented; but you can see that it works like this by examining the ComboBox's code on http://referencesource.microsoft.com/#PresentationFramework/src/Framework/System/Windows/Controls/ComboBox.cs, especially the UpdateSelectionBoxItem() method).

    By setting IsEditable="True" on the second ComboBox, you can see that everything works fine if the combo box has no read-only selection box.

    Therefore, you generally should avoid adding UI elements to combo boxes, especially if you are using the DisplayMemberPath property, i.e. if you never want to actually display the UI element.

    The recommended way to display ComboBox items with non-standard appearance (e.g. with UserControls) is described in the answer of @nit.

    If you, however, insist on passing a UserControl item list to the ComboBox, you might remove DisplayMemberPath and use something like this:

    
        
            
                
            
        
    
    

    Furthermore, in the constructor of your UserControl, you must place this line:

    ((FrameworkElement) Content).DataContext = this;
    

    This is necessary to make sure that the correct data context is available in the read-only selection box, which only contains the content of the user control, not the user control itself.

    Please note, that with the above example, the drop-down list contains text only (i.e. the item names), but the selection box will contain the fully rendered user control.

提交回复
热议问题