C# WPF 菜单在升级为 SDK 风格后不再起作用

问题描述 投票:0回答:1

问题:使用升级助手升级为SDK样式后,菜单不再起作用

起点:

项目类型:WPF App(.Net Framework)

默认生成App.xaml

修改后的MainWindow.xaml:

<Grid>
    <Menu UsesItemContainerTemplate="True"
          DataContext="{Binding MenuBar}" 
          ItemsSource="{Binding MenuItems}"
          IsMainMenu="True">
        <Menu.Resources>
            <ResourceDictionary>
                <ResourceDictionary.MergedDictionaries>
                    <ResourceDictionary Source="MenuStyles.xaml" />
                </ResourceDictionary.MergedDictionaries>
            </ResourceDictionary>
        </Menu.Resources>
    </Menu>
</Grid>

修改MainWindow.xaml.cs:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        var items = new List<IMenuItemViewModel>();
        items.Add(new CommandMenuItemViewModel("Sub menu 1"));
        items.Add(new SeparatorMenuItemViewModel());
        items.Add(new CommandMenuItemViewModel("Sub menu 2"));
        var popup = new PopupMenuItemViewModel(items);
        var model = new MenuViewModel(new[] { popup });
        this.DataContext = new MainWindowModel(model);
    }
}

public class MainWindowModel
{
    public MainWindowModel(MenuViewModel model)
    {
        this.MenuBar = model;
    }

    public MenuViewModel MenuBar { get; set; }
}

public interface IMenuViewModel { }

public class MenuViewModel : IMenuViewModel
{
    private IList<IMenuItemViewModel> menuItems;

    public MenuViewModel(IList<IMenuItemViewModel> menuItems)
    {
        this.menuItems = menuItems;
    }

    public IList<IMenuItemViewModel> MenuItems => this.menuItems;
}

public interface IMenuItemViewModel { }

public class CommandMenuItemViewModel : IMenuItemViewModel
{
    private string _displayName;

    public CommandMenuItemViewModel(string displayName)
    {
        _displayName = displayName;
    }

    public string DisplayName
    {
        get => _displayName;
        set => _displayName = value;
    }

    private bool _isEnabled = true;

    public bool IsEnabled
    {
        get => _isEnabled;
        set => _isEnabled = value;
    }
}

public class PopupMenuItemViewModel : IMenuItemViewModel
{
    private string _displayName = "Main menu";

    public string DisplayName
    {
        get => _displayName;
        set => _displayName = value;
    }
    private bool _isEnabled = true;

    public bool IsEnabled
    {
        get => _isEnabled;
        set => _isEnabled = value;
    }

    private IList<IMenuItemViewModel> menuItems;

    public PopupMenuItemViewModel(IList<IMenuItemViewModel> menuItems)
    {
        this.menuItems = menuItems;
    }

    public IList<IMenuItemViewModel> MenuItems => this.menuItems;
}

public class SeparatorMenuItemViewModel : IMenuItemViewModel
{
    private string _displayName = "Test 4";

    public string DisplayName
    {
        get => _displayName;
        set => _displayName = value;
    }
    private bool _isEnabled = true;

    public bool IsEnabled
    {
        get => _isEnabled;
        set => _isEnabled = value;
    }
}

添加了 MenuStyles.xaml:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:wpfApp2="clr-namespace:WpfApp2">

    <ItemContainerTemplate DataType="{x:Type wpfApp2:CommandMenuItemViewModel}">
        <MenuItem Header="{Binding DisplayName}">
        </MenuItem>
    </ItemContainerTemplate>

    <ItemContainerTemplate DataType="{x:Type wpfApp2:PopupMenuItemViewModel}">
        <MenuItem Header="{Binding DisplayName}" ItemsSource="{Binding MenuItems}" UsesItemContainerTemplate="True" />
    </ItemContainerTemplate>
    
    <ItemContainerTemplate DataType="{x:Type wpfApp2:SeparatorMenuItemViewModel}">
        <Separator Margin="30,2,0,2" />
    </ItemContainerTemplate>

</ResourceDictionary>

Display of the menu

使用升级助手从旧项目结构升级到新的 SDK 风格后(“升级项目功能”->“将项目转换为 SDK 风格”-> 2 成功,0 失败,0 跳过)

菜单现在仅显示主条目。子菜单条目不再显示或菜单无法再展开。

Display of the menu: SDK style

项目文件内容:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net48</TargetFramework>
    <OutputType>WinExe</OutputType>
    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
    <UseWPF>true</UseWPF>
    <ImportWindowsDesktopTargets>true</ImportWindowsDesktopTargets>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
    <PackageReference Include="System.Data.DataSetExtensions" Version="4.5.0" />
  </ItemGroup>
</Project>

一切看起来都很好,但行不通。有建议吗?

更改目标框架不起作用:

<TargetFramework>net8.0-windows</TargetFramework>

使用 ItemContainerTemplateSelector:

ItemsControl.FindResource(resourceKey)

没有找到资源,Application.FindResource也没有找到任何东西

MenuStyle.xaml 中指定的其他样式可以工作并应用

c# wpf upgrade
1个回答
0
投票

升级助手是无辜的/已知的 wpf 错误(自 2020 年起):

解决方法:如果您删除 DataType="{x:Type …}" 并放入 x:Key="{ItemContainerTemplateKey {x:Type …}}" ,这似乎可行。

解决方案链接

© www.soinside.com 2019 - 2024. All rights reserved.