【问题标题】:How to raise ContextMenuOpening event when opening context menu programmatically以编程方式打开上下文菜单时如何引发 ContextMenuOpening 事件
【发布时间】:2020-07-28 18:31:55
【问题描述】:

当我使用<control>.ContextMenu.IsOpen = true 打开上下文菜单时,上下文菜单变为可见,但不会触发打开或关闭事件。

当我以编程方式打开上下文菜单时,如何确保引发 ContextMenuOpeningContextMenuClosing 事件?


演示:

看看下面的 XAML

<Button Name="ContextMenuButton" 
        Content="Click me!" 
        Click="ContextMenuButton_Click" 
        ContextMenuOpening="ContextMenuButton_OnContextMenuOpening"
        ContextMenuClosing="ContextMenuButton_OnContextMenuClosing">
    <Button.ContextMenu>
        <ContextMenu>
            <MenuItem Header="First element" />
            <MenuItem Header="Second element" />
        </ContextMenu>
    </Button.ContextMenu>
</Button>

还有下面的代码

public MainWindow() // Constructor
{
    InitializeComponent();
    ContextMenuButton.ContextMenuOpening += (sender, args) => Debug.Print("Opening #2");
    ContextMenuButton.ContextMenuClosing += (sender, args) => Debug.Print("Closing #2");
}

private void ContextMenuButton_Click(object sender, RoutedEventArgs e)
{
    Button button = (sender as Button);
    button.ContextMenu.IsOpen = true; // How should I open the ContextMenu?
}

private void ContextMenuButton_OnContextMenuOpening(object sender, ContextMenuEventArgs e)
{
    Debug.Print("Opening #1");
}

private void ContextMenuButton_OnContextMenuClosing(object sender, ContextMenuEventArgs e)
{
    Debug.Print("Closing #1");
}

右键单击按钮时的行为:

上下文菜单正在打开。

输出是:

Opening #1
Opening #2
Closing #1
Closing #2

左键单击按钮时的行为:

上下文菜单正在打开。

输出是:

<Nothing>

【问题讨论】:

    标签: c# wpf wpf-controls contextmenu


    【解决方案1】:

    问题是您在 Button 的 ContextMenuOpening 上附加了事件,并且由于您手动调用 ContextMenu,因此事件没有触发

    所以要从 ContextMenu 中附加 Opened 和 Closed 事件来获取事件

        public MainWindow() // Constructor
        {
            InitializeComponent();
            ContextMenuButton.ContextMenu.Opened += (sender, args) => Debug.Print("Opening #2");
            ContextMenuButton.ContextMenu.Closed += (sender, args) => Debug.Print("Closing #2");
        }
    

    xaml

        <Button Name="ContextMenuButton" 
                Content="Click me!" 
                Click="ContextMenuButton_Click" >
            <Button.ContextMenu>
                <ContextMenu Opened="ContextMenuButton_OnContextMenuOpening" Closed="ContextMenuButton_OnContextMenuClosing">
                    <MenuItem Header="First element" />
                    <MenuItem Header="Second element" />
                </ContextMenu>
            </Button.ContextMenu>
        </Button>
    

    事件,ContextMenuEventArgs 改为 RoutedEventArgs

        private void ContextMenuButton_OnContextMenuOpening(object sender, RoutedEventArgs e)
        {
            Debug.Print("Opening #1");
        }
    
        private void ContextMenuButton_OnContextMenuClosing(object sender, RoutedEventArgs e)
        {
            Debug.Print("Closing #1");
        }
    

    按钮点击保持不变。

    这应该可以解决您的问题

    【讨论】:

      【解决方案2】:

      Opened 和Opening 事件之间存在差异。通常,Opening 事件用于在显示菜单之前动态构建菜单。在这种情况下,上述解决方案将不起作用。

      `
       // Raise Context menu Opening Event
       var args = CreateInstance<ContextMenuEventArgs>(element, true);
       args.RoutedEvent = FrameworkElement.ContextMenuOpeningEvent;
       element.RaiseEvent(args);
       
       contextMenu.IsOpen = true;
      `
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-05-05
        • 2014-05-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-04-05
        • 2021-12-13
        • 1970-01-01
        相关资源
        最近更新 更多