私はコンテキストメニューでさまざまな種類のツリーノードを含むTreeViewを持っています。さまざまなタイプのツリーノードのコンテキストメニューは異なりますが、いくつかのセクションも共有されます。私は共通のメニューセクションを一度定義したいだけです。したがって、メニュー項目の一般的な配列をリソースとして定義し、CompositeCollectionを使用して各コンテキストメニューにプルダウンします。次のようにItemViewModelは単にTreeViewのCompositeCollectionを使用したContextMenu:メニュー項目が消えます
public class ItemViewModel
{
public ObservableCollection<ItemViewModel> Children {get; set; }
public string Name {get;set;}
public ItemViewModel(string name)
{
Children = new ObservableCollection<ItemViewModel>();
Name = name;
}
}
として定義されて
<Window x:Class="TreeViewCompositeContextMenuProblem.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TreeViewCompositeContextMenuProblem"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<x:Array x:Key="EditMenuItems" Type="{x:Type MenuItem}">
<MenuItem Header="Copy" />
<MenuItem Header="Paste" />
<MenuItem Header="Delete" />
</x:Array>
<x:Array x:Key="CommonMenuItems" Type="{x:Type MenuItem}">
<MenuItem Header="View properties" />
</x:Array>
<HierarchicalDataTemplate DataType="{x:Type local:ItemViewModel}" ItemsSource="{Binding Path=Children}">
<TextBlock Text="{Binding Path=Name}">
<TextBlock.ContextMenu>
<ContextMenu>
<ContextMenu.ItemsSource>
<CompositeCollection>
<CollectionContainer Collection="{StaticResource EditMenuItems}" />
<Separator />
<CollectionContainer Collection="{StaticResource CommonMenuItems}" />
</CompositeCollection>
</ContextMenu.ItemsSource>
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
</HierarchicalDataTemplate>
</Window.Resources>
<Grid>
<TreeView Name="treeView">
</TreeView>
</Grid>
</Window>
は、私は、TreeViewコントロールをバインドします:
var vm = new ItemViewModel("root");
var a = new ItemViewModel("a");
var b = new ItemViewModel("b");
var c = new ItemViewModel("c");
vm.Children.Add(a);
vm.Children.Add(b);
b.Children.Add(c);
treeView.ItemsSource = new List<ItemViewModel>() { vm };
を今すぐ場合は、次のように私のシナリオの非常に単純な例です。アプリケーションを実行すると、アイテム "a"、アイテム "b"、アイテム "a"のコンテキストメニューが開き、次の結果が得られます。
私のCompositeCollectionを使用すると、データテンプレートではうまくいきません。誰がここで間違っているか知っていますか?
ありがとうございます!
これは良い点です。ありがとうございます。しかし、複数のコンテキストメニューが "EditMenuItems"コレクションを使用している場合、メニュー間で個々のメニュー項目の共有が導入されるため、問題は残っています。 x:Array要素にx:Shared = "False"を追加すると助けになりました。これは、配列を参照する代わりに、配列をそのままコピーするようにXAMLパーサに指示します。 –