WPF:如何将事件附加到枚举生成的上下文菜单?
WPF: How to attach events to enum-generated Context Menu?
在我的简单 WPF 应用程序中,我以动态方式在网格上使用上下文菜单:我从枚举中获取项目,以防将来扩展它。我想根据用户单击的菜单项执行不同的操作,但无论单击哪个项目,我都只能触发相同的事件。
这里是 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 个枚举元素,我可以手动完成所有菜单项,但如果可能的话,我想找到更多 "intelligent" 解决方法。
您应该能够使用带有 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;
}
在我的简单 WPF 应用程序中,我以动态方式在网格上使用上下文菜单:我从枚举中获取项目,以防将来扩展它。我想根据用户单击的菜单项执行不同的操作,但无论单击哪个项目,我都只能触发相同的事件。
这里是 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 个枚举元素,我可以手动完成所有菜单项,但如果可能的话,我想找到更多 "intelligent" 解决方法。
您应该能够使用带有 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
:
private void MenuButton_Click(object sender, RoutedEventArgs e)
{
MenuItem choice = sender as MenuItem;
ProcessType val = (ProcessType)choice.DataContext;
}