.Net Core WPF MVVM 菜单使用 ItemContainerTemplate 不工作
.Net Core WPF MVVM menu using ItemContainerTemplate not working
我在 .NET Framework 的 WPF 应用程序中使用了 MVVM 菜单方法。转换为 .NET Core 3.1 后,同样的方法不再有效。
问题:这是 WPF 中的错误吗?有谁知道解决方案或解决方法?
.NET Framework 4.7.2 中的最终结果。
.NET Core 3.1 中的相同代码将在 MenuItem(?) 中显示 MenuItem。没有出现子菜单。
这是视图模型的简化版本。
using System.Collections.ObjectModel;
namespace WpfMenuFw
{
class MainVm
{
public ObservableCollection<MenuVm> MenuVms { get; set; } = new ObservableCollection<MenuVm>();
}
abstract class MenuVm
{
}
class MenuSeparatorVm : MenuVm
{
}
class MenuItemVm : MenuVm
{
public string Header { get; set; } = nameof(MenuItemVm);
}
class MenuGroupVm : MenuVm
{
public string Header { get; set; } = nameof(MenuGroupVm);
public ObservableCollection<MenuVm> MenuVms { get; set; } = new ObservableCollection<MenuVm>();
}
}
XAML
<Window
x:Class="WpfMenuFw.MainWindow"
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:local="clr-namespace:WpfMenuFw"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="MainWindow"
Width="800"
Height="450"
d:DataContext="{d:DesignInstance local:MainVm}"
mc:Ignorable="d">
<Window.Resources>
<ItemContainerTemplate DataType="{x:Type local:MenuSeparatorVm}">
<Separator />
</ItemContainerTemplate>
<ItemContainerTemplate DataType="{x:Type local:MenuGroupVm}">
<MenuItem
d:DataContext="{d:DesignInstance local:MenuGroupVm}"
Header="{Binding Header}"
ItemsSource="{Binding MenuVms}"
UsesItemContainerTemplate="True" />
</ItemContainerTemplate>
<ItemContainerTemplate DataType="{x:Type local:MenuItemVm}">
<MenuItem
d:DataContext="{d:DesignInstance local:MenuItemVm}"
Header="{Binding Header}" />
</ItemContainerTemplate>
</Window.Resources>
<Window.DataContext>
<local:MainVm>
<local:MainVm.MenuVms>
<local:MenuGroupVm Header="Group 1">
<local:MenuGroupVm.MenuVms>
<local:MenuItemVm Header="Item A1" />
<local:MenuSeparatorVm />
<local:MenuItemVm Header="Item A2" />
</local:MenuGroupVm.MenuVms>
</local:MenuGroupVm>
<local:MenuGroupVm Header="Group 2">
<local:MenuGroupVm.MenuVms>
<local:MenuItemVm Header="Item B1" />
<local:MenuItemVm Header="Item B2" />
</local:MenuGroupVm.MenuVms>
</local:MenuGroupVm>
</local:MainVm.MenuVms>
</local:MainVm>
</Window.DataContext>
<DockPanel>
<Menu
DockPanel.Dock="Top"
IsMainMenu="True"
ItemsSource="{Binding MenuVms}"
UsesItemContainerTemplate="True" />
<TextBlock Text="MainContent">
<TextBlock.ContextMenu>
<ContextMenu
ItemsSource="{Binding MenuVms}"
UsesItemContainerTemplate="True" />
</TextBlock.ContextMenu>
</TextBlock>
</DockPanel>
</Window>
已报告此问题github link here
在问题得到解决之前,您应该使用以下解决方法。
- 为您的菜单或 MenuItem 设置项目面板模板
- 或者您可以在 MenuItem 的 ControlTemplate 中执行类似的解决方案
XAML
-1.-
<Menu.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Margin="-34,0,-54,0"/>
</ItemsPanelTemplate>
</Menu.ItemsPanel>
-2.- [...在 ControlTemplate 中...]
<Popup x:Name="PART_Popup" IsOpen...>
<ItemsPresenter Margin="-34,0,-54,0"/>
</Popup>
我在 .NET Framework 的 WPF 应用程序中使用了 MVVM 菜单方法。转换为 .NET Core 3.1 后,同样的方法不再有效。
问题:这是 WPF 中的错误吗?有谁知道解决方案或解决方法?
.NET Framework 4.7.2 中的最终结果。
.NET Core 3.1 中的相同代码将在 MenuItem(?) 中显示 MenuItem。没有出现子菜单。
这是视图模型的简化版本。
using System.Collections.ObjectModel;
namespace WpfMenuFw
{
class MainVm
{
public ObservableCollection<MenuVm> MenuVms { get; set; } = new ObservableCollection<MenuVm>();
}
abstract class MenuVm
{
}
class MenuSeparatorVm : MenuVm
{
}
class MenuItemVm : MenuVm
{
public string Header { get; set; } = nameof(MenuItemVm);
}
class MenuGroupVm : MenuVm
{
public string Header { get; set; } = nameof(MenuGroupVm);
public ObservableCollection<MenuVm> MenuVms { get; set; } = new ObservableCollection<MenuVm>();
}
}
XAML
<Window
x:Class="WpfMenuFw.MainWindow"
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:local="clr-namespace:WpfMenuFw"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="MainWindow"
Width="800"
Height="450"
d:DataContext="{d:DesignInstance local:MainVm}"
mc:Ignorable="d">
<Window.Resources>
<ItemContainerTemplate DataType="{x:Type local:MenuSeparatorVm}">
<Separator />
</ItemContainerTemplate>
<ItemContainerTemplate DataType="{x:Type local:MenuGroupVm}">
<MenuItem
d:DataContext="{d:DesignInstance local:MenuGroupVm}"
Header="{Binding Header}"
ItemsSource="{Binding MenuVms}"
UsesItemContainerTemplate="True" />
</ItemContainerTemplate>
<ItemContainerTemplate DataType="{x:Type local:MenuItemVm}">
<MenuItem
d:DataContext="{d:DesignInstance local:MenuItemVm}"
Header="{Binding Header}" />
</ItemContainerTemplate>
</Window.Resources>
<Window.DataContext>
<local:MainVm>
<local:MainVm.MenuVms>
<local:MenuGroupVm Header="Group 1">
<local:MenuGroupVm.MenuVms>
<local:MenuItemVm Header="Item A1" />
<local:MenuSeparatorVm />
<local:MenuItemVm Header="Item A2" />
</local:MenuGroupVm.MenuVms>
</local:MenuGroupVm>
<local:MenuGroupVm Header="Group 2">
<local:MenuGroupVm.MenuVms>
<local:MenuItemVm Header="Item B1" />
<local:MenuItemVm Header="Item B2" />
</local:MenuGroupVm.MenuVms>
</local:MenuGroupVm>
</local:MainVm.MenuVms>
</local:MainVm>
</Window.DataContext>
<DockPanel>
<Menu
DockPanel.Dock="Top"
IsMainMenu="True"
ItemsSource="{Binding MenuVms}"
UsesItemContainerTemplate="True" />
<TextBlock Text="MainContent">
<TextBlock.ContextMenu>
<ContextMenu
ItemsSource="{Binding MenuVms}"
UsesItemContainerTemplate="True" />
</TextBlock.ContextMenu>
</TextBlock>
</DockPanel>
</Window>
已报告此问题github link here
在问题得到解决之前,您应该使用以下解决方法。
- 为您的菜单或 MenuItem 设置项目面板模板
- 或者您可以在 MenuItem 的 ControlTemplate 中执行类似的解决方案
XAML
-1.-
<Menu.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Margin="-34,0,-54,0"/>
</ItemsPanelTemplate>
</Menu.ItemsPanel>
-2.- [...在 ControlTemplate 中...]
<Popup x:Name="PART_Popup" IsOpen...>
<ItemsPresenter Margin="-34,0,-54,0"/>
</Popup>