我试图给出具有不同外观和功能的上下文菜单项,但我找不到将命令绑定到这些项的方法。每个菜单项的视图模型都是从一个类AbstractEntryViewModel
派生的。这是我当前项目结构的缩写示例。使用ContextMenu.Resources
是我发现将模板绑定到某种类型的唯一方法。
<ContextMenu ItemsSource="{Binding Entries}">
<ContextMenu.Resources>
<DataTemplate DataType="{x:Type local:NopEntryViewModel}">
<!-- Content -->
</DataTemplate>
<HierarchicalDataTemplate
DataType="{x:Type local:GroupEntryViewModel}"
ItemsSource="{Binding Entries}">
<!-- Content -->
</HierarchicalDataTemplate>
<!-- More templates -->
</ContextMenu.Resources>
</ContextMenu>
internal abstract AbstractEntryViewModel : INotifyPropertyChanged {
public abstract void Invoke ();
// ...
}
internal NopEntryViewModel : AbstractEntryViewModel {
public override void Invoke () {}
}
internal GroupEntryViewModel : AbstractEntryViewModel {
public override void Invoke () { /* ... */ }
// ...
}
// More view models
通常我可以将命令绑定到MenuItem
,如此
<MenuItem Command="{Binding StaticResourceOrViewModelProperty}" />
如何使用数据模板执行相同的操作?是否有一个隐形容器,数据模板内容的包装器,我可以用来将命令绑定到?
答案 0 :(得分:2)
为简单起见,假设有2个派生的ViewModel,VM1
和VM2
,分别为Command
Command1
和Command2
。
两个步骤:
1)在基础ViewModel
中定义此属性:
public Type Type
{
get { return GetType(); }
}
我们不能直接使用GetType()
,因为WPF Bindings
只能处理属性,所以我们需要一个包装属性。
2)使用此属性为DataTrigger
Style
的{{1}}设置ContextMenu
:
MenuItem
<ContextMenu.Resources>
<Style TargetType="{x:Type MenuItem}">
<Style.Triggers>
<DataTrigger Binding="{Binding Type}" Value="{x:Type local:VM1}">
<Setter Property="Command" Value="{Binding Command1}"/>
</DataTrigger>
<DataTrigger Binding="{Binding Type}" Value="{x:Type local:VM2}">
<Setter Property="Command" Value="{Binding Command2}"/>
</DataTrigger>
<!-- add other DataTriggers, one for every ViewModel -->
</Style.Triggers>
</Style>
</ContextMenu.Resources>
设置如下:
DataTemplates