我有一个带有相当复杂模板的ComboBox
,其中包括两个图像和几行文本:
然而,在ComboBox
中选择的项本身显示不正确,因为垂直空间太小(我无法使其更高,因为它是ToolBar
的一部分)。
如何使ComboBox在选择项时使用不同的模板来显示在ComboBox
内?(默认的ToString
表示法也可以)
谢谢!
我有一个带有相当复杂模板的ComboBox
,其中包括两个图像和几行文本:
然而,在ComboBox
中选择的项本身显示不正确,因为垂直空间太小(我无法使其更高,因为它是ToolBar
的一部分)。
如何使ComboBox在选择项时使用不同的模板来显示在ComboBox
内?(默认的ToString
表示法也可以)
谢谢!
选择的项(在ComboBox
本身中,而不是下拉列表中)未位于ComboBoxItem
内,因此您可以像这样操作:
<ComboBox.ItemTemplate>
<DataTemplate>
<ContentControl Content="{Binding}">
<ContentControl.Style>
<Style TargetType="{x:Type ContentControl}">
<!-- Complex default template -->
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Image Source="{Binding XPath=media:thumbnail/@url}" Width="100" Height="100" />
</DataTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<!-- Simple selection box template -->
<DataTrigger
Binding="{Binding RelativeSource={RelativeSource AncestorType=ComboBoxItem}}"
Value="{x:Null}">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock Text="{Binding XPath=title}" />
</DataTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
</DataTemplate>
</ComboBox.ItemTemplate>
(编辑:请注意,选择框的绑定会引发错误,因为未找到RelativeSource
。有多种解决这个问题的方法,其中之一是使用自定义值转换器,根据祖先是否存在返回true
或false
(手动遍历树形结构)。
ComboBox
时是怎么想的。克服这个问题的天真方法是什么(当数据模板在两个地方使用时:用于项目列表和在列表隐藏时选择的项目)?使用样式的ContentControl
似乎是处理多个模板的常见hack,而不是使用DataTemplateSelector
的糟糕想法,但我真的很讨厌检查祖先,这反过来也有问题,根据最新的编辑。 - Sinatr我正在寻找这个问题的标准解决方案(不是hacky,也没有绑定错误),并在这里发现了它:使用DataTemplateSelector
。
这与@H.B.答案的想法相同:检查可视树中是否有ComboBoxItem
作为父级。
public class ComboBoxItemTemplateSelector : DataTemplateSelector
{
public DataTemplate SelectedTemplate { get; set; }
public DataTemplate DropDownTemplate { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
while (container != null)
{
container = VisualTreeHelper.GetParent(container);
if (container is ComboBoxItem)
return DropDownTemplate;
}
return SelectedTemplate;
}
}
使用说明:
<ComboBox.ItemTemplateSelector>
<local:ComboBoxItemTemplateSelector>
<local:ComboBoxItemTemplateSelector.SelectedTemplate>
<DataTemplate>
... simple template for selected item
</DataTemplate>
</local:ComboBoxItemTemplateSelector.SelectedTemplate>
<local:ComboBoxItemTemplateSelector.DropDownTemplate>
<DataTemplate>
... complex template used by dropdown items
</DataTemplate>
</local:ComboBoxItemTemplateSelector.DropDownTemplate>
</local:ComboBoxItemTemplateSelector>
</ComboBox.ItemTemplateSelector>