问题:使用升级助手升级为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>
使用升级助手从旧项目结构升级到新的 SDK 风格后(“升级项目功能”->“将项目转换为 SDK 风格”-> 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 中指定的其他样式可以工作并应用
升级助手是无辜的/已知的 wpf 错误(自 2020 年起):
解决方法:如果您删除 DataType="{x:Type …}" 并放入 x:Key="{ItemContainerTemplateKey {x:Type …}}" ,这似乎可行。