简体   繁体   中英

How to raise ContextMenuOpening event when opening context menu programmatically

When I open a context menu with <control>.ContextMenu.IsOpen = true , the context menu becomes visible but neither the opening or closing events are triggered.

How can I make sure the ContextMenuOpening and ContextMenuClosing events are raised when I open a context menu programmatically?


Demo:

Look at the following 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>

And the following code-behind

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");
}

Behavior when right-clicking on the button:

Context menu is opening.

Output is:

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

Behavior when left-clicking on the button:

Context menu is opening.

Output is:

<Nothing>

The Issue is that you've attached events on ContextMenuOpening of Button, and since you are invoking the ContextMenu manually the events did not fire

so to get the events attach the Opened and Closed event from ContextMenu

    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>

events, ContextMenuEventArgs changed to 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");
    }

button click remain same.

this should solve your issue

There is difference between Opened and Opening event. Usually Opening event is used to build the menu dynamically before menu are shown. The above solution will not work in such case.

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

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