WPF Binding in ComboBox with UserControl list

前端 未结 2 1658
囚心锁ツ
囚心锁ツ 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:11

    This is not the good way of achieving this. Better define the ItemTemplate for the combobox to have the UserControl in it like:

      <ComboBox ItemsSource="{Binding ItemList}" SelectedItem="{Binding SelectedItem}" >
            <ComboBox.ItemTemplate>
                <DataTemplate>
                    <myControls:MyUserControl/>
                </DataTemplate>
            </ComboBox.ItemTemplate>
        </ComboBox>
    

    and define the class Item

    public class Item
    {
        public string ItemName { get; set; }
    }
    
    ObservableCollection<Item> _ItemsList = new ObservableCollection<Item>();
    public ObservableCollection<Item> ItemsList 
    {
        get
        {
            return _ItemsList ;
        }
        set
        {
            _ItemsList = value;
            OnPropertyChanged();
        }
    }
    

    Here DataContext of your UserControl will be Item object. you can bind the ItemName within you user control to show it in anyway you want.

    in your user control you can have:

     <TextBlock Text="{Binding ItemName}"></TextBlock>
    
    0 讨论(0)
  • 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:

    <ComboBox ItemsSource="{Binding UserControlList}" SelectedItem="{Binding SelectedUserControl}" >
        <ComboBox.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding ItemName}"/>
            </DataTemplate>
        </ComboBox.ItemTemplate>
    </ComboBox>
    

    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.

    0 讨论(0)
提交回复
热议问题