Place a dividing line in a menu in WPF - wpf

In XAML, how do I put a standard dividing line in a menu?
eg
<MenuItem Header="_File" Name="m_fileMenu">
<MenuItem Header="_Open" Command="ApplicationCommands.Open"/>
<!-- Trying to put a divider here! -->
<MenuItem Header="-" /> <!-- Wrong guess -->
<MenuItem Header="E_xit" Command="ApplicationCommands.Close" />
</MenuItem>

Use a Separator like this:
<MenuItem Header="_Open" Command="ApplicationCommands.Open" />
<Separator />
<MenuItem Header="E_xit" Command="ApplicationCommands.Close" />

I needed to iterate through MenuItems for various reasons, and using Separator meant a bit of casting, so I used a 1px high MenuItem instead
<MenuItem Height="1" Background="LightGray"/>
The correct answer most definitely is to use Separator, but the above works visually too, and can be a solution in some cases.

Related

wpf extend contextmenu of textbox

I am searching for a way to extend the contextmenu of a textbox. I know there are dozens of solutions out there that recreate the contextmenu as a whole, but how on earth can I simply add one custom entry to a existing context menu?
Thanks
Klaus
<TextBox>
<TextBox.ContextMenu>
<ContextMenu>
<MenuItem Command="ApplicationCommands.Cut" />
<MenuItem Command="ApplicationCommands.Copy" />
<MenuItem Command="ApplicationCommands.Paste" />
<MenuItem Command="ApplicationCommands.SelectAll" />
//Your own item here
</ContextMenu>
</TextBox.ContextMenu>
</TextBox>
Please not that all command are automatically operation and will work as expected

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">

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>

WPF menu item with image

How to define MenuItem.Icon so that the MenuItemHeader text would be placed below the menu item image?Thanks for help!
How something along the lines of:
<ContextMenu>
<MenuItem Header="Reports">
<MenuItem.Icon>
<Image Source="/XSoftArt.WPFengine;component/Images/export32x32xp.png"/>
</MenuItem.Icon>
</MenuItem>
</ContextMenu>
The easy way way is to not use the Icon property but to instead put the icon in the Header:
<Menu>
<MenuItem>
<MenuItem.Header>
<StackPanel>
<Image Width="20" Height="20" Source="/XSoftArt.WPFengine;component/Images/export32x32xp.png" />
<ContentPresenter Content="Reports" />
</StackPanel>
</MenuItem.Header>
</MenuItem>
<MenuItem Header="Export" />
<MenuItem Header="New record" />
</Menu>
For this simple case the <ContentPresenter Content="Reports" /> can be replaced with a <TextBlock Text="Reports" /> because that's what ContentPresenter would use to present the string anyway. For more complex Header=, you could use the ContentPresenter as shown.
In the case of StackPanel use Label and not the TextBlock since only Label will allow you to have the mnemonics on the menu, like _Reports.

How to add Submenus in a Menu

How does one make submenu's in WPF and are their ways to orientate the layout?
For submenus you can add as many MenuItem nested inside.
<Menu>
<MenuItem Header="File">
<MenuItem Header="Open"/>
<MenuItem Header="Close"/>
</MenuItem>
<MenuItem Header="Edit">
<MenuItem Header="Copy"/>
<MenuItem Header="Paste"/>
</MenuItem>
<MenuItem Header="Options"/>
Just redefine the ItemsPanel:
<Menu>
<Menu.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical"/>
</ItemsPanelTemplate>
</Menu.ItemsPanel>
<MenuItem Header="Foo"/>
<MenuItem Header="Bar"/>
<MenuItem Header="Baz"/>
...
</Menu>
Note that this will not get rid of the vertical gradient effect in Vista/Win7 menus. If you want that, set Menu.Background property to whatever you want (could even be Transparent).

Resources