How to disable context menu in WPF? - wpf

I have two Menu items in a wpf context,
I bind them with command, how do I hide context menu when both items are not available, I mean when both commands cannot be executed?

Add an event handler for ContextMenuOpening event. Set Handled property in ContextMenuEventArgs object to true and the context menu will not open.

Related

Popup Never Closes

WPF is really getting me out of my nerves here. I configured a popup with some complex content (grid, buttons etc..). I set its StaysOpen property to False and IsOpen to True on a textbox MouseDown preview event.
Ths thing is that it opens but never closes when clicking anywhere outside the window.
Any suggestions?
Thanks!
UPDATE:
My popup has buttons inside. When I click one of those, the popup closes when I click outside of it. Is some weird stuff happening to the events routing?
Looks like the popup won't close if opened by any other control event. I just binded the IsOpen property to the IsChecked property of a ToggleButton to simulate a combobox.
Thanks for all your answers.
I was also having this issue, except on the PreviewMouseButtonUp event of a Button. The assumption that there is some bug with Popups and trying to open them in Tunneling events was accurate and led me down the path to my fix (which is a little more generic).
I needed to resolve this (the host control was generic / could be several types of controls) by listening for the bubbling event instead of the tunneling event, specifically with the AddHandler(RoutedEvent,Delegate,Boolean) method in order to capture handled events.
WAG the issue lies somewhere when transitioning from tunneling to bubbling.
I use code behind to initialize popup, and I've found that it's not closed if ran sync from other UI action like mouse event. To workaround this I run it async:
public static void ShowPopupMessage(string message)
{
DispatcherHelper.UIDispatcher.BeginInvoke(new Action(() =>
{
var popup = new Popup
{
Child = new AutoHideMessage(message),
StaysOpen = false,
IsOpen = true
};
}));
}
I set IsOpen on a textbox MouseDown preview event.
Set it to what? And where is the TextBox hosted?
I can only guess with the scant information provided, but I'd say when you click outside the Popup, your event handler is firing and opening it up again.
You can use LostFocus event of the PopUp. If the focus is not within the popup, set its IsOpen to false to close it.

WPF: Context Menu dissapears after item update in my GridView

so, I have this ListView in grid mode. I am dynamically updating it using a CollectionView. now, the problem I have is that when I open a context menu by right clicking on an item in my grid the context menu closes after the item updates--now, it is not a new item but it is the same item. Does anyone have any ideas on how I can make the contet menu stay open after the item updates?
[Edit]
The grid is part of a public safety application that updates in near real-time. so the items are periodically added, removed, and updated. If we right-click on an item to open the context menu and an update occurs before I can close it--even if the particular item does not change in any way--the context menu closes. The desired behavior is for the context menu to remain open.
If you could supply your XAML that would help, but my guess is that you have defined the context menu on the ListViewItem element and that the menu closes because the whole ListViewItem is regenerated or replaced by WPF.
Perhaps you can define the context menu on the ListView instead? You will have to update your commands and get the selected item from the list when executing, since the context will no longer be a specific item.

WP7 - Cancelling ContextMenu click event propagation

I'm having a problem when the Silverlight toolkit's ContextMenu is clicked while it is over a UIElement that has registered a Tap event GestureListener. The context menu click propagates to the underlying element and fires its tap event.
For instance, say I have a ListBox and each ListBoxItem within it has registered both a ContextMenu and a Tap GestureListener. Assume that clicking context menu item2 is supposed to take you to Page1.xaml, while tapping on any of ListBox items themselves is supposed to take you to Page2.xaml.
If I open the context menu on item1 in the ListBox, then context menu item2 is on top of ListBox item2. When I click on context menu item2 I get weird behavior where the app navigates to Page1.xaml and then immediately to Page2.xaml because the click event also triggered the Tap gesture for ListBox item2.
I've verified in the debugger that it is always the context menu that receives the click event first. How do I cancel the context menu item click's routed event propagation so it doesn't reach ListBox item2?
Thanks for your help!
You can get around the problem by doing the following:
In the context menu's Opened handler set LayoutRoot.IsHitTestVisible (LayoutRoot is the default name for the root UIElement) to false
In the context menu's Closed handler set LayoutRoot.IsHitTestVisible back to true
You could try adding a rectangle with a transparent background (important) over the effected area/page when showing the context menu.
I had a very similar issue, but I am using the ManipulationCompleted event as a "tap" detector as the object the ContentMenu applies to is a custom control.
LayoutRoot.IsHitTestVisible didn't work for me, perhaps because it does not apply to Manipulation events. However, it set me on the right path. I just implemented my own simple equivalent of it - I created a boolean variable bCancelManipulation in the page's scope.
In the ContentMenu's Opened event set it to True.
In the ContentMenu's Closed event set it to False.
In the ManipulationCompleted function, the first thing I do is check
if(bCancelManipulation==true) { return; }
It's kind of a hack, but it works great and is quite simple to code - it can easily be adapted to a Tap event too.

