WPF menu item with image - wpf

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.

Related

How to get menu items command CanExecute to apply when using images and text

If I convert my menu code from:
<MenuItem Header="Remove Special Event"
Command="{Binding RemoveSpecialEventCommand, Mode=OneWay}" />
To:
<MenuItem Command="{Binding RemoveSpecialEventCommand, Mode=OneWay}">
<MenuItem.Header>
<StackPanel Orientation="Horizontal">
<Image Source="Images/RemoveSpecialEvent.png" Stretch="None" Margin="0,0,5,0"/>
<TextBlock>Remove Special Event</TextBlock>
</StackPanel>
</MenuItem.Header>
</MenuItem>
Now the Command CanExecute is not being applied to the menu item. They are all enabled.
Update
I don't particularly expect this to work.
It worked!
I can't reproduce your issue, and I'm going to take you at your word that it's absolutely disabled, but yet does not gray out the text. I suppose it might be a theme thing.
Here's one thing you can try: Instead of giving the Header property a visual tree fragment, try templating the plain string header content instead.
<MenuItem
Header="Remove Special Event"
Command="{Binding RemoveSpecialEventCommand, Mode=OneWay}"
>
<MenuItem.HeaderTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image
Source="Images/RemoveSpecialEvent.png"
Stretch="None"
Margin="0,0,5,0"
/>
<ContentControl
Content="{Binding}"
/>
</StackPanel>
</DataTemplate>
</MenuItem.HeaderTemplate>
</MenuItem>
I don't particularly expect this to work.

WPF button with drop down list and arrow

Can someone suggest the best way to have a button with an arrow and dropdown list like in visual studio toolbar button new item. As you can find in VS the mouse hover is highlighting both default button and arrow button and after selecting an item from list the default button is changing according your selection.
Here is a piece of code which is showing drop down menu, but not for full functionality described above:
<StackPanel Orientation="Horizontal">
<Border CornerRadius="0" BorderBrush="Black" BorderThickness="1">
<Button Name="CreateButton" Click="CreateButton_Click" Background="Transparent" BorderBrush="{x:Null}">
<Image Source="/OMS.Resources;component/Resources/Images/LibraryImages/add1.png" />
<Button.ContextMenu>
<ContextMenu HorizontalAlignment="Right">
<MenuItem Header=" doc" Click="CreateDocButton_Click">
<MenuItem.Icon>
<Image Source="/OMS.Resources;component/Resources/Images/LibraryImages/add_sheet.png" Width="24" Height="24" />
</MenuItem.Icon>
</MenuItem>
<MenuItem Header=" xls" Click="CreateXlsButton_Click">
<MenuItem.Icon>
<Image Source="/OMS.Resources;component/Resources/Images/LibraryImages/add_sheet.png" Width="24" Height="24" />
</MenuItem.Icon>
</MenuItem>
<MenuItem Header=" txt" Click="CreateTxtButton_Click">
<MenuItem.Icon>
<Image Source="/OMS.Resources;component/Resources/Images/LibraryImages/add_sheet.png" Width="24" Height="24" />
</MenuItem.Icon>
</MenuItem>
</ContextMenu>
</Button.ContextMenu>
</Button>
</Border>
<Border CornerRadius="0" BorderBrush="Black" BorderThickness="1">
<Button HorizontalAlignment="Left" VerticalAlignment="Stretch" Background="Transparent" BorderBrush="{x:Null}"
ContextMenuService.IsEnabled="False" Click="AddButtonContextMenu_Click">
<Image Source="/OMS.Resources;component/Resources/Images/LibraryImages/arrow_down.png" VerticalAlignment="Center" Width="9" />
</Button>
</Border>
</StackPanel>
The solution is to make use a menu item and decorate it.
XAML Code:
<MenuItem Click="AddPresetButton_Click" x:Name="AddPresetButton">
<MenuItem.Icon>
<Image Source="/MyApp.Application;component/Resources/add.png" Height="20"/>
</MenuItem.Icon>
<MenuItem.Header>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Add Preset"/>
<Image Source="/MyApp.Application;component/Resources/arrow_down_simple.png"
Height="10" Margin="2,0,0,0"/>
</StackPanel>
</MenuItem.Header>
<MenuItem.ContextMenu>
<ContextMenu>
<MenuItem Header="Add 1"/>
<MenuItem Header="Add 2"/>
<MenuItem Header="Add 3"/>
</ContextMenu>
</MenuItem.ContextMenu>
</MenuItem>
C# Code:
When the menu is pressed the context menu is opened.
private void AddPresetButton_Click(object sender, RoutedEventArgs e)
{
var addButton = sender as FrameworkElement;
if (addButton != null)
{
addButton.ContextMenu.IsOpen = true;
}
}
It looks like you have three problems to solve:
Styling / Layout
Highlight dropdown and button OnMouseOver
Change default button according to menu's last selection
Styling / Layout
Here are a couple of examples:
http://dvoituron.wordpress.com/2011/01/06/toolbar-dropdownbutton-in-wpf/
http://blogs.msdn.com/b/llobo/archive/2006/10/25/split-button-in-wpf.aspx
I am sure there are many other ways (e.g. using a plain button and ComboBox styled appropriately)
Highlighting dropdown and button OnMouseOver
Experiment with triggers; e.g:
WPF Mouseover Trigger Effect for Child Controls
WPF - How to change children's style on mouseover of parent
Change default button according to menu's last selection
Try the MVVM approach:
The button element will be bound to a property on your ViewModel. Each menu item will call an action (ICommand) in your ViewModel. This ViewModel will know which menu item was called, and update the button's property on the ViewModel. The button will automatically update using data binding.

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 remove the default border around a group of subitems?

