. Net Базовое меню WPF MVVM с использованием ItemContainerTemplate не работает - PullRequest
2 голосов
/ 10 февраля 2020

Я использовал подход меню MVVM в моих приложениях WPF в. NET Framework. После преобразования в. NET Core 3.1 этот же подход больше не работает.

Вопрос: это ошибка в WPF? Кто-нибудь знает решение или обходной путь?

Конечный результат в. NET Framework 4.7.2.

enter image description here

тот же код в. NET Core 3.1 покажет MenuItem внутри MenuItem (?). Подменю не отображаются.

enter image description here

Вот упрощенная версия моделей представлений.

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>

1 Ответ

0 голосов
/ 29 апреля 2020

Об этой проблеме уже сообщается ссылка на github здесь

Вы должны использовать следующие обходные пути, пока проблема не будет устранена.

  1. Установить шаблон панели элементов для вашего Menu или MenuItem
  2. Или вы можете сделать подобное решение в ControlTemplate из MenuItem

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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...