WPF composite Application - tab region - view not getting focus

I'm just starting to use the composite application libraries for WPF. In my shell I have a region in a tabcontrol that is used to display different types of views. I also have a toolbar with buttons hooked up to commands, for example save. The commands are bound in my views, and the views have the canExecute and execute methods.
The idea is that when i click a tab, my tool bar buttons should be enabled or disabled according to the methods in the view. Problem is when I switch tabs the view is not getting the focus and the canExecute for that view doesn't get called. The toolbar buttons remain connected to the commands in the previously selected view, and reminds that way until i actually click on the new view
I'm stumped right now on how to force the view to get the focus. I've tried looking at the tab's content when the tabs SelectionChanged and setting the focus there but its not making a difference. Any ideas?
Try listening for the View.Loaded event, then call View.focus() in the handler. Wpf will not accept focus requests before an element is initialized and loaded. Since the SelectionChanged event is raised before the view is loaded, the focus request will just be ignored. The loaded event is called each time the element is shown after being hidden.
See this blog post for more information on focus:
http://www.julmar.com/blog/mark/PermaLink,guid,6e4769e5-a0b3-47b2-a142-6dfefd0c028e.aspx

Systray context menu - why are my commands not enabled?

I'm creating a WPF app and have a system tray icon with a context menu. For the menu items I want to use WPF commands but when I assign them they are always greyed out even though the (same) commands are enabled in other places.
MenuItem menuItem = new MenuItem();
menuItem.Header = "Exit";
menuItem.Command = CustomCommands.ExitApplication;
Systray.AddMenuItem(menuItem);
It works fine when I assign click events and I have tried to create a CanExecute method for the command which always sets CanExecute to true, but that doesn't help either. Anyone got an idea why the menu items are disabled?
Update: As suggested, I added a command binding to the context menu. This had the effect that it works but only after you have clicked on the menu, i.e., at first the menu items are greyed out but once you click somewhere on the menu the options become enabled.
To solve this problem I called the following, after I added the menu items to the context menu:
CommandManager.InvalidateRequerySuggested();
Of the top of my head I'd guess you have to add a CommandBinding to the Menu or systray so that your command gets handled. Although I think if that were the case it would be enabled by default.
Yea I've seen this occur. Sometimes you have to tell the WPF CommandManager system to rerun the CanExecute methods. Try calling this once the ContextMenu is loaded: CommandManager.InvalidateQuerySuggested();
I had a similar issue. I feel my solution it's a bit of a hack, but I could really not get around this problem. I'm using a custom DelegateCommand implementation, and ebabling/disabling buttons and menu items works except for items in context menus. So, what I did was to handle the ContextMenuOpening event, then store the Items in a temp variable, call the Clear method in the ContextMenu and re-add the items right after. Works like a charm, but like I said, feels "hacky". It goes something like this:
private void ContextMenu_ContextMenuOpening (object sender, System.ComponentModel.CancelEventArgs e)
{
// HACK: For some reason items need to be removed and added back so that the command enablement requery works.
var menu = sender as ContextMenu;
if (menu == null) return;
var menuItems = menu.Items.ToArray();
menu.Items.Clear();
foreach (var menuItem in menuItems)
menu.Items.Add(menuItem);
}

Resources