我想显示自定义模板/项目在ComboBox中选定的项目(这个项目实际上并不存在的项目列表中,并以不同更新)。 这不,甚至需要有一个项目,只是提供了一个自定义视图会工作。
我怎样才能做到这一点,而目前的组合框主题(所以没有控件模板更换可能)内停留? 据我所见,所有SelectionBox的*属性是不可编辑和国内的ComboBox使用无名ContentPresenter。
我想显示自定义模板/项目在ComboBox中选定的项目(这个项目实际上并不存在的项目列表中,并以不同更新)。 这不,甚至需要有一个项目,只是提供了一个自定义视图会工作。
我怎样才能做到这一点,而目前的组合框主题(所以没有控件模板更换可能)内停留? 据我所见,所有SelectionBox的*属性是不可编辑和国内的ComboBox使用无名ContentPresenter。
我会做这样的:
<Window.Resources>
<DataTemplate x:Key="NormalItemTemplate" ...>
...
</DataTemplate>
<DataTemplate x:Key="SelectionBoxTemplate" ...>
...
</DataTemplate>
<DataTemplate x:Key="CombinedTemplate">
<ContentPresenter x:Name="Presenter"
Content="{Binding}"
ContentTemplate="{StaticResource NormalItemTemplate}" />
<DataTemplate.Triggers>
<DataTrigger
Binding="{Binding RelativeSource={RelativeSource FindAncestor,ComboBoxItem,1}}"
Value="{x:Null}">
<Setter TargetName="Presenter" Property="ContentTemplate"
Value="{StaticResource SelectionBoxTemplate}" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</Window.Resources>
...
<ComboBox
ItemTemplate="{StaticResource CombinedTemplate}"
ItemsSource="..."
... />
这部作品的原因是CombinedTemplate
通常只使用NormalItemTemplate呈现它的数据,但如果没有ComboBoxItem
祖先它假定它是在选择框中所以它使用SelectionBoxTemplate。
需要注意的是这三个DataTemplates
可以列入的任何级别ResourceDictionary
(而不是仅仅在Window
级别),甚至直接内ComboBox
,根据自己的喜好。
如果我有这个直,你想有一个下拉按钮显示的项目与旁边的复选框列表一起显示的东西任意控制?
我甚至不会费劲去尝试再整一个ComboBox
来实现这一目标。 问题是, ComboBox
更专业下来比你需要一个不同的路径。 如果你看一下组合框控件模板实例 ,你会看到,它只是采用了Popup
控件来显示可能值的列表。
你可以把该模板为指导的作品创造一个UserControl
是容易理解和更好地提供你想要的。 你甚至就可以添加SelectedItems
属性并且使得ComboBox
不提供。
什么我通过指导的意思是一个例子:在Popup
有IsOpen
属性。 在控制模板,它被设置为{TemplateBinding IsDropDownOpen}
这意味着该ComboBox
类有一个IsDropDownOpen
是为了控制的展开/折叠改变属性Popup
。
阿列克谢Mitev对雷伯恩斯评论回答启发我写以下合理的短实用工具类,我现在在我所有的WPF项目使用:
public class ComboBoxItemTemplateSelector : DataTemplateSelector
{
public List<DataTemplate> SelectedItemTemplates { get; } = new List<DataTemplate>();
public List<DataTemplate> DropDownItemTemplates { get; } = new List<DataTemplate>();
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
return GetVisualParent<ComboBoxItem>(container) == null
? ChooseFrom(SelectedItemTemplates, item)
: ChooseFrom(DropDownItemTemplates, item);
}
private static DataTemplate ChooseFrom(IEnumerable<DataTemplate> templates, object item)
{
if (item == null)
return null;
var targetType = item.GetType();
return templates.FirstOrDefault(t => (t.DataType as Type) == targetType);
}
private static T GetVisualParent<T>(DependencyObject child) where T : Visual
{
while (child != null && !(child is T))
child = VisualTreeHelper.GetParent(child);
return child as T;
}
}
随着在工具箱中,它可能写出XAML这样的:
<UserControl.Resources>
<DataTemplate x:Key="SelectedItemTemplateForInt" DataType="{x:Type system:Int32}">
<!-- ... -->
</DataTemplate>
<DataTemplate x:Key="SelectedItemTemplateForDouble" DataType="{x:Type system:Double}">
<!-- ... -->
</DataTemplate>
<DataTemplate x:Key="DropDownItemTemplateForInt" DataType="{x:Type system:Int32}">
<!-- ... -->
</DataTemplate>
<DataTemplate x:Key="DropDownItemTemplateForDouble" DataType="{x:Type system:Double}">
<!-- ... -->
</DataTemplate>
</UserControl.Resources>
<ComboBox>
<ComboBox.ItemTemplateSelector>
<local:ComboBoxItemTemplateSelector>
<local:ComboBoxItemTemplateSelector.SelectedItemTemplates>
<StaticResource ResourceKey="SelectedItemTemplateForInt" />
<StaticResource ResourceKey="SelectedItemTemplateForDouble" />
</local:ComboBoxItemTemplateSelector.SelectedItemTemplates>
<local:ComboBoxItemTemplateSelector.DropDownItemTemplates>
<StaticResource ResourceKey="DropDownItemTemplateForInt" />
<StaticResource ResourceKey="DropDownItemTemplateForDouble" />
</local:ComboBoxItemTemplateSelector.DropDownItemTemplates>
</local:ComboBoxItemTemplateSelector>
</ComboBox.ItemTemplateSelector>
</ComboBox>
你需要寻找到触发器和样式 。 您可能还需要寻找到一些我在这里StackOverflow上旧的问题,帮助我克服了这些问题: