I would like to control when the contextmenu of my control to show or not.
here is my code:
void MyControl_MouseRightButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
if ( some condition .....)
{
this.Focus();
contextmeun.PlacementTarget = this;
contextmeun.IsOpen = true;
}
}
However, it just show up less than 1 second then disappear immediately. Why is that?
Thank you for all your help!
Probably because you're focussing the control that the context menu belongs to, then showing the context menu, however when the parent control gets focus, the context menu closes.
Try setting the context menu in Xaml instead to get the correct behaviour
<MyControl>
<MyControl.ContextMenu>
<ContextMenu>
<!-- Define context menu here -->
</ContextMenu>
</MyControl.ContextMenu>
</MyControl>
This can be done in pure XAML form, all you need to do is bind your visibility of context menu with a bool property containing your condition like this -
<YourControl>
<YourControl.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
</YourControl.Resources>
<YourControl.ContextMenu>
<ContextMenu Visibility="{Binding IsEnable,
Converter={StaticResource BooleanToVisibilityConverter}}">
<MenuItem Header="MenuItem1"/>
<MenuItem Header="MenuItem2"/>
<MenuItem Header="MenuItem3"/>
</ContextMenu>
</YourControl.ContextMenu>
</YourControl>
Here IsEnable is a plain CLR property, in its getter you can have the logic for your condition depending on which you need to toggle the visibility of your context menu..
Related
I have a ListBox dynamically generated.
In this ListBox there are some Items that the user could select, one or more, by left click.
With the right click on an Item of the ListBox area he could show a context menu.
My problem is that if the user right-clicks in the ListBox area all goes right, but if he right-clicks on an Items he toggles the selection.
I want to avoid the Items toggling by the right click.
This is how I configured the ListBox in the MyWindow.cs:
MyBeautifulList.SelectionMode = SelectionMode.Extended;
And this is a portion of the relative XAML file:
<ListBox.ContextMenu>
<ContextMenu>
<MenuItem Header="Send file" Click="SendFileToUser" />
<MenuItem Header="Send folder" Click="SendFolderToUser" />
<MenuItem Header="Copy user ID to the clipboard" Click="copyUserIDtoClipboard" />
</ContextMenu>
</ListBox.ContextMenu>
As well as click, wpf offers a bunch of other options.
Due to bubbling and tunnelling routed events which you might want to read up on.
You can handle the preview version of an event, mark it as handled and then it stops it firing.
void MenuItem_PreviewRightMouseButtonDown(object sender, MouseButtonEventArgs e)
{
e.Handled = true;
}
You will then have no context menu appear, so you will need to show the context menu using code.
Name your context menu
<ContextMenu Name="SomeMeaningfulName">
You can then set IsOpen in code in your new handler, like:
SomeMeaningfulName.IsOpen = true;
I have a WPF ContextMenu instance declared in my XAML like this
<Window.ContextMenu>
<ContextMenu>
<MenuItem Header="Do Nothing"/>
<Separator/>
<MenuItem Header="{x:Static p:Resources.MenuExit}" Click="IconMenu_Exit"/>
</ContextMenu>
</Window.ContextMenu>
I'm using the WinForms NotifyIcon to display a tray icon like this
_notifyIcon = new System.Windows.Forms.NotifyIcon();
_notifyIcon.Icon = Properties.Resources.mainicon;
_notifyIcon.Visible = true;
_notifyIcon.MouseClick += new System.Windows.Forms.MouseEventHandler(OnTrayIconMouseClick);
The implementation of the mouse click handler is this
private void OnTrayIconMouseClick(object sender, System.Windows.Forms.MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Right)
{
ContextMenu.IsOpen = true;
}
}
This displays the context menu and clicking on the menu items dismisses it, but if I just click away on another window, the context menu stays visible. This seems like strange default behavior. Is there another way to display the context menu other than IsOpen or do I have to explicitly hide the context menu somehow?
Edit: I don't know if it matters but the window's DataContext is set to this in its code-behind.
Edit2: The context menu dismisses properly if it's invoked by right clicking on the actual main window but not from the tray icon.
Check that you have not defined the StaysOpen property as true.
I have been working with c# for some time now but surprisingly I have never dealt with context menus before. I have a listView control in my universal windows 8.1 app. Now I am trying to get a context menu to popup for each item in the listView (they are all the same type of object and are added to the list as the user adds entries). I have run into several problems with this and have looked at code examples and they seem to be leading in different directions. Firstly when I right click on an item in the list it does not fire the ListView_RightTapped event.
<ListView x:Name="lstvwHours" HorizontalAlignment="Left" Height="264" Margin="427,77,0,0" VerticalAlignment="Top" Width="357" RightTapped="lstvwHours_RightTapped">
Secondly in Microsoft's context menu code example they say to use the PopupMenu class but in other code I've seen it coded into the XAML.
And lastly After the one context menu button is clicked I want it to fire a delete method.
private async void lstvwHours_RightTapped(object sender,
RightTappedRoutedEventArgs e)
{
var menu = new PopupMenu();
menu.Commands.Add(new UICommand("Delete"/*do I put the method to call here?*/));
var chosenCommand = await menu.ShowForSelectionAsync(GetElementRect((FrameworkElement)sender));
}
Here's an example.
In this case you can wire-up the commands that get invoked from your menuitem onto your view-model.
<ListView>
<ListViewItem Content="One">
<ListViewItem.ContextMenu>
<ContextMenu>
<MenuItem Header="Insert"
Command="{Binding DataContext.InsertQuery, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}}"/>
<MenuItem Header="Delete"
Command="{Binding DataContext.DeleteQuery, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}}"/>
</ContextMenu>
</ListViewItem.ContextMenu>
</ListViewItem>
</ListView>
Is it possible to bind the IsEnabled property of a button to a context menu item that is represented by a NotifyIcon?
When I push the menu item, it starts a method that disables my btnSave. In that case, I would like to "turn off" the MenuItem too. I attempted it this way, but it's not working:
<Window.Resources>
<ContextMenu x:Key="NotifierContextMenu" Placement="MousePoint">
<MenuItem Header="Start" Click="start_timer" IsEnabled="{Binding ElementName=btnSave, Path=IsEnabled}"/>
</ContextMenu>
</Window.Resources>
I believe your problem stems from a ContextMenu not existing within the visual tree, so ElementName bindings will be unsuccessful, unless you take some additional steps to correct the Name Scope, or resolve the DataContext to the visual tree.
Most of the techniques are covered fairly comprehensively in this answer: ElementName Binding from MenuItem in ContextMenu.
I've had success in the past with binding to a named element by reference, in your case, that would look something like this:
<MenuItem Header="Start"
IsEnabled="{Binding IsEnabled, Source={x:Reference btnSave}}"
Click="btnSave_Click"/>
I have a context menu to show up manually by pressing the hotkey ctrl+menu. Therefore i use this function:
ContextMenu.IsOpen = true;
I call this in my main window. But it has some odd effects.
If I only press the menu-key, the menu alwasy appears in the middle of the screen
If I manually call the menu, it always appears in the top left corner.
my menu is this one:
<Window.ContextMenu>
<ContextMenu Placement="Center">
<MenuItem IsCheckable="False" Name="item2" Click="MenuItem_Click" Header="{DynamicResource countDownNotificationOn}"/>
</ContextMenu>
</Window.ContextMenu>
using the xaml placement above dosen't work either. Therefore I set the window to
ContextMenuService.Placement="Center"
But doesn't work.
You need to set the PlacementTarget property of the ContextMenu:
if (element.ContextMenu != null )
{
element.ContextMenu.PlacementTarget = element;
element.ContextMenu.IsOpen = true;
}
If after this, the ContextMenu is still not placed correctly, you can set the placement using the ContextMenu.HorizontalOffset and ContextMenu.VerticalOffset properties. Take a look at the ContextMenu.HorizontalOffset Property and ContextMenu.VerticalOffset Property pages at MSDN for more information.