Command doesn't work on top level MenuItem in MVVM - wpf

It works fine if the MenuItem doesn't have a sub MenuItem, like this:
<MenuItem Header="Open" Command="{Binding OpenCommand}"/>
but, when I add a sub MenuItem to it, the Command doesn't work:
<MenuItem Header="Open" Command="{Binding OpenCommand}">
<MenuItem />
</MenuItem>
click event also doesn't work like this:
<MenuItem Header="Open" Click="MenuItem_Click">
<MenuItem />
</MenuItem>
when I try to add the Command to the header:
<MenuItem>
<MenuItem.Header>
<TextBlock>
<TextBlock.InputBindings>
<MouseBinding Gesture="LeftClick" Command="{Binding OpenCommand}"/>
</TextBlock.InputBindings>
Open
</TextBlock>
</MenuItem.Header>
<MenuItem />
</MenuItem>
the Command works but the sub MenuItem doesn't show.
Any help will be appreciate, and forgive my half-baked English.

If you have sub MenuItems the click event is used (and expected by the user) to show the sub-menu. To react upon a submenu opening use the event SubmenuOpened.
If you really want to be able to open a sub menu and click on the "Open", you could use this snipper, but I'd really not advice it:
<MenuItem SubmenuOpened="MenuItem_OnSubmenuOpened"> <!-- handle sub menu opening if desired -->
<MenuItem.Header>
<Button Click="Button_Click">Open V2</Button> <!-- handle click on "Open" if desired; doesn't open sub menu! -->
</MenuItem.Header>
<MenuItem />
</MenuItem>
Note that I have tested this with "Open" not being the top level menu item.

Related

Add 'Select All' context menu item to default TextBox menu items

I have a TextBox in CellEdititngTemplate for DataGridTemplateColumn in my DataGrid and I want to show 4 context menu items (Cut, Copy, Paste, Select All) when my DatagridCell is in edit mode and user right-clicks on it.
I see that default right-click context menu for TextBox control contains only 3 menu items: Cut (Ctrl+X), Copy (Ctrl+C), Paste (Ctrl+V).
There's no 'Select All' context menu item though Ctrl+A works for TextBox. So the question is - how to add a new Context Menu item 'Select All' into TextBox context menu without loosing cut, copy, paste menu items and their functionality?
I don't think you can change existing context menu, but you can create yours and repeat other commands
<ContextMenu>
<MenuItem Command="ApplicationCommands.Cut" />
<MenuItem Command="ApplicationCommands.Copy" />
<MenuItem Command="ApplicationCommands.Paste" />
<MenuItem Command="ApplicationCommands.SelectAll" />
</ContextMenu>
Usually I see a separator between the clipboard items and Select All. This worked for me in a RichTextBox:
<FrameworkElement.ContextMenu>
<ContextMenu>
<MenuItem Command="{x:Static ApplicationCommands.Cut}" />
<MenuItem Command="{x:Static ApplicationCommands.Copy}" />
<MenuItem Command="{x:Static ApplicationCommands.Paste}" />
<Separator />
<MenuItem Command="{x:Static ApplicationCommands.SelectAll}" />
</ContextMenu>
</FrameworkElement.ContextMenu>

How to apply a custom style context menu for TextBox (default context menu copy/cut/paste)?

I create style for the MenuItem.
When I create my own menu, everything is good.
But how can I apply a style to the context menu of TextBox?
I mean, the menu (Copy, Cut, Paste, etc.) - I do not want to create new lines, and just change the style.
//My Custom Menu Example
<UserControl.ContextMenu>
<ContextMenu Style="{StaticResource ContextMenuStyle}" HasDropShadow="True">
<MenuItem x:Name="MenuItem1" Header="Open"
Style="{StaticResource ContextMenuItem}">
</MenuItem>
<MenuItem x:Name="MenuItem2" Header="Save"
Style="{StaticResource ContextMenuItem}">
</MenuItem>
<MenuItem x:Name="MenuItem3" Header="Delete"
Style="{StaticResource ContextMenuItem}">
</MenuItem>
</ContextMenu>
</UserControl.ContextMenu>
You will technically have to to do the same thing you did to your UserControl.ContextMenu to the TextBox.ContextMenu.
Look the below link which has exactly the scenario you are asking about with xaml.

WPF menu tab navigation

