1
我有一個TreeView,它將包含許多不同種類的帶有上下文菜單的樹節點。不同類型的樹節點的上下文菜單將有所不同,但也會共享某些節。我只想定義一次通用的菜單部分。因此,我將一些常用的菜單項數組定義爲資源,然後使用CompositeCollection將它們拉入每個上下文菜單。我的方案的一個非常簡單的例子如下:TreeView中具有CompositeCollection的ContextMenu:菜單項消失
<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>
其中ItemViewModel被簡單地定義爲
public class ItemViewModel
{
public ObservableCollection<ItemViewModel> Children {get; set; }
public string Name {get;set;}
public ItemViewModel(string name)
{
Children = new ObservableCollection<ItemViewModel>();
Name = name;
}
}
我然後綁定的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解析器逐字複製數組,而不是引用它們。 –