.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

在问题得到解决之前,您应该使用以下解决方法。

  1. 为您的菜单或 MenuItem 设置项目面板模板
  2. 或者您可以在 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>