在我们的应用程序中,我们有一个屏幕设计功能,它由一个自定义 ScreenDesignPanel 和一个属性网格组成,ComboBox
顶部有一个指向 ScreenDesignPanel 上选定项目的属性网格。这允许用户通过 ComboBox 或鼠标选择 UIElement 来设置其属性。我们通过将 ComboBox 的 ItemsSource 绑定到 ScreenDesignPanel 的 Children 集合来实现这一点,然后将它们的 SelectedItem 绑定在一起。这很好用。
但是,无论出于何种原因,如果SelectedItem
是 aContentControl
或类似Button
为ItemTemplate
指定的子类ComboBox
,则“所选项目区域”将被忽略,但在下拉列表中显示项目时会应用它。如果SelectedItem
不是 a ContentControl
,则在这两种情况下都使用模板。
这似乎也是特定于ComboBox
. 如果我们使用任何其他选择器控件:ListBox
, ListView
, ItemsControl
... 甚至第三方ComboBox
控件... 它们都按预期工作,正确应用DataTemplate
. ComboBox 在内部做一些其他控件没有做的事情。
注意:下面是一个过度简化的示例,仅用于说明问题。如上所述,这不是我们实际使用它的方式。
另请注意:在 ComboBox.ItemTemplate 的 DataTemplate 中,我们仅使用属性(即示例中的 Foreground),而不显示 DataContext(即实际的 ContentControl)本身。这一点很重要,因为实际控件已经存在于 ScreenDesignPanel 上,因此不能用于在 ComboBox 的 ItemTemplate 中显示,因为它有两个不允许的父级。换句话说,它在这里纯粹用作数据。
最后一件事......我们的应用程序中有一个可行的解决方案,即在将 Children 绑定到ComboBox.ItemsSource
. 但是,我仍然很好奇为什么它的行为ComboBox
方式就是我要问的。(换句话说,我不是在寻找这个设计的其他解决方案。我们已经有一个可行的解决方案。我正在寻找它本身的奇怪行为的清晰度。)ComboBox
上代码!
在下面的第一个示例中,请注意数据模板如何应用于下拉列表中的所有内容,但如果所选项目不是ContentControl
.
<ComboBox>
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="I am the template" Foreground="{Binding Foreground}" />
</DataTemplate>
</ComboBox.ItemTemplate>
<!-- Four 'Data' items for example only -->
<TextBlock Text="I am a Red TextBox" Foreground="Red"/>
<ListBox Foreground="Purple">
<ListBoxItem>I am a Purple ListBox</ListBoxItem>
</ListBox>
<ContentControl Content="I am a Blue ContentControl" Foreground="Blue" />
<Button Content="I am a Button with Green text" Foreground="Green" />
</ComboBox>
第二个示例表明,使用 aUIElement
作为 a 的内容ContentPresenter
并仍然使用 a DataTemplate
(via ContentTemplate
) 是完全可以接受和完全支持的,因此您可以在纯数据角色中使用它,允许模板本身定义视觉外观而不显示UIElement 本身,在这里纯粹用作数据。
<ContentPresenter>
<ContentPresenter.ContentTemplate>
<DataTemplate>
<TextBlock Text="I am the ContentTemplate" Foreground="{Binding Foreground}" />
</DataTemplate>
</ContentPresenter.ContentTemplate>
<ContentPresenter.Content>
<Button Content="I am the button" Foreground="Green" />
</ContentPresenter.Content>
</ContentPresenter>
同样,这个问题是特定于ComboBox.
我想找出为什么数据模板没有在那个单一的情况下应用的,以及如果可能的话如何强制应用它。
值得注意的是,ComboBox
确实定义SelectionBoxItemTemplate
了哪个与常规分开,ItemTemplate
但摩擦是只读的,因此您无法设置它。我们真的不想重新模板化,ComboBox
因为那样会弄乱正确的主题。