将项目Click侦听器直接添加到后面代码中的动态填充的上下文菜单中

时间:2018-11-08 18:10:05

标签: c# wpf code-behind

我在WPF中有一个上下文菜单,它将由List<String>驱动,以显示动态生成的菜单项集。

该列表分配给上下文菜单的ItemsSource属性,并正确显示菜单的内容。

我在后面的代码中创建了一个MenuItem,可以为该项目分配一个点击侦听器,然后将该项目添加到菜单的Items列表中,该菜单正确地填充了该列表,并允许每个项目都称为点击监听器。

我已经实现了这种方法,如下所示。

 private ContextMenu _elementContextMenu;

    public ContextMenu ElementContextMenu {
        get {
            if (_elementContextMenu == null) {
                _elementContextMenu = new ContextMenu();

                //root menu item
                _elementMenuRootItem = new MenuItem();
                _elementMenuRootItem.Click += _elementMenuRootItem_Click;
                _elementMenuRootItem.ItemsSource = ElementMenuContent;

                _elementContextMenu.Items.Add(_elementMenuRootItem);
            }
            return _elementContextMenu;
        }
        set { _elementContextMenu = value; }
    }

使用这种方法,点击侦听器会将被点击的菜单项作为事件的源传递,我可以将其投射到MenuItem上,如下所示:

  void _elementMenuRootItem_Click(object sender, RoutedEventArgs e) {
        MenuItem selectedMenuItem = (MenuItem)e.OriginalSource;
    }

我要实现的是显示为列表根的项目列表。

如果我将菜单项的列表(在此实现中为名称ElementMenuContent绑定到上下文菜单的ItemsSource属性,则该菜单将按照我的意愿进行填充,但是有Click中没有ContextMenu事件。

所需的实现如下所示:

    public ContextMenu ElementContextMenu {
        get {
            if (_elementContextMenu == null) {
                _elementContextMenu = new ContextMenu();
                _elementContextMenu.ItemsSource = ElementMenuContent;

                //Add a click listener directly to the ContextMenu object which allows
                //the source menu item which was clicked to be referenced in the same way 
                //as with a MenuItem click listener
            }
            return _elementContextMenu;
        }
        set { _elementContextMenu = value; }
    }

要在其中实现的组件扩展了WPF Canvas,并且仅是.cs文件,因此必须完全在代码中实现。在这种情况下,我无法使用XAML。

任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:0)

我不确定我是否理解您的问题的这一部分:

  

我要实现的是显示为列表根的项目列表。

正如您所说,ContextMenu本身没有 Click 事件。最简单的解决方案是改为订阅 PreviewMouseUp ,它将捕获所有鼠标单击活动,然后您可以使用MouseButtonEventArgs访问所需的内容。

PreviewMouseUp https://docs.microsoft.com/en-us/dotnet/api/system.windows.uielement.previewmouseup?view=netframework-4.7.2

如果这没有帮助,您可以随时研究创建自定义的路由事件:https://docs.microsoft.com/en-us/dotnet/framework/wpf/advanced/how-to-create-a-custom-routed-event

答案 1 :(得分:0)

对于遇到同样问题的任何人,解决方案是设置菜单本身的ItemsSource属性(在这种情况下,ElementMenuContent对象是List<String>,并添加一个ContextMenu的事件处理程序,该事件处理程序在任何ClickEvent组件的MenuItem上运行,如下所示:

    _elementContextMenu.ItemsSource = ElementMenuContent;

    _elementContextMenu.AddHandler(MenuItem.ClickEvent, new RoutedEventHandler(ElementContextMenuItemClick));

处理程序方法被定义为普通方法。

    public void ElementContextMenuItemClick(object sender, RoutedEventArgs e) {
        MenuItem selectedMenuItem = (MenuItem)e.OriginalSource;
        String command = selectedMenuItem.Header.ToString();
        SwimLaneController.Instance.ProcessContextMenuCommand(this, command);
    }