Я пытаюсь реализовать контекстное меню с привязкой ViewModel, как показано ниже:
Стиль, кажется, в порядке, но я не могу найти способ реализовать подменю с флажками, привязанными к viewmodel.
, пожалуйста, найдите ниже код, который я использую для получения меню, подобного этому:
<Window x:Class="WpfContextMenu.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:WpfContextMenu"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<!-- Separator -->
<Style TargetType="{x:Type Separator}"
x:Key="SeparatorStyle">
<Setter Property="Height"
Value="0" />
<Setter Property="Background"
Value="#0f3c5a" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Separator}">
<Rectangle Height="{TemplateBinding Height}"
Fill="White" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--Outer menu items-->
<Style TargetType="{x:Type MenuItem}">
<Setter Property="Background" Value="Black"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="IsCheckable" Value="True"/>
<Style.Triggers>
<Trigger Property="IsHighlighted"
Value="True">
<Setter Property="Background"
Value="Black"></Setter>
</Trigger>
<Trigger Property="IsEnabled"
Value="False">
<Setter Property="Foreground"
Value="LightGray"></Setter>
</Trigger>
</Style.Triggers>
</Style>
<!-- Outer menu -->
<Style TargetType="{x:Type ContextMenu}">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="Foreground" Value="LightGray"/>
<Setter Property="Background" Value="Black"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ContextMenu}">
<!--Here is where you change the border thickness to zero on the menu-->
<Border BorderThickness="0"
x:Name="Border"
Background="Black">
<StackPanel ClipToBounds="True"
Orientation="Vertical"
IsItemsHost="True" Background="Black"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver"
Value="true">
<Setter TargetName="Border"
Property="Background"
Value="#0f3c5a" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- Submenu Item -->
<ControlTemplate x:Key="{x:Static MenuItem.SubmenuItemTemplateKey}"
TargetType="{x:Type MenuItem}">
<Border Name="Border">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"
SharedSizeGroup="Icon" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto"
SharedSizeGroup="Shortcut" />
<ColumnDefinition Width="13" />
</Grid.ColumnDefinitions>
<ContentPresenter Name="Icon"
Margin="6,0,6,0"
VerticalAlignment="Center"
ContentSource="Icon" />
<Border Name="Check"
Width="13"
Height="13"
Visibility="Collapsed"
Margin="6,0,6,0"
Background="Black"
BorderThickness="1"
BorderBrush="#5082a4">
<Path Name="CheckMark"
Width="7"
Height="7"
Visibility="Hidden"
SnapsToDevicePixels="False"
Stroke="#5082a4"
StrokeThickness="2"
Data="F1 M 0.468732,4.66838L 3.03345,7.95443L 7.28127,0.420569" />
</Border>
<ContentPresenter Name="HeaderHost"
Grid.Column="1"
ContentSource="Header"
RecognizesAccessKey="True" />
<TextBlock x:Name="InputGestureText"
Grid.Column="2"
Text="{TemplateBinding InputGestureText}"
Margin="5,2,0,2"
DockPanel.Dock="Right" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="Icon"
Value="{x:Null}">
<Setter TargetName="Icon"
Property="Visibility"
Value="Hidden" />
</Trigger>
<Trigger Property="IsChecked"
Value="true">
<Setter TargetName="CheckMark"
Property="Visibility"
Value="Visible" />
</Trigger>
<Trigger Property="IsCheckable"
Value="true">
<Setter TargetName="Check"
Property="Visibility"
Value="Visible" />
<Setter TargetName="Icon"
Property="Visibility"
Value="Hidden" />
</Trigger>
<Trigger Property="IsHighlighted"
Value="true">
<Setter TargetName="Border"
Property="Background"
Value="#5082a4" />
</Trigger>
<Trigger Property="IsEnabled"
Value="false">
<Setter Property="Foreground"
Value="#0f3c5a" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<!-- Submenu Header -->
<ControlTemplate x:Key="{x:Static MenuItem.SubmenuHeaderTemplateKey}"
TargetType="{x:Type MenuItem}">
<Border Name="Border">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"
SharedSizeGroup="Icon" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto"
SharedSizeGroup="Shortcut" />
<ColumnDefinition Width="13" />
</Grid.ColumnDefinitions>
<ContentPresenter Name="Icon"
Margin="6,0,6,0"
VerticalAlignment="Center"
ContentSource="Icon" />
<ContentPresenter Name="HeaderHost"
Grid.Column="1"
ContentSource="Header"
RecognizesAccessKey="True" />
<TextBlock x:Name="InputGestureText"
Grid.Column="2"
Text="{TemplateBinding InputGestureText}"
Margin="5,2,2,2"
DockPanel.Dock="Right" />
<Path Grid.Column="3"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="M 0 0 L 0 7 L 4 3.5 Z"
Fill="Red" Stretch="Fill" Height="15" Width="7"/>
<Popup Name="Popup"
Placement="Right"
HorizontalOffset="-4"
IsOpen="{TemplateBinding IsSubmenuOpen}"
AllowsTransparency="True"
Focusable="False"
PopupAnimation="Fade">
<Border Name="SubmenuBorder"
SnapsToDevicePixels="True"
Background="Black"
BorderBrush="#0f3c5a"
BorderThickness="1">
<StackPanel IsItemsHost="True"
KeyboardNavigation.DirectionalNavigation="Cycle" />
</Border>
</Popup>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="Icon"
Value="{x:Null}">
<Setter TargetName="Icon"
Property="Visibility"
Value="Collapsed" />
</Trigger>
<Trigger Property="IsHighlighted"
Value="true">
<Setter TargetName="Border"
Property="Background"
Value="#5082a4" />
</Trigger>
<Trigger SourceName="Popup"
Property="Popup.AllowsTransparency"
Value="True">
<Setter TargetName="SubmenuBorder"
Property="CornerRadius"
Value="4" />
<Setter TargetName="SubmenuBorder"
Property="Padding"
Value="0,3,0,3" />
</Trigger>
<Trigger Property="IsEnabled"
Value="false">
<Setter Property="Foreground"
Value="#0f3c5a" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Window.Resources>
<Grid>
<Rectangle x:Name="rect1"
Width="100"
Height="30"
Margin="5"
ContextMenuService.IsEnabled="False"
ContextMenuService.Placement="Top"
ContextMenuService.PlacementTarget="{Binding ElementName=rect1}"
ContextMenuService.ShowOnDisabled="True"
Fill="Gray"
MouseDown="rect1_MouseDown">
<Rectangle.ContextMenu>
<ContextMenu ItemsSource="{Binding MenuItems}" FontSize="20">
<ContextMenu.ItemTemplate>
<HierarchicalDataTemplate>
<ContentPresenter Content="{Binding MainMenuHeader}"/>
<HierarchicalDataTemplate.ItemsSource>
<Binding Path="SubItems"/>
</HierarchicalDataTemplate.ItemsSource>
</HierarchicalDataTemplate>
</ContextMenu.ItemTemplate>
</ContextMenu>
</Rectangle.ContextMenu>
</Rectangle>
</Grid>
public class MainWindowViewModel : BindableBase
{
private ObservableCollection<MenuItem> _menuItems = new ObservableCollection<MenuItem>();
public MainWindowViewModel()
{
var menuItems = new MenuItem
{
MainMenuHeader = "Personal Customer Forms"
};
menuItems.SubItems.Add(new MenuItem { MainMenuHeader = "Sub 1"});
menuItems.SubItems.Add(new MenuItem { MainMenuHeader = "Sub 2" });
menuItems.SubItems.Add(new MenuItem { MainMenuHeader = "Sub 3" });
MenuItems.Add(menuItems);
var menuItems1 = new MenuItem
{
MainMenuHeader = "Second"
};
menuItems1.SubItems.Add(new MenuItem { MainMenuHeader = "Sub 1" });
menuItems1.SubItems.Add(new MenuItem { MainMenuHeader = "Sub 2" });
menuItems1.SubItems.Add(new MenuItem { MainMenuHeader = "Sub 3" });
MenuItems.Add(menuItems1);
}
public ObservableCollection<MenuItem> MenuItems
{
get => _menuItems;
set { _menuItems = value; RaisePropertyChanged(); }
}
}
public class MenuItem : BindableBase
{
private ObservableCollection<MenuItem> _subItems = new ObservableCollection<MenuItem>();
public MenuItem()
{
}
public string MainMenuHeader { get; set; }
public ObservableCollection<MenuItem> SubItems
{
get => _subItems;
set
{
_subItems = value;
RaisePropertyChanged();
}
}
}
Когда Я устанавливаю свойство IsCheckable для пункта меню в true, тогда только основные элементы становятся проверяемыми.
Буду признателен, если кто-то сможет помочь с этой проблемой.
Заранее спасибо.