在我的简单WPF应用程序中,我以动态的方式在网格上使用contextmenu:我将从枚举中获取项目以防将来扩展它。我想根据用户点击的菜单项执行不同的操作,但无论点击哪个项目,我都只能触发相同的事件。
以下是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>
我尝试在上下文菜单上附加一个click事件,然后将其对象参数转换为上下文菜单,但我只能访问上下文菜单的名称(不是其项目的名称)和其他属性,如宽度和高度等。
以下是Code-Behind的相关部分:
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个枚举元素,我可以手动完成所有菜单项,但如果可能的话,我想找到更“智能”的解决方法。
答案 0 :(得分:2)
您应该能够使用带有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;
}