WPF中的上下文菜单继承

时间:2011-11-22 13:11:16

标签: wpf xaml contextmenu maintainability

我有TreeView,它包含不同的项目类型。项目样式在自定义ItemContainerStyleSelector属性上定义。

我的风格都是共享基本风格,每种风格中只定义了特定于项目的内容。它看起来像这样:

<Style x:Key="BaseStyle" TargetType="{x:Type TreeViewItem}">
...
</Style>

<Style x:Key ="SomeSpecificStyle" TargetType="{x:Type TreeViewItem}" BasedOn="{StaticResource BaseStyle}">
   <Setter Property="ContextMenu" Value="{StaticResource NodeContextMenu}"/>
   ...  
</Style>

<Style x:Key ="SomeSpecificStyle" TargetType="{x:Type TreeViewItem}" BasedOn="{StaticResource BaseStyle}">
   <Setter Property="ContextMenu" Value="{StaticResource AnotherNodeContextMenu}"/>
   ...  
</Style>

上下文菜单定义如下

<ContextMenu x:Key="NodeContextMenu">
  <MenuItem Header="Select Views" Command="{Binding Path=OpenViewsCommand}" />
  ...other specific entries
  <MenuItem Header="Remove" Command="{Binding Path=DocumentRemoveCommand}" />
  ...other entries common for all menus
</ContextMenu>

另一个上下文菜单也应该包含像删除这些常见项目。每次命令属性等发生变化时,都需要通过复制粘贴进行复制。可维护性的地狱。有没有办法定义包含公共项的上下文菜单,然后“派生”特定的上下文菜单?

编辑:我找到了一个解决方案,其中包含来自此主题的提示: 我使用常用​​项目定义集合,并在定义菜单时使用复合集合以包含新项目和公共项目集合

<CompositeCollection x:Key="CommonItems"> 
  <MenuItem Header="Remove" Command="{Binding Path=DocumentRemoveCommand}">
  ....Other common stuff
</CompositeCollection>

<ContextMenu x:Key="NodeContextMenu">
  <ContextMenu.ItemsSource>
    <CompositeCollection>
      <MenuItem Header="Select Views" Command="{Binding Path=OpenViewsCommand}" />
      <CollectionContainer Collection="{StaticResource CommonItems}" />
    </CompositeCollection>
  </ContextMenu.ItemsSource>
</ContextMenu>

1 个答案:

答案 0 :(得分:3)

您可以将项目声明为资源并引用它们:

<Some.Resources>
    <MenuItem x:Key="mi_SelectViews" x:Shared="false"
              Header="Select Views" Command="{Binding Path=OpenViewsCommand}" />
    <MenuItem x:Key="mi_Remove" x:Shared="false"
              Header="Remove" Command="{Binding Path=DocumentRemoveCommand}" />
</Some.Resources>
<ContextMenu x:Key="NodeContextMenu">
  <StaticResource ResourceKey="mi_SelectViews" />
  ...other specific entries
  <StaticResource ResourceKey="mi_Remove" />
  ...other entries common for all menus
</ContextMenu>

x:Shared很重要)


另一种可能性是通过对象模型方法生成MenuItems,您只需将ItemsSource绑定到一些对象列表,这些对象模拟MenuItem的功能(即子项的属性) items,header和command),然后你可以创建一个Remove模型,它可以是多个列表的一部分。