使用多个模板时,在`ContextMenu`中将命令绑定到`DataTemplate`?

时间:2016-08-28 13:51:53

标签: wpf datatemplate

我试图给出具有不同外观和功能的上下文菜单项,但我找不到将命令绑定到这些项的方法。每个菜单项的视图模型都是从一个类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}" />

如何使用数据模板执行相同的操作?是否有一个隐形容器,数据模板内容的包装器,我可以用来将命令绑定到?

1 个答案:

答案 0 :(得分:2)

为简单起见,假设有2个派生的ViewModel,VM1VM2,分别为Command Command1Command2

两个步骤:

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