I have hooked up a context menu item in a listbox item such that tapping it will change its state. I need either the menu to stay open after the item has been selected, or to programmatically reopen the menu right after it closes.
My menu looks like so:
Some Command 1
Some Command 2
Some Command 3
Inverted
And the user can tap the Inverted
command and then tap one of the other commands to cause them to function in Inverted Mode, and the menu through data binding appears like so:
Some Command 1
Some Command 2
Some Command 3
Inverted ✔
Not being able to figure out how to keep the menu open after tap, I've tried the less ideal reopen menu approach like so:
private void onCommandInvert(object sender, RoutedEventArgs e)
{
CommandState.Instance.Inverted = !CommandState.Instance.Inverted;
// Open it again.
MenuItem menuItem = (MenuItem)sender;
ContextMenu menu = (ContextMenu)menuItem.Parent;
menu.IsOpen = true;
}
But doing so throws the following exception on the menu.IsOpen = true
statement:
A first chance exception of type 'System.InvalidOperationException' occurred in
System.Windows.dll
An unhandled exception of type 'System.InvalidOperationException' occurred in
System.Windows.dll
Additional information: Element is already the child of another element.
I have also tried the following with the Closed
event, with the same exception occurring:
private void onContextMenuClosed(object sender, RoutedEventArgs e)
{
ContextMenu menu = (ContextMenu)sender;
menu.IsOpen = true;
}
Any ideas? Thanks!
I got it! Thanks to willmel's comment, I digged through the source code for the MenuItem
and was able to override OnClick()
to do exactly what I needed (the ideal solution no doubt). I couldn't access Click
however, so I needed to introduce a StayClick
event property as well.
Enjoy!
using Microsoft.Phone.Controls;
using System.Windows;
namespace MyNamespace
{
public class MenuItemEx : MenuItem
{
public bool StayOpenWhenClicked
{
get;
set;
}
public event RoutedEventHandler StayClick;
protected override void OnClick()
{
if (StayOpenWhenClicked)
{
if (StayClick != null)
{
StayClick.Invoke(this, new RoutedEventArgs());
}
}
else
{
base.OnClick();
}
}
}
}
and in the page's xaml, instead of toolkit:MenuItem
you use my:MenuItemEx
<my:MenuItemEx
Header="Inverted"
StayClick="onCommandInvert"
StayOpenWhenClicked="True"
/>
If you want to persist the menu after the user has selected an item then I believe the Context menu control is not what you should be using.
Better you should create your own user control to mimic the behaviour and have it place appropriately on the screen where it makes sense (to the side or above/below)
Alternatively if these are options to be enacted on selected items consider using the application bar icons / menu items and write the event code to read the currently selected value of the listbox item.
Hope this helps.
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.