我有一个WPF应用程序,它具有基于MVVM的上下文菜单。可以通过相应的视图模型动态添加上下文菜单项。我的看法如下:
<Window x:Class="WpfApp11.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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp11"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<ResourceDictionary>
<Style TargetType="{x:Type MenuItem}" x:Key="MyItemStyle">
<Setter Property="Header" Value="{Binding Header}"/>
</Style>
<HierarchicalDataTemplate x:Key="MyItemContainer"
DataType="{x:Type local:MenuItemViewModel}"
ItemsSource="{Binding MenuItems}">
</HierarchicalDataTemplate>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/WpfApp11;component/Resources/Images.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Border BorderBrush="Blue" BorderThickness="3">
<Grid>
<Button Width="100" Height="30">
<Button.ContextMenu>
<ContextMenu ItemsSource="{Binding MeasurementContextMenu}"
ItemContainerStyle="{StaticResource MyItemStyle}"
ItemTemplate="{StaticResource MyItemContainer}"/>
</Button.ContextMenu>
</Button>
</Grid>
</Border>
</Window>
视图模型如下:
public class MainModel : INotifyPropertyChanged
{
public MainModel()
{
Initialize();
}
private void Initialize()
{
var first = new MenuItemViewModel("Just a test");
var second = new MenuItemViewModel("Second");
first.MenuItems.Add(second);
MeasurementContextMenu.Add(first);
}
public ObservableCollection<MenuItemViewModel> MeasurementContextMenu { get; } = new ObservableCollection<MenuItemViewModel>();
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName]string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
以及菜单项的视图模型:
public class MenuItemViewModel : INotifyPropertyChanged
{
#region Fields
private string _header;
#endregion Fields
#region Constructors
public MenuItemViewModel(string header)
{
Header = header;
}
#endregion Constructors
#region Properties
public string Header
{
get
{
return _header;
}
set
{
if(_header != value)
{
_header = value;
OnPropertyChanged();
}
}
}
public ObservableCollection<MenuItemViewModel> MenuItems { get; } = new ObservableCollection<MenuItemViewModel>();
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName]string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion Properties
}
因此,层次结构的东西按预期工作,但是所应用的样式不起作用。因此,这些项目出现了,但是没有任何文本。似乎此属性没有任何影响
ItemContainerStyle="{StaticResource MyItemStyle}"
在这种情况下如何应用样式?
摆脱ItemContainerStyle
:
<ContextMenu ItemsSource="{Binding MeasurementContextMenu}"
ItemTemplate="{StaticResource MyItemContainer}"/>
...并将TextBlock
绑定到Header
中的HierarchicalDataTemplate
:
<HierarchicalDataTemplate x:Key="MyItemContainer"
DataType="{x:Type local:MenuItemViewModel}"
ItemsSource="{Binding MenuItems}">
<TextBlock Text="{Binding Header}" />
</HierarchicalDataTemplate>