MenuCollection 绑定两次 MVVM + 数据绑定子菜单项
MenuCollection Binding twice MVVM + Databinding Child menu items
如下图所示,您可以看到 2 种悬停状态。这是 XAML
<Menu ItemsSource="{Binding Data.MenuCollection}">
<Menu.ItemTemplate >
<DataTemplate DataType="MenuItem">
<MenuItem Header="{Binding Header}" Command="{Binding Command}" ItemsSource="{Binding Children}"/>
</DataTemplate>
</Menu.ItemTemplate>
</Menu>
数据集合在页眉上起作用。但是我无法让子节点出现。
public void CreateTempMenuList()
{
MenuCollection = new ObservableCollection<MenuItem>()
{
new MenuItem()
{
Header = "File",
Children = new ObservableCollection<MenuItem>()
{
new MenuItem()
{
Header = "Exit"
}
}
}
};
}
MenuItem
class 是我创造的东西。每个 属性 都有一个调用 OnPropertiesChanged
函数的 setter。如果需要,我可以添加 class,但我很确定这不是问题所在。
所以我的问题是。我如何摆脱 'double' hover
。在图像中,您可以看到 2 borders
。我将鼠标悬停在 outer border
上。悬停会一直停留,直到专注于其他事情。
我的第二个问题是如何让子项目工作? menuitem
标签上的 itemssource
可能是错误的,但这是我能想到的。
定义一个 HierarchicalDataTemplate
:
<Menu ItemsSource="{Binding Data.MenuCollection}">
<Menu.Resources>
<Style TargetType="MenuItem">
<Setter Property="Command" Value="{Binding Command}" />
</Style>
</Menu.Resources>
<Menu.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Children}">
<TextBlock Text="{Binding Header}" />
</HierarchicalDataTemplate>
</Menu.ItemTemplate>
</Menu>
为每个项目隐式创建了一个 System.Windows.Controls.MenuItem
容器,因此您不应在模板中添加另一个 MenuItem
元素。
还要确保您没有绑定到 ObservableCollection<System.Windows.Controls.MenuItem>
,因为 ItemTemplate
不会应用于内置 MenuItem
元素。
要使您当前的代码正常工作,请右键单击您的 Menu control > Edit Additional Template > Edit ItemContainerStyle > Edit Copy
。
并且在生成的样式中,
搜索这段代码:
<Trigger Property="Role" Value="TopLevelItem">
<Setter Property="Padding" Value="7,2,8,3"/>
<Setter Property="Template" Value="{DynamicResource {ComponentResourceKey ResourceId=TopLevelItemTemplateKey, TypeInTargetAssembly={x:Type MenuItem}}}"/>
</Trigger>
并将 Padding
更改为 0
而不是 7,2,8,3
。
如下图所示,您可以看到 2 种悬停状态。这是 XAML
<Menu ItemsSource="{Binding Data.MenuCollection}">
<Menu.ItemTemplate >
<DataTemplate DataType="MenuItem">
<MenuItem Header="{Binding Header}" Command="{Binding Command}" ItemsSource="{Binding Children}"/>
</DataTemplate>
</Menu.ItemTemplate>
</Menu>
数据集合在页眉上起作用。但是我无法让子节点出现。
public void CreateTempMenuList()
{
MenuCollection = new ObservableCollection<MenuItem>()
{
new MenuItem()
{
Header = "File",
Children = new ObservableCollection<MenuItem>()
{
new MenuItem()
{
Header = "Exit"
}
}
}
};
}
MenuItem
class 是我创造的东西。每个 属性 都有一个调用 OnPropertiesChanged
函数的 setter。如果需要,我可以添加 class,但我很确定这不是问题所在。
所以我的问题是。我如何摆脱 'double' hover
。在图像中,您可以看到 2 borders
。我将鼠标悬停在 outer border
上。悬停会一直停留,直到专注于其他事情。
我的第二个问题是如何让子项目工作? menuitem
标签上的 itemssource
可能是错误的,但这是我能想到的。
定义一个 HierarchicalDataTemplate
:
<Menu ItemsSource="{Binding Data.MenuCollection}">
<Menu.Resources>
<Style TargetType="MenuItem">
<Setter Property="Command" Value="{Binding Command}" />
</Style>
</Menu.Resources>
<Menu.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Children}">
<TextBlock Text="{Binding Header}" />
</HierarchicalDataTemplate>
</Menu.ItemTemplate>
</Menu>
为每个项目隐式创建了一个 System.Windows.Controls.MenuItem
容器,因此您不应在模板中添加另一个 MenuItem
元素。
还要确保您没有绑定到 ObservableCollection<System.Windows.Controls.MenuItem>
,因为 ItemTemplate
不会应用于内置 MenuItem
元素。
要使您当前的代码正常工作,请右键单击您的 Menu control > Edit Additional Template > Edit ItemContainerStyle > Edit Copy
。
并且在生成的样式中,
搜索这段代码:
<Trigger Property="Role" Value="TopLevelItem">
<Setter Property="Padding" Value="7,2,8,3"/>
<Setter Property="Template" Value="{DynamicResource {ComponentResourceKey ResourceId=TopLevelItemTemplateKey, TypeInTargetAssembly={x:Type MenuItem}}}"/>
</Trigger>
并将 Padding
更改为 0
而不是 7,2,8,3
。