我可以将自己类型的集合绑定到菜单中。但我正在与热键挣扎。热键显示但不起作用或热键不显示但工作正常。
你知道这里出了什么问题吗?
以下是精简代码:
public class Category : DependencyObject
{
public string Caption
{
get { return (string)GetValue(CaptionProperty); }
set { SetValue(CaptionProperty, value); }
}
public static readonly DependencyProperty CaptionProperty =
DependencyProperty.Register("Caption", typeof(string), typeof(Category), new PropertyMetadata(null));
public ObservableCollection<Item> SubItems
{
get { return (ObservableCollection<Item>)GetValue(SubItemsProperty); }
set { SetValue(SubItemsProperty, value); }
}
public static readonly DependencyProperty SubItemsProperty =
DependencyProperty.Register("SubItems", typeof(ObservableCollection<Item>), typeof(Category), new PropertyMetadata(null));
}
public class Item : DependencyObject
{
public string Header
{
get { return (string)GetValue(HeaderProperty); }
set { SetValue(HeaderProperty, value); }
}
public static readonly DependencyProperty HeaderProperty =
DependencyProperty.Register("Header", typeof(string), typeof(Item), new PropertyMetadata(null));
}
public class MenuViewModel : DependencyObject
{
public ObservableCollection<Category> MenuCategories
{
get { return (ObservableCollection<Category>)GetValue(MenuCategoriesProperty); }
set { SetValue(MenuCategoriesProperty, value); }
}
public static readonly DependencyProperty MenuCategoriesProperty =
DependencyProperty.Register("MenuCategories", typeof(ObservableCollection<Category>), typeof(MenuViewModel), new PropertyMetadata(null));
public MenuViewModel()
{
MenuCategories = new ObservableCollection<Category>()
{
new Category() {Caption = "_One", SubItems = new ObservableCollection<Item>() { new Item() { Header = "_one"}, new Item() { Header = "t_wo" }, new Item() { Header = "_three" } } },
new Category() {Caption = "_Two", SubItems = new ObservableCollection<Item>() { new Item() { Header = "_one"}, new Item() { Header = "t_wo" }, new Item() { Header = "_three" } } },
};
}
}
public partial class Test1Window : Window
{
public Test1Window()
{
InitializeComponent();
DataContext = new MenuViewModel();
}
}
public class MenuItemContainerTemplateSelector : ItemContainerTemplateSelector
{
public override DataTemplate SelectTemplate(object item, ItemsControl parentItemsControl)
{
var key = new DataTemplateKey(item.GetType());
return (DataTemplate)parentItemsControl.FindResource(key);
}
}
xaml 1.尝试:
<Window x:Class="DynamicMenuTest.Test1Window"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:DynamicMenuTest"
mc:Ignorable="d"
Title="Test1Window" Height="300" Width="300">
<Window.Resources>
<local:MenuItemContainerTemplateSelector x:Key="MenuItemContainerTemplateSelector"/>
<DataTemplate DataType="{x:Type local:Item}">
<MenuItem Header="{Binding Header}">
<MenuItem.HeaderTemplate>
<DataTemplate>
<AccessText VerticalAlignment="Center" Text="{Binding}" />
</DataTemplate>
</MenuItem.HeaderTemplate>
</MenuItem>
</DataTemplate>
<HierarchicalDataTemplate DataType="{x:Type local:Category}" ItemsSource="{Binding SubItems}">
<MenuItem VerticalContentAlignment="Center">
<!-- Hotkey works but doesn't show up -->
<MenuItem.Header>
<AccessText Text="{Binding Caption}"/>
</MenuItem.Header>
</MenuItem>
</HierarchicalDataTemplate>
</Window.Resources>
<Grid>
<Menu ItemsSource="{Binding MenuCategories}"
UsesItemContainerTemplate ="true"
ItemContainerTemplateSelector="{StaticResource MenuItemContainerTemplateSelector}"
/>
</Grid>
Xaml 2.尝试:
<Window x:Class="DynamicMenuTest.Test2Window"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:DynamicMenuTest"
mc:Ignorable="d"
Title="Test2Window" Height="300" Width="300">
<Window.Resources>
<local:MenuItemContainerTemplateSelector x:Key="MenuItemContainerTemplateSelector"/>
<DataTemplate DataType="{x:Type local:Item}">
<MenuItem Header="{Binding Header}">
<MenuItem.HeaderTemplate>
<DataTemplate>
<AccessText VerticalAlignment="Center" Text="{Binding}" />
</DataTemplate>
</MenuItem.HeaderTemplate>
</MenuItem>
</DataTemplate>
<HierarchicalDataTemplate DataType="{x:Type local:Category}" ItemsSource="{Binding SubItems}">
<MenuItem
Header="{Binding Caption}"
VerticalContentAlignment="Center">
<!-- Hotkey shows up but menu not working -->
<MenuItem.HeaderTemplate>
<DataTemplate>
<ContentPresenter RecognizesAccessKey="True" Content="{Binding }" VerticalAlignment="Center" Margin="4,0"/>
</DataTemplate>
</MenuItem.HeaderTemplate>
</MenuItem>
</HierarchicalDataTemplate>
</Window.Resources>
<Grid>
<Menu ItemsSource="{Binding MenuCategories}"
UsesItemContainerTemplate ="true"
ItemContainerTemplateSelector="{StaticResource MenuItemContainerTemplateSelector}"
/>
</Grid>
Xaml 3.尝试:
<Window x:Class="DynamicMenuTest.Test3Window"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:DynamicMenuTest"
mc:Ignorable="d"
Title="Test3Window" Height="300" Width="300">
<Window.Resources>
<local:MenuItemContainerTemplateSelector x:Key="MenuItemContainerTemplateSelector"/>
<DataTemplate DataType="{x:Type local:Item}">
<MenuItem Header="{Binding Header}">
<MenuItem.HeaderTemplate>
<DataTemplate>
<AccessText VerticalAlignment="Center" Text="{Binding}" />
</DataTemplate>
</MenuItem.HeaderTemplate>
</MenuItem>
</DataTemplate>
<HierarchicalDataTemplate DataType="{x:Type local:Category}" ItemsSource="{Binding SubItems}">
<MenuItem
Header="{Binding Caption}"
VerticalContentAlignment="Center">
<!-- Hotkey shows up but menu doesn't work -->
<MenuItem.HeaderTemplate>
<DataTemplate>
<AccessText Text="{Binding}" VerticalAlignment="Center" Margin="4,0"/>
</DataTemplate>
</MenuItem.HeaderTemplate>
</MenuItem>
</HierarchicalDataTemplate>
</Window.Resources>
<Grid>
<Menu ItemsSource="{Binding MenuCategories}"
UsesItemContainerTemplate ="true"
ItemContainerTemplateSelector="{StaticResource MenuItemContainerTemplateSelector}"
/>
</Grid>
答案 0 :(得分:1)
您的DataTemplate
和HierarchicalDataTemplate
描述了MenuItem
的标题内容应如何显示,因此嵌套另一个MenuItem
是个坏主意。相反,保持简单和享受:
<DataTemplate DataType="{x:Type local:Item}">
<AccessText VerticalAlignment="Center" Text="{Binding Header}" />
</DataTemplate>
<HierarchicalDataTemplate DataType="{x:Type local:Category}" ItemsSource="{Binding SubItems}">
<AccessText Text="{Binding Caption}"/>
</HierarchicalDataTemplate>