C# MVVM中未应用WPF上下文菜单项样式
我有一个WPF应用程序,它有一个基于MVVM的上下文菜单。可以通过相应的视图模型动态添加关联菜单项。我的观点是这样的:C# MVVM中未应用WPF上下文菜单项样式,c#,wpf,xaml,mvvm,C#,Wpf,Xaml,Mvvm,我有一个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" xmln
<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));
}
}
在这种情况下如何应用样式?摆脱
ItemContainerStyle
:
<ContextMenu ItemsSource="{Binding MeasurementContextMenu}"
ItemTemplate="{StaticResource MyItemContainer}"/>
当只有标题文本时,这就可以了。但后来我想添加其他东西,如图标,IsChecked,IsChecked等。因此,我不想在模板中使用TextBlock。。。此外,当我使用键“MyItemStyle”时,如果没有应用样式,它也不会解释。当我定义一个没有键的样式时,它似乎起作用了,但仍然不明白为什么。@FranzGsell:那么你应该简单地用
面板替换文本块
。你的问题的解决方案仍然是一样的。你真的对这个答案投了反对票吗…?那么用面板替换文本块是什么意思呢?你的意思是我应该添加一个带有相应控件的面板来自己处理IsCheck、IsCheckable、Icon等吗?是的,我否决了这个答案,因为它并没有真正回答这个问题:“为什么ItemContainerStyle=“{StaticResource MyItemStyle}”“不适用吗?您的解决方案似乎更像是一种变通方法……您的ItemTemplate
覆盖了ItemContainerStyle
。在模板中设置标题
绑定,或者将样式附加到项目模板
。
ItemContainerStyle="{StaticResource MyItemStyle}"
<ContextMenu ItemsSource="{Binding MeasurementContextMenu}"
ItemTemplate="{StaticResource MyItemContainer}"/>
<HierarchicalDataTemplate x:Key="MyItemContainer"
DataType="{x:Type local:MenuItemViewModel}"
ItemsSource="{Binding MenuItems}">
<TextBlock Text="{Binding Header}" />
</HierarchicalDataTemplate>