WPF:如何将事件附加到枚举生成的上下文菜单



在我的简单WPF应用程序中,我以动态方式在网格上使用contextenu:我从枚举中获取项目,以备将来扩展它。我想根据用户单击的菜单项执行不同的操作,但无论单击了哪个菜单项,我都只能激发相同的事件。

这是XAML代码:

<Window
x:Class="ProcessViewer.MainWindow"
Title="Process Viewer"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:ProcessViewer"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Height="350"
Width="525"
WindowStartupLocation="Manual"
mc:Ignorable="d">
<Window.Resources>
<ObjectDataProvider
x:Key="contextToEnum"
MethodName="GetValues"
ObjectType="{x:Type sys:Enum}">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="local:ProcessType" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>       
</Window.Resources>
<Grid
x:Name="grid"
Background="Transparent">
<Grid.ContextMenu>
<ContextMenu
Name="menu"                
MenuItem.Click="MenuButton_Click"
ItemsSource="{Binding
Source={StaticResource contextToEnum}}">
</ContextMenu>
</Grid.ContextMenu>
</Grid>

我试图在上下文菜单上附加一个点击事件,然后将其对象参数转换为上下文菜单,但我只能访问上下文菜单的名称(而不是其项目的名称)和其他属性,如宽度和高度等。

以下是代码背后的相关部分:

private void MenuButton_Click(object sender, RoutedEventArgs e)
{
ContextMenu choice = sender as ContextMenu;
MessageBox.Show("You clicked: " + choice.Name.ToString());
}

是否有方法将单独的事件控件附加到每个项目?当然,问题是我事先不知道枚举中有多少项,所以理想的解决方案是这样的:

if(clikedOnItem == enum.OneOfTheItems)
{
DoSomething()
}
else if (clikedOnItem == enum.Anotheritem)
{
DoSomethingElse()
}

等等。

由于我最多使用5-15个枚举元素,我可以手动完成所有菜单项,但如果可能的话,我想找到一个更"智能"的解决方案。

您应该能够使用带有EventTrigger:的ItemContainerStyle来处理每个MenuItem的Click事件

<ContextMenu Name="menu" ItemsSource="{Binding Source={StaticResource contextToEnum}}">
<ContextMenu.ItemContainerStyle>
<Style TargetType="MenuItem">
<EventSetter Event="Click" Handler="MenuButton_Click" />
</Style>
</ContextMenu.ItemContainerStyle>
</ContextMenu>

然后将sender参数强制转换为MenuItem,并通过MenuItem:的DataContext属性访问枚举值

private void MenuButton_Click(object sender, RoutedEventArgs e)
{
MenuItem choice = sender as MenuItem;
ProcessType val = (ProcessType)choice.DataContext;
}   

最新更新