简体   繁体   中英

How do I subscribe to context menu closing event in WPF?

I have attempted various solutions, such as the one found here , which has the accepted answer of the following:

<Button ContextMenuClosing="ContextMenu_ContextMenuClosing">
    <Button.ContextMenu>
        <ContextMenu>
             <MenuItem Header="Go"/>
        </ContextMenu>
    </Button.ContextMenu>
 </Button>

However, after implementing the above solution, I have still been unsuccessful listening to the ContextMenuClosing event, no matter how it is closed (making a selection, clicking the parent button, clicking anywhere off the menu or button). Below is my code, what am I doing wrong?

TestPage.xaml

<Page x:Class="MyProject.pages.TestPage"
    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:MIMOUI.pages"
    mc:Ignorable="d"
    d:DesignHeight="300"
    d:DesignWidth="300"
    Title="TestPage">

    <Grid>
        <Button x:Name="myMenuButton" 
            Width="140" 
            Height="100" 
            Click="myMenuButton_Click"
            ContextMenuClosing="myMenuButton_ContextMenuClosing"
            Background="NavajoWhite" 
            Foreground="BurlyWood">

            <Button.ContextMenu>
                <ContextMenu x:Name="myMenuButton_ContextMenu" Width="250">
                    <MenuItem x:Name="myTaskMenuButton" Header="TASKS" />
                    <MenuItem x:Name="myTransactionButton" Header="TRANSACTION" />
                    <MenuItem x:Name="mySetupMenuButton" Header="SETUP" />
                </ContextMenu>
            </Button.ContextMenu>
        </Button>
    </Grid>
</Page>

TestPage.xaml.cs

using System;
using System.Windows;
using System.Windows.Controls;

namespace MyProject.pages {
    public partial class TestPage : Page {
        public TestPage() {
            InitializeComponent();
        }

        public void myMenuButton_Click(object sender, RoutedEventArgs e) {
            (sender as Button).ContextMenu.IsOpen = true;
        }

        public void myMenuButton_ContextMenuClosing(object sender, RoutedEventArgs e) {
            Console.WriteLine("intercepted!!!!");
            e.Handled = true;
        }
    }
}

For reasons unknown to me ContextMenuClosing seems not to be triggered when it was opened by your Click code. If you would open ContextMenu by right-click on your button event is triggered as expected. As a workaround you can use ContextMenu.Closed event which seems to be called in both cases

<Button x:Name="myMenuButton" Click="myMenuButton_Click" ...>
    <Button.ContextMenu>
        <ContextMenu ... Closed="myMenuButton_ContextMenu_Closed">
            <MenuItem x:Name="myTaskMenuButton" Header="TASKS" />
            <MenuItem x:Name="myTransactionButton" Header="TRANSACTION" />
            <MenuItem x:Name="mySetupMenuButton" Header="SETUP" />
        </ContextMenu>
    </Button.ContextMenu>
</Button>

and in your code

private void myMenuButton_ContextMenu_Closed(object sender, RoutedEventArgs e)
{
    Debug.WriteLine("myMenuButton_ContextMenu_Closed");
}

the only difference seems to be that you cannot stop ContextMenu from closing as you would be able to in ContextMenuClosing event

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM