You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

升级为SDK风格项目后WPF菜单无法展开显示子项的问题求助

升级为SDK风格项目后WPF菜单无法展开显示子项的问题求助

大家好,我遇到一个棘手的问题:用升级助手把WPF(.NET Framework)项目转换成SDK风格后,菜单功能出问题了——现在只能显示主菜单条目,子菜单完全无法展开显示。下面是详细情况,希望各位能帮忙看看!

原项目情况

  • 项目类型:WPF App (.Net Framework)
  • 使用默认生成的App.xaml,自定义了MainWindow.xaml、MainWindow.xaml.cs,还新增了MenuStyles.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;
    }
}
<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>

升级后的问题

通过升级助手完成转换(执行了"upgrade project features" -> "convert project to SDK style",结果2成功0失败0跳过),之后菜单只能显示主条目,子菜单无法展开,效果如下:
升级后菜单显示效果

升级后的项目文件内容

<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中的其他样式能正常被应用,说明资源文件本身是被正确加载的

有没有大佬能指点下问题出在哪?

备注:内容来源于stack exchange,提问作者Noe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.17 11:53:06