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

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>

Related

Command doesn't work on top level MenuItem in MVVM

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.

Defining another level of menu items within a MenuItem ItemTemplate

I have a list of objects on my WPF window, all having a context menu which allows the user to copy or move items into different panels (so the ItemsSource of the Context menu is this list of panels, and "Copy" and "Move" are sub-menuitems). However, I have a "CanCopy" property defined in the object that determines whether or not the object can actually be copied. How can I show/hide this MenuItem depending on the value of this property? My problem seems to be in defining this variable additional level of MenuItems.
At first I tried something like this, but obviously it's not quite what I'm looking for, since this doubles up the PanelName MenuItem in to two MenuItem containers:
<MenuItem Header="Panels..." ItemsSource="{Binding PanelsList}">
<MenuItem.ItemTemplate>
<DataTemplate>
<MenuItem Header="{Binding PanelName}">
<MenuItem Header="Copy" Visibility="{Binding CanCopy,Converter={StaticResource BoolToHiddenConverter}}"/>
<MenuItem Header="Move"/>
</MenuItem>
</DataTemplate>
</MenuItem.ItemTemplate>
</MenuItem>
Suggestions?
Add as Content not ItemTemplate
<MenuItem Header="Panels..." ItemsSource="{Binding PanelsList}">
<MenuItem Header="{Binding PanelName}">
<MenuItem Header="Copy" Visibility="{Binding CanCopy,Converter={StaticResource BoolToHiddenConverter}}"/>
<MenuItem Header="Move"/>
</MenuItem>
</MenuItem>

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.

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>

Why can't I use the same Icon for more than 1 item in Menu?

I have a MenuItem like below
<MenuItem Header="Edit">
<MenuItem Header="Copy Direct Link" Icon="{StaticResource CopyIcon}" Command="{Binding CopyImageCommand}" />
<MenuItem Header="Copy Image Data" Icon="{StaticResource CopyIcon}" Command="{Binding CopyImageDataCommand}" />
<MenuItem Header="Paste" Icon="{StaticResource PasteIcon}" Command="{Binding PasteImageCommand}" />
</MenuItem>
Notice the 1st 2 items use the same icon, I get something like below
I tried removing the 2nd item,
<MenuItem Header="Edit">
<MenuItem Header="Copy Direct Link" InputGestureText="Ctrl+C" Icon="{StaticResource CopyIcon}" Command="{Binding CopyImageCommand}" />
<!--<MenuItem Header="Copy Image Data" InputGestureText="Ctrl+Alt+C" Icon="{StaticResource CopyIcon}" Command="{Binding CopyImageDataCommand}" />-->
<MenuItem Header="Paste" InputGestureText="Ctrl+P" Icon="{StaticResource PasteIcon}" Command="{Binding PasteImageCommand}" />
</MenuItem>
then I got something like
How can I reuse Icons?
See this question
An Image can only have one parent so it will be moved from the first MenuItem to the second. You can add the x:Shared attribute like this
<Window.Resources>
<Image x:Key="CopyIcon" x:Shared="False" Source="..." />
</Window.Resources>
From msdn
x:Shared Attribute
When set to false, modifies WPF
resource-retrieval behavior so that
requests for the attributed resource
create a new instance for each request
instead of sharing the same instance
for all requests.
You're most likely declaring CopyIcon as Image type in your resource, something like this:
<Window.Resources>
<Image x:Key="CopyIcon" Source="yourcopyicon.ico"/>
</Window.Resources>
So, the root cause of the problem is, Image is a visual element, since it derives from FrameworkElement (which is a visual element), and a visual element cannot have more than one parent at the same time. That is why the first MenuItem is not showing the icon, since the second MenuItem reset the parent of CopyIcon, making itself parent of the CopyIcon.
Hope this explanation is helpful to you. Now follow what Meleak has said in his response. :-)
Try the following:
<MenuItem Header=“Paste“ >
<MenuItem.Icon><Image Height=“16“ Width=“16“ Source=“paste.jpg“ /></MenuItem.Icon>
</MenuItem>

Resources