I'm trying to find a way to get rid of the border around the container of the MenuItems of a menu, in Expression Blend 4.
Here is an image of what I mean, I'd like to make the big white border around Item2 and Item3 disappear.
http://i.stack.imgur.com/dhOwY.png
And here is the XAML of this menu:
<Menu Background="{DynamicResource MenuGradient}" Margin="8,3,0,0" Height="26" VerticalAlignment="Top" ItemTemplate="{DynamicResource GeneratedMenuItem}">
<MenuItem x:Name="itm1" Header="Item1" FontSize="16" Foreground="White" Template="{DynamicResource CustomMenuItemStyle}">
<MenuItem x:Name="itm2" Header="Item2" Style="{DynamicResource CustomSubMenuItemStyle}"/>
<MenuItem x:Name="itm3" Header="Item3" Style="{DynamicResource CustomSubMenuItemStyle}"/>
</MenuItem>
<MenuItem x:Name="itmOptions" Header="Options" Foreground="White" FontSize="16" Template="{DynamicResource CustomMenuItemStyle}"/>
</Menu>
I think you need to edit the popup part inside the template of the menu item.

Property Binding to Static Properties in WPF: Width binding doesn't work

Update: I've corrected the post, so the question is closed.
Expected result:
Menu width must be equal to the main window width.
Here is full code:
<Menu Name="menu1" DockPanel.Dock="Top">
<Menu.Width>
<Binding Path="MainWindow.Width"
Source="{x:Static Application.Current}"
UpdateSourceTrigger="PropertyChanged"/>
</Menu.Width>
<MenuItem Header="File">
<MenuItem Header="Open" />
<MenuItem Header="Close" />
</MenuItem>
</Menu>
The result:
Menu width is equal to content width
Doh,
Dmitry, Application.Current doesn't have a property Width...
Use Grid instead of DockPanel:
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<Menu Name="menu1" VerticalAlignment="Top">
<MenuItem Header="File">
<MenuItem Header="Open"/>
<MenuItem Header="Close"/>
</MenuItem>
</Menu>
</Grid>
</Page>
Don't overcomplicate things. And I really encourage you to read wonderful Dr. WPF articles: ItemsControl from A to Z
Cheers, Anvaka

Resources