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

时间:2017-01-30 15:37:10

标签: wpf enums contextmenu

在我的简单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个枚举元素,我可以手动完成所有菜单项,但如果可能的话,我想找到更“智能”的解决方法。

1 个答案:

答案 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;
}