I have a view with a menu:
<Menu IsTabStop="False">
<MenuItem
Header="_File"
IsTabStop="True">
<MenuItem
Header="New / Start Over"
IsTabStop="True"
InputGestureText="Ctrl+N"
Command="{x:Static common:Commands.StartOverCommand}" />
<Separator
IsTabStop="False" />
<MenuItem
Header="Log Out"
IsTabStop="True"
InputGestureText="F12"
Click="LogoutMenuItem_Click" />
<MenuItem
Header="E_xit"
IsTabStop="True"
InputGestureText="Alt+F4"
Click="ExitMenuItem_Click" />
</MenuItem>
<MenuItem
Header="_Edit"
IsTabStop="True">
<MenuItem
Header="Undo Edit Field"
IsTabStop="True"
InputGestureText="Ctrl+Z"
Click="_undoMenuItem_Click" />
<MenuItem
Header="Redo Edit Field"
IsTabStop="True"
InputGestureText="Ctrl+Y"
Click="_redoMenuItem_Click" />
</MenuItem>
<MenuItem
Header="_Tools"
IsTabStop="True">
<MenuItem
Header="Comments"
IsTabStop="True"
InputGestureText="Ctrl+M"
Click="_commentsMenuItem_Click" />
</MenuItem>
</Menu>
I would like to be able to navigate through the menus (File, Edit, Tools) by using the right and left arrow keys, which I was able to accomplish by making these MenuItems IsTabStop="True". But since I did this I am able to tab to the menu as I cycle through the other valid fields on a page. When I use Alt+F to put focus on the File menu I want to be able to cycle through the 3 menus with the arrow keys, but I don't want to be able to tab to these menus from the page. How would I accomplish this?
Use the KeyboardNavigation.TabNavigation Attached Property with KeyboardNavigationMode.None on menu.
<Menu KeyboardNavigation.TabNavigation="None">

How to create a right-click context menu for a button in WPF

i know how to create a left-click context menu for a button, but I am not too sure how to do it for a right click? (i.e. how to specify that the context menu should appear on a right-click, not a left click).
Many thanks.
Here is a sample:
<Button Content="button" Name="btn" Width="100">
<Button.ContextMenu>
<ContextMenu>
<MenuItem Header="Cut"/>
<MenuItem Header="Copy"/>
<MenuItem Header="Paste"/>
</ContextMenu>
</Button.ContextMenu>
</Button>

XAML and Binding Submenu items in a ContextMenu?

I have a ContextMenu defined on a Datagrid but want to bind submenu items to a collection on my viewmodel. Can anybody suggest how this should be done?
The following is a simple example of what I'm trying to achieve, BUT I want "Test1", "Test2" to come from a collection on my viewmodel, not hardcoded. I know how to bind my collection to the whole ContextMenu, but not how to bind it to just the one submenu...
<ContextMenu>
<MenuItem Header="Add to">
<MenuItem Header="Test1" />
<MenuItem Header="Test2" />
</MenuItem>
<MenuItem Header="Remove from All" />
</ContextMenu>
I'm using 3.5 SP1 and the WPF Toolkit.
Guess I should have experimented more. Turns out this was relatively simple:
<my:DataGrid.ContextMenu>
<ContextMenu>
<MenuItem Header="Add to" ItemsSource="{Binding MyItems}">
<MenuItem.ItemTemplate>
<DataTemplate>
<MenuItem CommandTarget="{Binding}" Click="AddClick">
<MenuItem.Header>
<TextBlock>
<TextBlock.Text><Binding StringFormat="Add to {0}" /></TextBlock.Text>
</TextBlock>
</MenuItem.Header>
</MenuItem>
</DataTemplate>
</MenuItem.ItemTemplate>
</MenuItem>
<MenuItem Header="Remove from All" />
</ContextMenu>
</my:DataGrid.ContextMenu>
There is a bug when using MenuItem.ItemTemplate. The color when do mouse over on the sub menu make user misunderstand that they can click to select the menu but it doesn't work for all area even if it's highlighted. See the picture
Then I used this code instead and it worked fine for me.
<ContextMenu>
<MenuItem Header="Add to" ItemsSource="{Binding MyItems}"
DisplayMemberPath="{Binding ItemName}">
<MenuItem.ItemContainerStyle>
<Style>
<EventSetter Event="MenuItem.Click" Handler="Menu_Click"/>
</Style>
</MenuItem.ItemContainerStyle>
</MenuItem>
<MenuItem Header="Remove from All" />
</ContextMenu>

Resources