且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

WPF绑定在ComboBox与UserControl列表

更新时间:2022-06-19 08:27:55

原因是什么?:

第二个组合框没有显示任何选择的原因是 ComboBox 处理类型 ContentControl 的项目。在只读选择框中,不是用于显示值的 ContentControl ,而是 ContentControl 。由于 UserControl ContentControl ,因此 UserControl 显示在选择框内,因此您丢失了 UserControl 的数据上下文;最后,即使 SelectedItem 包含对仍然具有有效数据的 UserControl 的引用,也会显示一个空字符串上下文。 (据我所知,这种行为是无记录;但你可以看到它的工作原理是这样的,通过检查ComboBox的代码 http://referencesource.microsoft.com/#PresentationFramework/src/Framework/System/Windows/Controls/ComboBox.cs ,尤其是UpdateSelectionBoxItem()方法)。

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).

通过在第二个ComboBox上设置 IsEditable =True,您可以看到,如果组合框没有只读选择框。

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.

因此,你通常应该避免添加UI元素到组合框,特别是如果你使用 DisplayMemberPath

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.

推荐以非标准外观显示ComboBox项目的方法(例如:

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

但是,如果你坚持传递一个 UserControl 项目列表到ComboBox,您可以删除 DisplayMemberPath ,并使用如下所示:

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>

此外,在UserControl的构造函数中,必须放置此行:

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.