I am using the WPF extended library WatermarkedComboBox and when I hover over a ComboBoxItem I want the background to change to a light grey and not the defaul blue.
<!-- Combo Box -->
<xctk:WatermarkComboBox Style="{StaticResource MonthComboBoxDropDown}" ItemsSource="{Binding ListOfMonths}" SelectedItem="{Binding SelectedMonth, ValidatesOnDataErrors=True}" Margin="0,0,20,0">
<xctk:WatermarkComboBox.Watermark>
<TextBlock Text="Month" Foreground="{StaticResource OffsetWhiteBrush}"/>
</xctk:WatermarkComboBox.Watermark>
<xctk:WatermarkComboBox.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Pink" />
</xctk:WatermarkComboBox.Resources>
<xctk:WatermarkComboBox.ItemContainerStyle>
<Style TargetType="{x:Type ComboBoxItem}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Pink" />
<Setter Property="Foreground" Value="Yellow" />
<Setter Property="BorderThickness" Value="5" />
</Trigger>
</Style.Triggers>
</Style>
</xctk:WatermarkComboBox.ItemContainerStyle>
</xctk:WatermarkComboBox>
<!-- Combo box styling -->
<Style x:Key="MonthComboBoxDropDown" TargetType="{x:Type ComboBox}" BasedOn="{StaticResource TextBoxErrorStyle}">
<Setter Property="Foreground" Value="{StaticResource WhiteColorBrush}" />
<Setter Property="FontSize" Value="{StaticResource FontSize20}" />
<Setter Property="FontFamily" Value="{StaticResource LatoRegular}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBox}">
<Grid>
<ToggleButton Grid.Column="2" Focusable="false" IsChecked="{Binding Path=IsDropDownOpen,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}" >
<ToggleButton.Template>
<ControlTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Border Name="Border" Grid.ColumnSpan="2" Background="{StaticResource DarkGreyBrush}" BorderThickness="0" />
<Path x:Name="Arrow" Grid.Column="1" Fill="{StaticResource WhiteColorBrush}" HorizontalAlignment="Center" VerticalAlignment="Center" Data="M 0 0 L 4 4 L 8 0 Z"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="ToggleButton.IsChecked" Value="true">
<Setter TargetName="Border" Property="Background" Value="{StaticResource LightGreyBrush}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</ToggleButton.Template>
</ToggleButton>
<ContentPresenter Name="ContentSite" IsHitTestVisible="False" Content="{TemplateBinding SelectionBoxItem}" ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}" ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}" Margin="3" />
<TextBox x:Name="PART_EditableTextBox" Visibility="Hidden" MinWidth="120" />
<Popup Name="Popup" Placement="Bottom" IsOpen="{TemplateBinding IsDropDownOpen}" AllowsTransparency="True" Focusable="False" PopupAnimation="Slide">
<Grid Name="DropDown" SnapsToDevicePixels="True" MinWidth="{TemplateBinding ActualWidth}" MaxHeight="{TemplateBinding MaxDropDownHeight}">
<Border x:Name="DropDownBorder" Background="{StaticResource DarkGreyBrush}" />
<ScrollViewer SnapsToDevicePixels="True" Foreground="{StaticResource WhiteColorBrush}" FontFamily="{StaticResource LatoRegular}" FontSize="{StaticResource FontSize20}" VerticalAlignment="Center">
<StackPanel IsItemsHost="True" />
</ScrollViewer>
</Grid>
</Popup>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
When I hover over the an item in the combo box it looks like this
I have managed to make the foreground and border change but how can I also make the background change?
Add to your ComboBox style to change the HighlightBrush to gray
<Style x:Key="MonthComboBoxDropDown" TargetType="{x:Type ComboBox}" BasedOn=" {StaticResource TextBoxErrorStyle}">
<Style.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Gray"/>
<SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}" Color="DarkGray"/>
</Style.Resources>
<Setter Property="Foreground" Value="{StaticResource WhiteColorBrush}" />
<Setter Property="FontSize" Value="{StaticResource FontSize20}" />
<Setter Property="FontFamily" Value="{StaticResource LatoRegular}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBox}">
<Grid>
<ToggleButton Grid.Column="2" Focusable="false" IsChecked="{Binding Path=IsDropDownOpen,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}" >
<ToggleButton.Template>
<ControlTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Border Name="Border" Grid.ColumnSpan="2" Background="{StaticResource DarkGreyBrush}" BorderThickness="0" />
<Path x:Name="Arrow" Grid.Column="1" Fill="{StaticResource WhiteColorBrush}" HorizontalAlignment="Center" VerticalAlignment="Center" Data="M 0 0 L 4 4 L 8 0 Z"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="ToggleButton.IsChecked" Value="true">
<Setter TargetName="Border" Property="Background" Value="{StaticResource LightGreyBrush}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</ToggleButton.Template>
</ToggleButton>
<ContentPresenter Name="ContentSite" IsHitTestVisible="False" Content="{TemplateBinding SelectionBoxItem}" ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}" ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}" Margin="3" />
<TextBox x:Name="PART_EditableTextBox" Visibility="Hidden" MinWidth="120" />
<Popup Name="Popup" Placement="Bottom" IsOpen="{TemplateBinding IsDropDownOpen}" AllowsTransparency="True" Focusable="False" PopupAnimation="Slide">
<Grid Name="DropDown" SnapsToDevicePixels="True" MinWidth="{TemplateBinding ActualWidth}" MaxHeight="{TemplateBinding MaxDropDownHeight}">
<Border x:Name="DropDownBorder" Background="{StaticResource DarkGreyBrush}" />
<ScrollViewer SnapsToDevicePixels="True" Foreground="{StaticResource WhiteColorBrush}" FontFamily="{StaticResource LatoRegular}" FontSize="{StaticResource FontSize20}" VerticalAlignment="Center">
<StackPanel IsItemsHost="True" />
</ScrollViewer>
</Grid>
</Popup>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ComboBox" TargetType="{x:Type ComboBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBoxItem}">
<Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="True">
<ContentPresenter ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="TextElement.Foreground" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" TargetName="Bd" Value="{StaticResource LightGreyBrush}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
To override the style I had to override the ComboBoxItem ControlTemplate.
We have been tasked with designing an enterprise application in WPF that will replace a battleship grey Winforms application with a modern look and feel.
We like the look and feel that Microsoft web applications currently possess:
We could create these menus in WPF in the usual way:
<DockPanel>
<Menu DockPanel.Dock="Top">
<MenuItem Header="_File">
<MenuItem Header="_New" />
<MenuItem Header="_Open" />
<MenuItem Header="_Save" />
<Separator />
<MenuItem Header="_Exit" />
</MenuItem>
</Menu>
<TextBox AcceptsReturn="True" />
</DockPanel>
But we'd get something that looks like a Winforms menu.
I've seen some rather impressive styling efforts like this one, but they all seem to have the same familiar Winforms shape. I've also seen menus in libraries like MahApps Metro, but these strike us as too spartan.
Is the WPF Menu control flexible enough to be styled as shown in the picture above, or should we go another route like building a custom menu control from Stack Panels and Lists? What are the tradeoffs?
Bonus points (i.e. a bounty) will be awarded for xaml/code that does exactly this.
An example of this menu style in action:
https://www.visualstudio.com/
WPF was really designed with the possibility to change the look and behavior of every out-of-the-box mechanisms / controls (buttons, menus, treeview, etc.).
So, in general, it's better to do this rather than to rewrite everything. For example, if you redesign your custom menu, you'll have to think about keyboard, UI automation, etc...
So, I gave a shot at your example and tried to build a minimum working sample - pure XAML - that mimics VS online menu (I've also added the hover background color change that's not by default in WPF's menu).
Here is the result and, as you see, it looks very similar:
Here is the XAML. I've chosen to use a custom control template per each MenuItem. I think it's quite practical when you need to really customize every item.
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="550" Width="525">
<Window.Resources>
<BooleanToVisibilityConverter x:Key="btv" />
<!-- style a top level menu item -->
<ControlTemplate x:Key="VsMenuTop" TargetType="MenuItem">
<StackPanel TextBlock.FontSize="15px" Height="40">
<!-- label, icons, etc. -->
<Label Content="{TemplateBinding Header}" Margin="5" Foreground="White" />
<!-- sub items -->
<Popup IsOpen="{TemplateBinding IsSubmenuOpen}" AllowsTransparency="True" Focusable="False">
<Border BorderThickness="1" Background="White" BorderBrush="#E0E0E0">
<StackPanel IsItemsHost="True" />
</Border>
</Popup>
<StackPanel.Style>
<Style TargetType="StackPanel">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#106EBE" />
</Trigger>
</Style.Triggers>
</Style>
</StackPanel.Style>
</StackPanel>
</ControlTemplate>
<!-- style a non-top level menu item -->
<ControlTemplate x:Key="VsMenuSub" TargetType="MenuItem">
<DockPanel TextBlock.FontSize="15px" x:Name="panel">
<!-- label, icons, etc. -->
<Image Source="{Binding Icon, RelativeSource={RelativeSource TemplatedParent}}" Width="20" Margin="5,0" />
<Label Content="{TemplateBinding Header}" Foreground="Black" Margin="0,5,5,5" />
<!-- draw the right arrow only if this menu item has sub items -->
<Image Source="icon_right.png" Visibility="{Binding HasItems, Converter={StaticResource btv}, RelativeSource={RelativeSource TemplatedParent}}" />
<!-- sub items -->
<Popup IsOpen="{TemplateBinding IsSubmenuOpen}" AllowsTransparency="True" Focusable="False" Placement="Right" >
<Border BorderThickness="1" Background="White" BorderBrush="#E0E0E0">
<StackPanel IsItemsHost="True" />
</Border>
</Popup>
</DockPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsHighlighted" Value="True">
<Setter Property="Background" TargetName="panel" Value="#EFF6FC" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<!-- style the separator -->
<ControlTemplate x:Key="VsMenuSep" TargetType="Separator">
<Border Height="1" Background="#E0E0E0" />
</ControlTemplate>
<!-- style the VSOnline -->
<ControlTemplate x:Key="VsOnline" TargetType="MenuItem">
<StackPanel TextBlock.FontSize="15px" Height="40" Orientation="Horizontal" Background="#005A9E">
<Label Content="{TemplateBinding Header}" Margin="5" Foreground="White" />
<Image Source="icon_down.png" Height="20" Margin="0,0,5,0" />
<!-- sub items -->
<Popup IsOpen="{TemplateBinding IsSubmenuOpen}" AllowsTransparency="True" Focusable="False">
<Border BorderThickness="1" Background="White" BorderBrush="#E0E0E0">
<StackPanel IsItemsHost="True" />
</Border>
</Popup>
</StackPanel>
</ControlTemplate>
<!-- some base stuff -->
<Style TargetType="Menu">
<Setter Property="Background" Value="#0078D7" />
<Setter Property="Height" Value="40px" />
</Style>
</Window.Resources>
<!-- the real app and real menu -->
<StackPanel>
<Menu IsMainMenu="True">
<MenuItem Header="_VSOnline" Template="{StaticResource VsOnline}" >
<MenuItem Header="_Whatever" Template="{StaticResource VsMenuSub}" />
</MenuItem>
<MenuItem Header="_Dashboards" Template="{StaticResource VsMenuTop}">
<MenuItem Header="_Overview" Template="{StaticResource VsMenuSub}" />
</MenuItem>
<MenuItem Header="_Code" Template="{StaticResource VsMenuTop}">
<MenuItem Header="_Files" Template="{StaticResource VsMenuSub}" />
<MenuItem Header="_Commits" Template="{StaticResource VsMenuSub}" />
<MenuItem Header="_Pushes" Template="{StaticResource VsMenuSub}" />
</MenuItem>
<MenuItem Header="_Work" Template="{StaticResource VsMenuTop}">
<MenuItem Header="_Backlogs" Template="{StaticResource VsMenuSub}" Icon="icon_backlogs.png" />
<MenuItem Header="_Queries" Template="{StaticResource VsMenuSub}" Icon="icon_queries.png" />
<Separator Template="{StaticResource VsMenuSep}" />
<MenuItem Header="_New Work Item" Template="{StaticResource VsMenuSub}">
<MenuItem Header="_Epic" Template="{StaticResource VsMenuSub}" Icon="icon_epic.png" />
<MenuItem Header="_Feature" Template="{StaticResource VsMenuSub}" Icon="icon_feature.png" />
<MenuItem Header="_Issue" Template="{StaticResource VsMenuSub}" Icon="icon_issue.png" />
<MenuItem Header="_Task" Template="{StaticResource VsMenuSub}" Icon="icon_task.png" />
<MenuItem Header="_Test Case" Template="{StaticResource VsMenuSub}" Icon="icon_testcase.png" />
<MenuItem Header="_User Story" Template="{StaticResource VsMenuSub}" Icon="icon_userstory.png" />
</MenuItem>
<MenuItem Header="_Bug" Template="{StaticResource VsMenuSub}" Icon="icon_bug.png" />
</MenuItem>
</Menu>
</StackPanel>
</Window>
The project is available here on github.
You are probably looking for some Wpf Theme to start with.
Such as
http://brianlagunas.com/free-metro-light-and-dark-themes-for-wpf-and-silverlight-microsoft-controls/
or have a look at that SO answer:
Any free WPF themes?
Then you probably would want to customize it even more with look and feel you are looking for.
You could use something like: http://materialdesigninxaml.net
This is the default menu, but white, you can change the background color, text font, height, and everything else you want just by editing this style.
Here your MainWindow.xaml
<Menu IsMainMenu="True" HorizontalContentAlignment="Left" Background="Transparent" >
<MenuItem Header="File" HorizontalContentAlignment="Left" >
<MenuItem Header="Menu Item 01" Command="{Binding MenuCommand}" CommandParameter="Param01" >
<MenuItem.Icon>
<Image Source="Images/settings.png" Height="20"/>
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="Menu Item 02" Command="{Binding MenuCommand}" CommandParameter="Param02" >
<MenuItem.Icon>
<Image Source="Images/settings.png" Height="20"/>
</MenuItem.Icon>
</MenuItem>
<Separator />
<MenuItem Header="LogOff" Command="{Binding MenuCommand}" CommandParameter="LogOff" >
<MenuItem.Icon>
<Image Source="Images/logoff.png" Height="20"/>
</MenuItem.Icon>
</MenuItem>
</MenuItem>
</Menu>
style in app.xaml file
<!-- Menu Begin -->
<!-- Menu -->
<Style TargetType="{x:Type Menu}">
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.MenuBarBrushKey}}"/>
<Setter Property="FontFamily" Value="{DynamicResource {x:Static SystemFonts.MenuFontFamilyKey}}"/>
<Setter Property="FontSize" Value="{DynamicResource {x:Static SystemFonts.MenuFontSizeKey}}"/>
<Setter Property="FontStyle" Value="{DynamicResource {x:Static SystemFonts.MenuFontStyleKey}}"/>
<Setter Property="FontWeight" Value="{DynamicResource {x:Static SystemFonts.MenuFontWeightKey}}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.MenuTextBrushKey}}"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Menu}">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- Level 0 -->
<ControlTemplate x:Key="{x:Static MenuItem.TopLevelItemTemplateKey}" TargetType="{x:Type MenuItem}">
<Border x:Name="templateRoot" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
<Grid x:Name="Grid" VerticalAlignment="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<ContentPresenter x:Name="Icon" Content="{TemplateBinding Icon}" ContentSource="Icon" HorizontalAlignment="Center" Height="16" Margin="3" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center" Width="16" Visibility="Collapsed"/>
<Path x:Name="GlyphPanel" Data="F1M10,1.2L4.7,9.1 4.5,9.1 0,5.2 1.3,3.5 4.3,6.1 8.3,0 10,1.2z" Fill="{TemplateBinding Foreground}" FlowDirection="LeftToRight" Margin="3" Visibility="Collapsed" VerticalAlignment="Center"/>
<ContentPresenter x:Name="ContentPresenter" ContentTemplate="{TemplateBinding HeaderTemplate}" Content="{TemplateBinding Header}" Grid.Column="1" ContentStringFormat="{TemplateBinding HeaderStringFormat}" ContentSource="Header" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
<Popup x:Name="PART_Popup" AllowsTransparency="True" Focusable="False" IsOpen="{Binding IsSubmenuOpen, RelativeSource={RelativeSource TemplatedParent}}" PopupAnimation="{DynamicResource {x:Static SystemParameters.MenuPopupAnimationKey}}" Placement="Bottom" >
<Border x:Name="SubMenuBorder" BorderBrush="#FF999999" BorderThickness="1" Background="White" Padding="2">
<ScrollViewer x:Name="SubMenuScrollViewer" Style="{DynamicResource {ComponentResourceKey ResourceId=MenuScrollViewer, TypeInTargetAssembly={x:Type FrameworkElement}}}">
<Grid x:Name="Grid1" RenderOptions.ClearTypeHint="Enabled">
<Canvas x:Name="Canvas" HorizontalAlignment="Left" Height="0" VerticalAlignment="Top" Width="0">
<Rectangle x:Name="OpaqueRect" Fill="{Binding Background, ElementName=SubMenuBorder}" Height="{Binding ActualHeight, ElementName=SubMenuBorder}" Width="{Binding ActualWidth, ElementName=SubMenuBorder}"/>
</Canvas>
<Rectangle x:Name="Rectangle" Fill="Transparent" HorizontalAlignment="Left" Margin="29,2,0,2" Width="1"/>
<ItemsPresenter x:Name="ItemsPresenter" KeyboardNavigation.DirectionalNavigation="Cycle" Grid.IsSharedSizeScope="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" KeyboardNavigation.TabNavigation="Cycle"/>
</Grid>
</ScrollViewer>
</Border>
</Popup>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSuspendingPopupAnimation" Value="True">
<Setter Property="PopupAnimation" TargetName="PART_Popup" Value="None"/>
</Trigger>
<Trigger Property="Icon" Value="{x:Null}">
<Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Visibility" TargetName="GlyphPanel" Value="Visible"/>
<Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
</Trigger>
<Trigger Property="IsHighlighted" Value="True">
<Setter Property="Background" TargetName="templateRoot" Value="#3D26A0DA"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="#FF26A0DA"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="TextElement.Foreground" TargetName="templateRoot" Value="#FF707070"/>
<Setter Property="Fill" TargetName="GlyphPanel" Value="#FF707070"/>
</Trigger>
<Trigger Property="CanContentScroll" SourceName="SubMenuScrollViewer" Value="False">
<Setter Property="Canvas.Top" TargetName="OpaqueRect" Value="{Binding VerticalOffset, ElementName=SubMenuScrollViewer}"/>
<Setter Property="Canvas.Left" TargetName="OpaqueRect" Value="{Binding HorizontalOffset, ElementName=SubMenuScrollViewer}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<!-- Level 0 -->
<ControlTemplate x:Key="{x:Static MenuItem.TopLevelHeaderTemplateKey}" TargetType="{x:Type MenuItem}">
<Border x:Name="templateRoot" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
<Grid x:Name="Grid" VerticalAlignment="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<ContentPresenter x:Name="Icon" Content="{TemplateBinding Icon}" ContentSource="Icon" HorizontalAlignment="Center" Height="16" Margin="3" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center" Width="16" Visibility="Collapsed"/>
<Path x:Name="GlyphPanel" Data="F1M10,1.2L4.7,9.1 4.5,9.1 0,5.2 1.3,3.5 4.3,6.1 8.3,0 10,1.2z" Fill="{TemplateBinding Foreground}" FlowDirection="LeftToRight" Margin="3" Visibility="Collapsed" VerticalAlignment="Center"/>
<ContentPresenter x:Name="ContentPresenter" ContentTemplate="{TemplateBinding HeaderTemplate}" Content="{TemplateBinding Header}" Grid.Column="1" ContentStringFormat="{TemplateBinding HeaderStringFormat}" ContentSource="Header" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
<Popup x:Name="PART_Popup" AllowsTransparency="True" Focusable="False" IsOpen="{Binding IsSubmenuOpen, RelativeSource={RelativeSource TemplatedParent}}" PopupAnimation="{DynamicResource {x:Static SystemParameters.MenuPopupAnimationKey}}" Placement="Bottom" >
<Border x:Name="SubMenuBorder" BorderBrush="#FF999999" BorderThickness="1" Background="{DynamicResource {x:Static SystemColors.MenuColorKey}}" Padding="2">
<ScrollViewer x:Name="SubMenuScrollViewer" Style="{DynamicResource {ComponentResourceKey ResourceId=MenuScrollViewer, TypeInTargetAssembly={x:Type FrameworkElement}}}">
<Grid x:Name="Grid1" RenderOptions.ClearTypeHint="Enabled">
<Canvas x:Name="Canvas" HorizontalAlignment="Left" Height="0" VerticalAlignment="Top" Width="0">
<Rectangle x:Name="OpaqueRect" Fill="{Binding Background, ElementName=SubMenuBorder}" Height="{Binding ActualHeight, ElementName=SubMenuBorder}" Width="{Binding ActualWidth, ElementName=SubMenuBorder}"/>
</Canvas>
<Rectangle x:Name="Rectangle" Fill="Transparent" HorizontalAlignment="Left" Margin="29,2,0,2" Width="1"/>
<ItemsPresenter x:Name="ItemsPresenter" KeyboardNavigation.DirectionalNavigation="Cycle" Grid.IsSharedSizeScope="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" KeyboardNavigation.TabNavigation="Cycle"/>
</Grid>
</ScrollViewer>
</Border>
</Popup>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSuspendingPopupAnimation" Value="True">
<Setter Property="PopupAnimation" TargetName="PART_Popup" Value="None"/>
</Trigger>
<Trigger Property="Icon" Value="{x:Null}">
<Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Visibility" TargetName="GlyphPanel" Value="Visible"/>
<Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
</Trigger>
<Trigger Property="IsHighlighted" Value="True">
<Setter Property="Background" TargetName="templateRoot" Value="#3D26A0DA"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="#FF26A0DA"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="TextElement.Foreground" TargetName="templateRoot" Value="#FF707070"/>
<Setter Property="Fill" TargetName="GlyphPanel" Value="#FF707070"/>
</Trigger>
<Trigger Property="CanContentScroll" SourceName="SubMenuScrollViewer" Value="False">
<Setter Property="Canvas.Top" TargetName="OpaqueRect" Value="{Binding VerticalOffset, ElementName=SubMenuScrollViewer}"/>
<Setter Property="Canvas.Left" TargetName="OpaqueRect" Value="{Binding HorizontalOffset, ElementName=SubMenuScrollViewer}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<!-- Level 1,2,3,4,... -->
<ControlTemplate x:Key="{x:Static MenuItem.SubmenuHeaderTemplateKey}" TargetType="{x:Type MenuItem}">
<Border x:Name="templateRoot" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
<Grid Margin="-1">
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="22" SharedSizeGroup="MenuItemIconColumnGroup" Width="Auto"/>
<ColumnDefinition Width="13"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="30"/>
<ColumnDefinition SharedSizeGroup="MenuItemIGTColumnGroup" Width="Auto"/>
<ColumnDefinition Width="20"/>
</Grid.ColumnDefinitions>
<ContentPresenter x:Name="Icon" Content="{TemplateBinding Icon}" ContentSource="Icon" HorizontalAlignment="Center" Height="16" Margin="3" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center" Width="16"/>
<Border x:Name="GlyphPanel" BorderBrush="#FF26A0DA" BorderThickness="1" Background="#3D26A0DA" Height="22" Margin="-1,0,0,0" Visibility="Hidden" VerticalAlignment="Center" Width="22" >
<Path x:Name="Glyph" Data="{DynamicResource ลง}" Fill="#FF212121" FlowDirection="LeftToRight" Height="11" Width="9"/>
</Border>
<ContentPresenter ContentTemplate="{TemplateBinding HeaderTemplate}" Content="{TemplateBinding Header}" Grid.Column="2" ContentStringFormat="{TemplateBinding HeaderStringFormat}" ContentSource="Header" HorizontalAlignment="Left" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center"/>
<TextBlock Grid.Column="4" Margin="{TemplateBinding Padding}" Opacity="0.7" Text="{TemplateBinding InputGestureText}" VerticalAlignment="Center"/>
<Path x:Name="RightArrow" Grid.Column="5" Data="M0,0L4,3.5 0,7z" Fill="#FF212121" HorizontalAlignment="Left" Margin="10,0,0,0" VerticalAlignment="Center"/>
<Popup x:Name="PART_Popup" AllowsTransparency="True" Focusable="False" HorizontalOffset="-2" IsOpen="{Binding IsSubmenuOpen, RelativeSource={RelativeSource TemplatedParent}}" PopupAnimation="{DynamicResource {x:Static SystemParameters.MenuPopupAnimationKey}}" Placement="Right" VerticalOffset="-3">
<Border x:Name="SubMenuBorder" BorderBrush="#FF999999" BorderThickness="1" Background="{DynamicResource {x:Static SystemColors.MenuColorKey}}" Padding="2">
<ScrollViewer x:Name="SubMenuScrollViewer" Style="{DynamicResource {ComponentResourceKey ResourceId=MenuScrollViewer, TypeInTargetAssembly={x:Type FrameworkElement}}}">
<Grid RenderOptions.ClearTypeHint="Enabled">
<Canvas HorizontalAlignment="Left" Height="0" VerticalAlignment="Top" Width="0">
<!--Fill="{Binding Background, ElementName=SubMenuBorder}" White #FFF0F0F0-->
<Rectangle x:Name="OpaqueRect" Fill="{Binding Background, ElementName=SubMenuBorder}" Height="{Binding ActualHeight, ElementName=SubMenuBorder}" Width="{Binding ActualWidth, ElementName=SubMenuBorder}"/>
</Canvas>
<Rectangle Fill="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}" HorizontalAlignment="Left" Margin="29,2,0,2" Width="1"/>
<ItemsPresenter x:Name="ItemsPresenter" KeyboardNavigation.DirectionalNavigation="Cycle" Grid.IsSharedSizeScope="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" KeyboardNavigation.TabNavigation="Cycle"/>
</Grid>
</ScrollViewer>
</Border>
</Popup>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSuspendingPopupAnimation" Value="True">
<Setter Property="PopupAnimation" TargetName="PART_Popup" Value="None"/>
</Trigger>
<Trigger Property="Icon" Value="{x:Null}">
<Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Visibility" TargetName="GlyphPanel" Value="Visible"/>
<Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
</Trigger>
<Trigger Property="IsHighlighted" Value="True">
<Setter Property="Background" TargetName="templateRoot" Value="Transparent"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="#FF26A0DA"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="TextElement.Foreground" TargetName="templateRoot" Value="#FF707070"/>
<Setter Property="Fill" TargetName="Glyph" Value="#FF707070"/>
<Setter Property="Fill" TargetName="RightArrow" Value="#FF707070"/>
</Trigger>
<Trigger Property="CanContentScroll" SourceName="SubMenuScrollViewer" Value="False">
<Setter Property="Canvas.Top" TargetName="OpaqueRect" Value="{Binding VerticalOffset, ElementName=SubMenuScrollViewer}"/>
<Setter Property="Canvas.Left" TargetName="OpaqueRect" Value="{Binding HorizontalOffset, ElementName=SubMenuScrollViewer}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<!-- Level 1,2,3,4,... -->
<ControlTemplate x:Key="{x:Static MenuItem.SubmenuItemTemplateKey}" TargetType="{x:Type MenuItem}">
<Border x:Name="templateRoot" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
<Grid Margin="-1">
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="22" SharedSizeGroup="MenuItemIconColumnGroup" Width="Auto"/>
<ColumnDefinition Width="13"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="30"/>
<ColumnDefinition SharedSizeGroup="MenuItemIGTColumnGroup" Width="Auto"/>
<ColumnDefinition Width="20"/>
</Grid.ColumnDefinitions>
<ContentPresenter x:Name="Icon" Content="{TemplateBinding Icon}" ContentSource="Icon" HorizontalAlignment="Center" Height="16" Margin="3" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center" Width="16"/>
<Border x:Name="GlyphPanel" BorderBrush="#FF26A0DA" BorderThickness="1" Background="#3D26A0DA" ClipToBounds="False" HorizontalAlignment="Center" Height="22" Margin="-1,0,0,0" Visibility="Hidden" VerticalAlignment="Center" Width="22">
<Path x:Name="Glyph" Data="F1M10,1.2L4.7,9.1 4.5,9.1 0,5.2 1.3,3.5 4.3,6.1 8.3,0 10,1.2z" Fill="#FF212121" FlowDirection="LeftToRight" Height="11" Width="10"/>
</Border>
<ContentPresenter x:Name="menuHeaderContainer" ContentTemplate="{TemplateBinding HeaderTemplate}" Content="{TemplateBinding Header}" Grid.Column="2" ContentStringFormat="{TemplateBinding HeaderStringFormat}" ContentSource="Header" HorizontalAlignment="Left" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center"/>
<TextBlock x:Name="menuGestureText" Grid.Column="4" Margin="{TemplateBinding Padding}" Opacity="0.7" Text="{TemplateBinding InputGestureText}" VerticalAlignment="Center"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="Icon" Value="{x:Null}">
<Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Visibility" TargetName="GlyphPanel" Value="Visible"/>
<Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
</Trigger>
<Trigger Property="IsHighlighted" Value="True">
<Setter Property="Background" TargetName="templateRoot" Value="#3D26A0DA"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="#FF26A0DA"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="TextElement.Foreground" TargetName="templateRoot" Value="#FF707070"/>
<Setter Property="Fill" TargetName="Glyph" Value="#FF707070"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsHighlighted" Value="True"/>
<Condition Property="IsEnabled" Value="False"/>
</MultiTrigger.Conditions>
<Setter Property="Background" TargetName="templateRoot" Value="#0A000000"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="#21000000"/>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<!-- Menu End -->
I would create the menu with XAML
XAML of Page something like this:
<Window.Resources>
<Style TargetType="TextBlock">
<Setter Property="Margin" Value="10" />
<Setter Property="FontSize" Value="15" />
<Setter Property="Foreground" Value="White" />
</Style>
</Window.Resources>
<Grid x:Name="Content">
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" Background="CornflowerBlue">
<TextBlock Text="Menu1" MouseLeftButtonDown="OnMouseLeftButtonDown" />
<TextBlock Text="Menu2" MouseLeftButtonDown="OnMouseLeftButtonDown" />
<TextBlock Text="Menu3" MouseLeftButtonDown="OnMouseLeftButtonDown" />
</StackPanel>
<Border Grid.Row="1" Background="Bisque"></Border>
</Grid>
</Grid>
And in Code:
private void OnMouseLeftButtonDown(object sender, MouseEventArgs e) {
var textBlock = sender as TextBlock;
if (textBlock == null) return;
var relativePoint = VisualTreeHelper.GetOffset(textBlock);//textBlock.TransformToAncestor(Content).Transform(new Point(0, 0));
//Almost invisible Background - If the user clicks it the menu is hidden
var back = new Border{Background = new SolidColorBrush(Color.FromArgb(1,255,255,255))};
back.MouseLeftButtonDown += (o, args) => {
Content.Children.Remove(back.Tag as UIElement);
Content.Children.Remove(back);
};
Content.Children.Add(back);
//Build menu
var menu = new Border{Background = new SolidColorBrush(Colors.White), Width = 200, Height = 500, BorderBrush = new SolidColorBrush(Colors.Gray), BorderThickness = new Thickness(1), HorizontalAlignment = HorizontalAlignment.Left, VerticalAlignment = VerticalAlignment.Top};
back.Tag = menu;
menu.RenderTransform = new TranslateTransform(relativePoint.X, relativePoint.Y + textBlock.ActualHeight + 5);
//Do some more styling
//Fill Menu here according to the tag of the TextBlock (switch(textBlock.Tag){...} or use a predefined view
Content.Children.Add(menu);
//Hide the Menu on click - TODO Implement logic to hide menu if a MenuItem was clicked...
menu.MouseLeftButtonDown += (o, args) => {
Content.Children.Remove(back.Tag as UIElement);
Content.Children.Remove(back);
};
}
OK, this is a very basic example and needs a lot of improvement but I think you can work on it...
I have set a style for my MenuItems which looks like the following
App.xaml
<Style x:Key="MenuItemHover" TargetType="MenuItem">
<Setter Property="Width" Value="50"></Setter>
<Setter Property="FontFamily" Value="Calibri"></Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="MenuItem">
<Border x:Name="border"
Background="#282828"
>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="border" Property="Background" Value="Gray"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
MainWindow.xaml
<Menu x:Name="Menu_Dropdown" Width="150" Background="#282828" Foreground="White" HorizontalAlignment="Left" Grid.Column="0" Grid.ColumnSpan="2" Height="25" VerticalAlignment="Top">
<MenuItem x:Name="MenuItem_User" Height="25" Header="Nutzer" Style="{DynamicResource MenuItemHover}"></MenuItem>
<MenuItem x:Name="MenuItem_Kasse" Header="Kasse" Style="{DynamicResource MenuItemHover}"></MenuItem>
<MenuItem x:Name="MenuItem_Design" Header="Design" Style="{DynamicResource MenuItemHover}"></MenuItem>
</Menu>
When I use my style "MenuItemHover" it let the text disappear. The rest is working fine. (so the hover effect itself - it's changing the color when I move my mouse over)
Without using the style the header is getting showed normally.
There are a couple of things to make this code better, let's take a look one by one.
First of all, when you override the template, you need to know that you're not extending, but rather rewrite it; therefore you need to add the "obvious" parts as well, not just the new ones. As Anton says, you need at least one control to display the text itself. See his answer for an example.
Secondly, if you want to use the same style for every MenuItem, it is better to define the Style without a key. That way that's going to be the default style for MenuItems and it will be applied to all of them unless you say explicitly otherwise. (You don't need to add Style="{DynamicResource MenuItemHover}" to every MenuItem tag. Keep in mind that there is a hierarchy of applying styles. For example if you set the font size to 15 in the style, but then you add FontSize="50" to one of the MenuItems explicitly that MenuItem will use the value 50. See more about it here)
Last, but not least I think a good way to do this kind of changes in the styles is opening up Blend, select the control, then create a copy of the original template:
and customize that copy. (As you can see below this is just the ControlTemplate, you need to put this into a style) This way you can be sure you won't lose anything that is there originally.
Example (MenuItem ControlTemplate):
<ControlTemplate x:Key="MenuItemControlTemplate1" TargetType="{x:Type MenuItem}">
<Border x:Name="templateRoot" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
<Grid VerticalAlignment="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<ContentPresenter x:Name="Icon" Content="{TemplateBinding Icon}" ContentSource="Icon" HorizontalAlignment="Center" Height="16" Margin="3" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center" Width="16"/>
<Path x:Name="GlyphPanel" Data="F1M10,1.2L4.7,9.1 4.5,9.1 0,5.2 1.3,3.5 4.3,6.1 8.3,0 10,1.2z" Fill="#FF212121" FlowDirection="LeftToRight" Margin="3" Visibility="Collapsed" VerticalAlignment="Center"/>
<ContentPresenter ContentTemplate="{TemplateBinding HeaderTemplate}" Content="{TemplateBinding Header}" Grid.Column="1" ContentStringFormat="{TemplateBinding HeaderStringFormat}" ContentSource="Header" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="Icon" Value="{x:Null}">
<Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Visibility" TargetName="GlyphPanel" Value="Visible"/>
<Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
</Trigger>
<Trigger Property="IsHighlighted" Value="True">
<Setter Property="Background" TargetName="templateRoot" Value="#3D26A0DA"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="#FF26A0DA"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="TextElement.Foreground" TargetName="templateRoot" Value="#FF707070"/>
<Setter Property="Fill" TargetName="GlyphPanel" Value="#FF707070"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsHighlighted" Value="True"/>
<Condition Property="IsEnabled" Value="False"/>
</MultiTrigger.Conditions>
<Setter Property="Background" TargetName="templateRoot" Value="#0A000000"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="#21000000"/>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
The relevant part in your case is:
<Trigger Property="IsHighlighted" Value="True">
<Setter Property="Background" TargetName="templateRoot" Value="#3D26A0DA"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="#FF26A0DA"/>
</Trigger>
You can change the background color here to achieve what you want (I changed it to Red to see it better):
You may want to change the BorderBrush color as well.
Your template should contains ContentPresenter
<Border x:Name="border"Background="#282828" >
<ContentPresenter Content="{TemplateBinding Header}"/>
</Border>
In native template of MenuItem used ContentPresenter and set ContentSource="Header"
<ControlTemplate x:Key="{ComponentResourceKey ResourceId=SubmenuItemTemplateKey, TypeInTargetAssembly={x:Type MenuItem}}" TargetType="{x:Type MenuItem}">
<Border x:Name="templateRoot" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Height="22" SnapsToDevicePixels="true">
<Grid Margin="-1">
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="22" SharedSizeGroup="MenuItemIconColumnGroup" Width="Auto"/>
<ColumnDefinition Width="13"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="30"/>
<ColumnDefinition SharedSizeGroup="MenuItemIGTColumnGroup" Width="Auto"/>
<ColumnDefinition Width="20"/>
</Grid.ColumnDefinitions>
<ContentPresenter x:Name="Icon" ContentSource="Icon" HorizontalAlignment="Center" Height="16" Margin="3" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center" Width="16"/>
<Border x:Name="GlyphPanel" BorderBrush="{StaticResource MenuItem.Highlight.Border}" BorderThickness="1" Background="{StaticResource MenuItem.Highlight.Background}" HorizontalAlignment="Center" Height="22" Margin="-1,0,0,0" Visibility="Hidden" VerticalAlignment="Center" Width="22">
<Path x:Name="Glyph" Data="{StaticResource Checkmark}" Fill="{StaticResource MenuItem.Selected.Glyph}" FlowDirection="LeftToRight" Height="11" Width="9"/>
</Border>
<!-- ContentPresenter which showing MenuItem.Header -->
<ContentPresenter x:Name="menuHeaderContainer" Grid.Column="2" ContentSource="Header" HorizontalAlignment="Left" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center"/>
<TextBlock x:Name="menuGestureText" Grid.Column="4" Margin="{TemplateBinding Padding}" Opacity="0.7" Text="{TemplateBinding InputGestureText}" VerticalAlignment="Center"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
...
</ControlTemplate.Triggers>
</ControlTemplate>
Here is my code -
<Style x:Key="CustomComboBox" TargetType="{x:Type ComboBox}">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="FontSize" Value="18"/>
<Setter Property="Background" Value="LightGray"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBox}">
<Grid>
<Grid.Resources>
// This part, I want to set dynamically
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="{TemplateBinding BorderBrush}"></SolidColorBrush>
</Grid.Resources>
<ToggleButton Grid.Column="2" Template="{StaticResource ComboBoxToggleButton}" x:Name="ToggleButton" Focusable="false" IsChecked="{Binding Path=IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" ClickMode="Press" Background="{TemplateBinding Background}" Foreground="{TemplateBinding Foreground}" BorderBrush="{TemplateBinding BorderBrush}"/>
<ContentPresenter HorizontalAlignment="Left" Margin="10,3,23,3" x:Name="Content" VerticalAlignment="Center" Content="{TemplateBinding SelectionBoxItem}" ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}" ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}" IsHitTestVisible="False"/>
<TextBox x:Name="PART_EditableTextBox" Visibility="Hidden" Template="{StaticResource ComboBoxTextBox}" HorizontalAlignment="Left" Margin="3,3,23,3" Style="{x:Null}" VerticalAlignment="Center" Focusable="True" Background="{TemplateBinding Background}" Foreground="{TemplateBinding Foreground}" IsReadOnly="{TemplateBinding IsReadOnly}" FontSize="{TemplateBinding FontSize}"/>
<Popup Placement="Center" x:Name="Popup" Focusable="False" AllowsTransparency="True"
IsOpen="{TemplateBinding IsDropDownOpen}" PopupAnimation="Fade" VerticalOffset="-2">
<Grid MinWidth="{TemplateBinding ActualWidth}" MaxHeight="{TemplateBinding MaxDropDownHeight}"
x:Name="DropDown" SnapsToDevicePixels="True">
<Border BorderBrush="LightGray" BorderThickness="1,1,1,1" x:Name="DropDownBorder" Background="White" />
<ScrollViewer x:Name="ScrollViewer" Template="{DynamicResource CustomScrollViewerControlTemplate}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="0" Margin="4,6,4,6" SnapsToDevicePixels="True" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" CanContentScroll="True">
<ItemsPresenter KeyboardNavigation.DirectionalNavigation="Contained" />
</ScrollViewer>
</Grid>
</Popup>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="HasItems" Value="false">
<Setter Property="MinHeight" Value="95" TargetName="DropDownBorder"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="LightGray"/>
</Trigger>
<Trigger Property="IsGrouping" Value="true">
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
</Trigger>
<Trigger Property="AllowsTransparency" SourceName="Popup" Value="true">
<Setter Property="Margin" Value="0,2,0,0" TargetName="DropDownBorder"/>
</Trigger>
<Trigger Property="IsEditable" Value="true">
<Setter Property="IsTabStop" Value="false"/>
<Setter Property="Visibility" Value="Visible" TargetName="PART_EditableTextBox"/>
<Setter Property="Visibility" Value="Hidden" TargetName="ContentSite"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I am creating Custom ComboBox. Here I am trying to get BorderBrush value from ComboBox's TemplateBinding. But I am not getting it. It is always white. I dont know why it is happening, may be my way of getting the Brush is wrong.
Please suggest.
I would like to add radio buttons to my menu items.
I have seen a few answers where people were making radio buttons as the menu items. But I want my menu items to have the proper radio button that can be easily done in Winforms.
To make sure I don't get the same answers as other people, here is a picture of what the menu items' radio buttons should look like:
And by the way, I am using C#, WPF.
Edited Template
<Window.Resources>
<Style x:Key="{x:Type MenuItem}" TargetType="MenuItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type MenuItem}">
<Border x:Name="templateRoot" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
<Grid VerticalAlignment="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<ContentPresenter x:Name="Icon" Content="{TemplateBinding Icon}" ContentSource="Icon" HorizontalAlignment="Center" Height="16" Margin="3" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center" Width="16"/>
<RadioButton Margin="3" IsChecked="{TemplateBinding IsChecked}" VerticalAlignment="Center" x:Name="GlyphPanel" Visibility="Collapsed"/>
<ContentPresenter ContentTemplate="{TemplateBinding HeaderTemplate}" Content="{TemplateBinding Header}" Grid.Column="1" ContentStringFormat="{TemplateBinding HeaderStringFormat}" ContentSource="Header" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
<Popup x:Name="PART_Popup" AllowsTransparency="True" Focusable="False" IsOpen="{Binding IsSubmenuOpen, RelativeSource={RelativeSource TemplatedParent}}" PopupAnimation="{DynamicResource {x:Static SystemParameters.MenuPopupAnimationKey}}" Placement="Bottom">
<Border x:Name="SubMenuBorder" BorderBrush="#FF999999" BorderThickness="1" Background="#FFF0F0F0" Padding="2">
<ScrollViewer x:Name="SubMenuScrollViewer" Style="{DynamicResource {ComponentResourceKey ResourceId=MenuScrollViewer, TypeInTargetAssembly={x:Type FrameworkElement}}}">
<Grid RenderOptions.ClearTypeHint="Enabled">
<Canvas HorizontalAlignment="Left" Height="0" VerticalAlignment="Top" Width="0">
<Rectangle x:Name="OpaqueRect" Fill="{Binding Background, ElementName=SubMenuBorder}" Height="{Binding ActualHeight, ElementName=SubMenuBorder}" Width="{Binding ActualWidth, ElementName=SubMenuBorder}"/>
</Canvas>
<Rectangle Fill="#FFD7D7D7" HorizontalAlignment="Left" Margin="29,2,0,2" Width="1"/>
<ItemsPresenter x:Name="ItemsPresenter" KeyboardNavigation.DirectionalNavigation="Cycle" Grid.IsSharedSizeScope="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" KeyboardNavigation.TabNavigation="Cycle"/>
</Grid>
</ScrollViewer>
</Border>
</Popup>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSuspendingPopupAnimation" Value="True">
<Setter Property="PopupAnimation" TargetName="PART_Popup" Value="None"/>
</Trigger>
<Trigger Property="Icon" Value="{x:Null}">
<Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Visibility" TargetName="GlyphPanel" Value="Visible"/>
<Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
</Trigger>
<Trigger Property="IsHighlighted" Value="True">
<Setter Property="Background" TargetName="templateRoot" Value="#3D26A0DA"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="#FF26A0DA"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="TextElement.Foreground" TargetName="templateRoot" Value="#FF707070"/>
<Setter Property="Visibility" TargetName="GlyphPanel" Value="Collapsed"/>
</Trigger>
<Trigger Property="CanContentScroll" SourceName="SubMenuScrollViewer" Value="False">
<Setter Property="Canvas.Top" TargetName="OpaqueRect" Value="{Binding VerticalOffset, ElementName=SubMenuScrollViewer}"/>
<Setter Property="Canvas.Left" TargetName="OpaqueRect" Value="{Binding HorizontalOffset, ElementName=SubMenuScrollViewer}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ItemcontainerStyle" TargetType="MenuItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type MenuItem}">
<Border x:Name="templateRoot" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
<Grid Margin="-1">
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="22" SharedSizeGroup="MenuItemIconColumnGroup" Width="Auto"/>
<ColumnDefinition Width="13"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="30"/>
<ColumnDefinition SharedSizeGroup="MenuItemIGTColumnGroup" Width="Auto"/>
<ColumnDefinition Width="20"/>
</Grid.ColumnDefinitions>
<ContentPresenter x:Name="Icon" Content="{TemplateBinding Icon}" ContentSource="Icon" HorizontalAlignment="Center" Height="16" Margin="3" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center" Width="16"/>
<Border x:Name="GlyphPanel" BorderBrush="#FF26A0DA" BorderThickness="1" Background="#3D26A0DA" ClipToBounds="False" HorizontalAlignment="Center" Height="22" Margin="-1,0,0,0" Visibility="Hidden" VerticalAlignment="Center" Width="22">
<RadioButton x:Name="Glyph" IsChecked="{TemplateBinding IsChecked}" GroupName="a" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Border>
<ContentPresenter x:Name="menuHeaderContainer" ContentTemplate="{TemplateBinding HeaderTemplate}" Content="{TemplateBinding Header}" Grid.Column="2" ContentStringFormat="{TemplateBinding HeaderStringFormat}" ContentSource="Header" HorizontalAlignment="Left" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center"/>
<TextBlock x:Name="menuGestureText" Grid.Column="4" Margin="{TemplateBinding Padding}" Opacity="0.7" Text="{TemplateBinding InputGestureText}" VerticalAlignment="Center"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="Icon" Value="{x:Null}">
<Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Visibility" TargetName="GlyphPanel" Value="Visible"/>
<Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
</Trigger>
<Trigger SourceName="Glyph" Property="IsChecked" Value="False">
<Setter Property="Visibility" TargetName="GlyphPanel" Value="Hidden"/>
<Setter Property="Visibility" TargetName="Glyph" Value="Collapsed"/>
</Trigger>
<Trigger Property="IsHighlighted" Value="True">
<Setter Property="Background" TargetName="templateRoot" Value="#3D26A0DA"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="#FF26A0DA"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="TextElement.Foreground" TargetName="templateRoot" Value="#FF707070"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsHighlighted" Value="True"/>
<Condition Property="IsEnabled" Value="False"/>
</MultiTrigger.Conditions>
<Setter Property="Background" TargetName="templateRoot" Value="#0A000000"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="#21000000"/>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
MainWindow.xaml:
<Menu>
<MenuItem Header="File" ItemContainerStyle="{StaticResource ItemcontainerStyle}">
<MenuItem IsCheckable="True" Header="Example Menu Item"/>
<MenuItem IsCheckable="True" Header="Example Menu Item"/>
</MenuItem>
</Menu>
App.xaml
<Application x:Class="MenuItemTemplate.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
<!--Luna-->
<ResourceDictionary Source="/PresentationFramework.Luna, Version=3.0.0.0,
Culture=neutral, PublicKeyToken=31bf3856ad364e35,
ProcessorArchitecture=MSIL;component/themes/luna.normalcolor.xaml" />
<!--Aero-->
<!--<ResourceDictionary Source="/PresentationFramework.Aero, Version=3.0.0.0,
Culture=neutral, PublicKeyToken=31bf3856ad364e35,
ProcessorArchitecture=MSIL;component/themes/aero.normalcolor.xaml"/>-->
<!--Classic-->
<!--<ResourceDictionary Source="/PresentationFramework.Classic, Version=3.0.0.0,
Culture=neutral, PublicKeyToken=31bf3856ad364e35,
ProcessorArchitecture=MSIL;component/themes/classic.xaml" />-->
</Application.Resources>
OutPut
You can change the look of a Control by changing its Template-property:
<MenuItem>
<MenuItem.Template>
<ControlTemplate>
<RadioButton>Radio</RadioButton>
</ControlTemplate>
</MenuItem.Template>
</MenuItem>
EDIT: Use a RadioButton as MenuItem-Icon, to get the look which is shown in the picture:
<MenuItem Header="Hallo">
<MenuItem.Icon>
<RadioButton/>
</MenuItem.Icon>
</MenuItem>