C# WPF MenuItem custom template
27,850
Solution 1
You could just use TemplateBinding on the Header property in the same way you've used it on the Background
property:
<ControlTemplate TargetType="{x:Type MenuItem}">
<Grid Background="{TemplateBinding Background}">
<MenuItem Header="{TemplateBinding Header}" />
</Grid>
</ControlTemplate>
Solution 2
You can make an individual style for every MenuItem using a StyleSelector.
public class MyStyleSelector : StyleSelector
{
public override Style SelectStyle(object item, DependencyObject container)
{
var itemsControl = ItemsControl.ItemsControlFromItemContainer(container);
var index = itemsControl.ItemContainerGenerator.IndexFromContainer(container);
if (index == 0)
return (Style)itemsControl.FindResource("FirstItemStyle");
if (index == 1)
return (Style)itemsControl.FindResource("SecondItemStyle");
return base.SelectStyle(item, container);
}
}
And in your XAML
<Window x:Class="Menus.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Menus"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<local:MyStyleSelector x:Key="MyStyleSelector" />
<Style x:Key="FirstItemStyle" TargetType="MenuItem">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" Value="#0a99f3" />
<Setter Property="Foreground" Value="White"/>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="SecondItemStyle" TargetType="MenuItem">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" Value="Red" />
<Setter Property="Foreground" Value="White"/>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<Menu ItemContainerStyleSelector="{StaticResource MyStyleSelector}">
<MenuItem Header="Menu 1" />
<MenuItem Header="Menu 2" />
<MenuItem Header="Menu 3" />
</Menu>
</Grid>
See StyleSelector here: StyleSelector
Comments
-
sparcopt almost 4 years
In Main.xaml I have these two menu items:
- The first with the header = Disconnect from current
- The second with the header = Quit
- ...
- More menu items with different header texts...
In order to edit some colors of the first item I created a custom template in App.xaml:
<!--Template for Menu Items--> <Style x:Key="MenuItemBaseStyle" TargetType="MenuItem"> <Style.Triggers> <Trigger Property="IsMouseOver" Value="true"> <Setter Property="Background" Value="#0a99f3" /> <Setter Property="Foreground" Value="White"/> </Trigger> </Style.Triggers> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type MenuItem}"> <Grid Background="{TemplateBinding Background}"> <MenuItem Header="DISCONNECT FROM CURRENT" /> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style>
And in Main.xaml:
<MenuItem Header="CONNECTION"> <MenuItem Style="{StaticResource MenuItemBaseStyle}" Header="DISCONNECT FROM CURRENT" /> <MenuItem Header="QUIT"/> </MenuItem>
Now I want to do the same for the second menu item. The problem is with the different header. If I delete the header from the template, it won't show any header even if the header text is still present in Main.xaml
How can I use this template for many menu items where the only thing that changes is the header text?
-
AgentFire over 8 yearsCodebehind is so undesirable.
-
Ketobomb over 8 yearsWhere do you see a code behind? MyStyleSelector is a separate class.
-
nam almost 3 yearsI have a similar post here if you have any suggestions/comments etc.