2011-11-22 89 views
2

我有TreeView,其中包含不同的项目类型。项目样式通过自定义的ItemContainerStyleSelector属性定义。WPF中的上下文菜单继承

我的样式都是共享基础样式,并且每种样式中只定义了特定项目的样式。它看起来像这样:

<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> 
+4

最好是你发布你自己的答案与编辑你的问题的答案。 – LarsTech

回答

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(即,功能性子项目的属性,标题和命令),那么您可以创建一个可以成为多个列表的一部分的模型Remove

+0

那么,这是更好的原始解决方案,但仍然可以导致麻烦,因为复制是必要的,如果新项目被添加或条目被删除.. –

+0

@PetrOsipov:这是怎么回事?你只有多个参考,你将永远有至少。 –

+0

嗯,我会喜欢这样的东西:BaseMenu包含一打通常的项目,只写过一次。每个子菜单引用一个基本菜单,接管它的项目,并添加只有节点特定的东西。 –