为项使用派生类型
本文关键字:派生 类型 | 更新日期: 2023-09-27 17:53:45
我有一个从MenuItem派生的类型。我希望在从MenuItem.ItemsSource生成子菜单项时使用该类型。
下面是一个XAML示例,它创建了一个正确类型的项,但将其包装在另一个MenuItem中。我想去掉换行菜单项。
<MenuItem ItemsSource="{Binding MyItems}">
<MenuItem.ItemTemplate>
<DataTemplate>
<local:MenuItemDerived Header="{Binding Name}" Property1="{Binding Prop1}" />
</DataTemplate>
</MenuItem.ItemTemplate>
</MenuItem>
可以将生成的子类型更改为派生类型吗?
通常,您只需要重写MenuItem控件模板来创建自定义项,而不是子类化MenuItem。但是,可以按照您的要求进行操作,并更改生成的子菜单项的类型。有两种方法可以做到这一点,这取决于您的用例。
-
为菜单中的每种类型的项目设置
ItemContainerTemplate
。假设您正在用一个名为MyItem
的类的实例填充它,您可以这样做:<MenuItem Header="Test" UsesItemContainerTemplate="True" ItemsSource="{Binding Items}"> <MenuItem.Resources> <ItemContainerTemplate DataType="{x:Type local:MyItem}"> <local:MenuItemDerived /> </ItemContainerTemplate> </MenuItem.Resources> </MenuItem>
你可以在那里添加你想要的,每一个类型的项目,可以在菜单中(通常只有一个)。
-
使用
ItemContainerTemplateSelector
来使用您想要选择模板的任何自定义逻辑。如果您只是希望每个生成的项都使用相同的菜单项类型,这是很好的,因为第一个选项不允许这样做(您不能使用Object
作为数据模板的数据类型)。如果您想基于自定义逻辑来选择模板,这比检查项的类型要复杂得多,这也是必要的。
我在这里使用的非常简单的<MenuItem Header="Test" UsesItemContainerTemplate="True" ItemsSource="{Binding Items}"> <MenuItem.ItemContainerTemplateSelector> <local:MenuItemContainerTemplateSelector> <DataTemplate> <local:MenuItemDerived /> </DataTemplate> </local:MenuItemContainerTemplateSelector> </MenuItem.ItemContainerTemplateSelector> </MenuItem>
MenuItemContainerTemplateSelector
类看起来像这样:[ContentProperty("Template")] internal class MenuItemContainerTemplateSelector : ItemContainerTemplateSelector { public DataTemplate Template { get; set; } public override DataTemplate SelectTemplate(object item, ItemsControl parentItemsControl) { return Template; } }
当然,如果你愿意,你也可以创建一个包含多个模板的复杂选择器。
注意在这两种情况下UsesItemContainerTemplate
属性的使用。对于任何自定义项容器模板,