I've been working on a SplitButton control for WPF and its basically done, but I'm trying to go through all the possible properties that can be set on it and make sure they are actually implemented. I mostly have only two properties left to implement which is the ItemTemplate and ItemTemplateSelector (and AlternationCount, okay so 3 properties).
I was able to get the HeaderTemplate and HeaderTemplateSelector working by binding the ContentTemplate and ContentTemplateSelector to them on a ContentPresenter. This is for the button part of the control though. For the drop-drop part of the control I'm using a Popup, Border, and ItemsPresenter. The problem is that I can't figure how to set the ItemTemplate and ItemTemplateSelector properties for the ItemsPresenter.
Any ideas?
Update:
The full source code for the SplitButton is now available at:
http://anothersplitbutton.codeplex.com/
Here's the Luna.NormalColor.xaml file:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:WpfSplitButton="clr-namespace:WpfSplitButton"
xmlns:mwt="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Luna"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!-- SplitButtonHeader Style -->
<Style x:Key="{x:Type WpfSplitButton:SplitButtonHeader}"
TargetType="{x:Type WpfSplitButton:SplitButtonHeader}">
<Style.Resources>
<Style x:Key="ButtonFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="2"
StrokeThickness="1"
Stroke="Black"
StrokeDashArray="1 2"
SnapsToDevicePixels="True" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Style.Resources>
<Style.Setters>
<Setter Property="FocusVisualStyle"
Value="{StaticResource ButtonFocusVisual}" />
<Setter Property="HorizontalContentAlignment"
Value="Center" />
<Setter Property="PastLeftDetection"
Value="True" />
<Setter Property="VerticalContentAlignment"
Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<mwt:ButtonChrome x:Name="Chrome"
BorderBrush="{TemplateBinding Border.BorderBrush}"
RenderDefaulted="{TemplateBinding Button.IsDefaulted}"
RenderMouseOver="{TemplateBinding UIElement.IsMouseOver}"
RenderPressed="{TemplateBinding ButtonBase.IsPressed}"
SnapsToDevicePixels="True">
<Grid Background="{TemplateBinding ButtonBase.Background}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ContentPresenter Content="{TemplateBinding ContentControl.Content}"
ContentTemplate="{TemplateBinding ButtonBase.ContentTemplate}"
ContentTemplateSelector="{TemplateBinding ButtonBase.ContentTemplateSelector}"
HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}"
Margin="{TemplateBinding Control.Padding}"
RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}"
VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}" />
<Border x:Name="PART_DropDownInitiator"
Background="Transparent"
BorderBrush="{Binding Path=BorderBrush, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type WpfSplitButton:SplitButtonHeader}}}"
BorderThickness="1,0,0,0"
Grid.Column="1"
HorizontalAlignment="Stretch"
Margin="0,0,0,0"
Padding="4,0,4,0"
VerticalAlignment="Stretch">
<Path Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type WpfSplitButton:SplitButtonHeader}}}"
VerticalAlignment="Center">
<Path.Style>
<Style>
<Setter Property="Path.Fill"
Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}" />
<Style.Triggers>
<Trigger Property="WpfSplitButton:SplitButton.IsMouseOver"
Value="True">
<Setter Property="Path.Fill"
Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}" />
</Trigger>
</Style.Triggers>
</Style>
</Path.Style>
<Path.Data>
<PathGeometry>
<PathGeometry.Figures>
<PathFigureCollection>
<PathFigure IsClosed="True"
StartPoint="0,0">
<PathFigure.Segments>
<PathSegmentCollection>
<LineSegment Point="8,0" />
<LineSegment Point="4,5" />
</PathSegmentCollection>
</PathFigure.Segments>
</PathFigure>
</PathFigureCollection>
</PathGeometry.Figures>
</PathGeometry>
</Path.Data>
</Path>
</Border>
</Grid>
</mwt:ButtonChrome>
<ControlTemplate.Triggers>
<Trigger Property="UIElement.IsKeyboardFocused"
Value="True">
<Setter TargetName="Chrome"
Property="mwt:ButtonChrome.RenderDefaulted"
Value="True" />
</Trigger>
<Trigger Property="ToggleButton.IsChecked"
Value="True">
<Setter TargetName="Chrome"
Property="mwt:ButtonChrome.RenderPressed"
Value="True" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style.Setters>
</Style>
<!-- SplitButton -->
<Style x:Key="{x:Type WpfSplitButton:SplitButton}"
TargetType="{x:Type WpfSplitButton:SplitButton}">
<Style.Resources>
<LinearGradientBrush x:Key="ButtonNormalBackgroundFill"
EndPoint="0.5,1"
StartPoint="0.5,0">
<LinearGradientBrush.GradientStops>
<GradientStop Color="#FFFFFFFF"
Offset="0" />
<GradientStop Color="#FFF0F0EA"
Offset="0.9" />
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
<SolidColorBrush x:Key="ButtonBorder"
Color="#FF003C74" />
</Style.Resources>
<Setter Property="AutoUpdateHeader"
Value="True" />
<Setter Property="Background"
Value="{StaticResource ButtonNormalBackgroundFill}" />
<Setter Property="BorderBrush"
Value="{StaticResource ButtonBorder}" />
<Setter Property="BorderThickness"
Value="1" />
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
<Setter Property="HorizontalContentAlignment"
Value="Center" />
<Setter Property="Padding"
Value="4,4,4,4" />
<Setter Property="VerticalContentAlignment"
Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type WpfSplitButton:SplitButton}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<WpfSplitButton:SplitButtonHeader x:Name="PART_Header"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Content="{TemplateBinding Header}"
ContentTemplate="{TemplateBinding HeaderTemplate}"
ContentTemplateSelector="{TemplateBinding HeaderTemplateSelector}"
Cursor="{TemplateBinding Cursor}"
Foreground="{TemplateBinding Foreground}"
Grid.Row="0"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
Padding="{TemplateBinding Padding}"
VerticalAlignment="Stretch"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" />
<Popup x:Name="PART_Popup"
AllowsTransparency="True"
Grid.Row="1"
IsOpen="{Binding Path=IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
MinWidth="{Binding Path=ActualWidth, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type WpfSplitButton:SplitButton}}}"
Placement="Bottom"
PlacementTarget="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type WpfSplitButton:SplitButton}}}"
PopupAnimation="{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}"
StaysOpen="False">
<mwt:SystemDropShadowChrome Color="Transparent">
<Border x:Name="DropDownBorder"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Border>
</mwt:SystemDropShadowChrome>
</Popup>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsEnabled"
Value="False">
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
</Trigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
Update 2
I tried switching out the ItemsPresenter with a ItemsControl, but I can't seem to get the ItemTemplate property to do anything. Here's the changed section of code:
<ItemsControl DataContext="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type WpfSplitButton:SplitButton}}}"
AlternationCount="{TemplateBinding AlternationCount}"
IsTabStop="{TemplateBinding IsTabStop}"
IsTextSearchEnabled="{TemplateBinding IsTextSearchEnabled}"
ItemContainerStyle="{TemplateBinding ItemContainerStyle}"
ItemContainerStyleSelector="{TemplateBinding ItemContainerStyleSelector}"
ItemBindingGroup="{TemplateBinding ItemBindingGroup}"
ItemsPanel="{TemplateBinding ItemsPanel}"
ItemsSource="{Binding Path=Items}"
ItemStringFormat="{TemplateBinding ItemStringFormat}"
ItemTemplateSelector="{TemplateBinding ItemTemplateSelector}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="HELLO" />
</DataTemplate>
</ItemsControl.ItemTemplate>
Have you considered using an ItemsControl instead of the ItemsPresenter? This would give you the ItemTemplate and ItemTemplateSelector property as well as the AlternationCount property.
Update:
I got it to work just fine using the ItemsControl like you posted above using the following line to bind to the ItemsTemplate Property in your Classic.xaml file:
ItemTemplate="{TemplateBinding ItemsTemplate, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type WpfSplitButton:SplitButton}}}"
Then in your MainWindow's Resources i just added the following template:
<DataTemplate x:Key="Test">
<MenuItem Header="{Binding}" />
</DataTemplate>
Then i set the ItemTemplate Property on the SplitButton:
ItemTemplate="{StaticResource Test}"
So just hook up your ItemSource and you are good to go... i just used a simple string[] in the code behind...
Hope this helps!
Related
I am trying to copy the IntelliJ Titlebar Menu in Windows as a learning exercise.
The default color changes of a WPF MenuItem seem to be:
Low Opacity blue background when "IsMouseOver" and not "IsSubmenuOpen"
Low Opacity blue background when "IsSubmenuOpen"
I would like to change this behavior to this (which can be observed in IntelliJ):
No color change when "IsMouseOver" and not "IsSubmenuOpen"
Dark blue background when "IsSubmenuOpen"
White foreground when "IsSubmenuOpen"
I have found code in this answer which is capable of doing this, but it also seems to disable the ability of the MenuItem to open its drop down box to reveal its children.
<Style x:Key="TitleBarMenuItem" TargetType="{x:Type MenuItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type MenuItem}">
<Border Background="{TemplateBinding Background}">
<ContentPresenter Content="{TemplateBinding Header}" Margin="35 5 10 5" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSubmenuOpen" Value="True">
<Setter Property="Foreground" Value="White"/>
<Setter Property="Background" Value="#2675BF"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
How can I get these color changes without disabling the MenuItem functionality?
The problem you have there is that there's no popup for the sub menu. You're missing something like:
<Popup x:Name="Popup"
Placement="Right"
HorizontalOffset="-4"
IsOpen="{TemplateBinding IsSubmenuOpen}"
AllowsTransparency="True"
Focusable="False"
PopupAnimation="Fade">
<Border x:Name="SubmenuBorder"
SnapsToDevicePixels="True"
Background="{DynamicResource MenuPopupBrush}"
BorderThickness="1">
<Border.BorderBrush>
<SolidColorBrush Color="{DynamicResource BorderMediumColor}" />
</Border.BorderBrush>
<ScrollViewer CanContentScroll="True"
Style="{StaticResource MenuScrollViewer}">
<StackPanel IsItemsHost="True"
KeyboardNavigation.DirectionalNavigation="Cycle" />
</ScrollViewer>
</Border>
</Popup>
Note that "IsItemsHost".
If you take a look at the templates for menu and menuitem you will notice it is very complicated stuff.
The approach I prefer is to work with content. You can put pretty much anything you like in a menuitem header.
One app I have does so with hard coded xaml. That's easier to understand than binding anyhow. Part of it looks like:
<MenuItem Header="_Layers" Style="{x:Null}">
<MenuItem>
<MenuItem.Header>
<CheckBox IsChecked="{Binding ShowBackground, Mode=TwoWay}">
_Background
</CheckBox>
</MenuItem.Header>
<MenuItem>
<MenuItem.Header>
<StackPanel Width="160">
<TextBlock Text="Opacity" />
<Slider Value="{Binding BackgroundOpacity, Mode=TwoWay}" />
</StackPanel>
</MenuItem.Header>
</MenuItem>
</MenuItem>
<MenuItem>
<MenuItem.Header>
<CheckBox IsChecked="{Binding AppSettings.ShowElevationMap, Mode=TwoWay}">
_Elevation Map
</CheckBox>
</MenuItem.Header>
<MenuItem>
<MenuItem.Header>
<StackPanel Width="160">
<TextBlock Text="Opacity" />
<Slider
Value="{Binding AppSettings.ElevationOpacity, Mode=TwoWay}" />
</StackPanel>
</MenuItem.Header>
Layers is a top level menu item. These are templated different to their children. ( Did I mention menus are complicated ).
I offset the content so I don't need to worry about the icon column in the grid.
The styling I have might be useful to get you started.
You said this was a learning exercise so just doing it for you is presumably not exactly going to exercise your learning.
<ItemsPanelTemplate x:Key="MenuItemPanelTemplate">
<StackPanel Margin="-20,0,0,0" Background="White"/>
</ItemsPanelTemplate>
<Style TargetType="MenuItem" x:Key="MenuItemNoIcon">
<Setter Property="ItemsPanel" Value="{StaticResource MenuItemPanelTemplate}"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
</Style>
<Style TargetType="{x:Type MenuItem}" x:Key="{x:Type MenuItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type MenuItem}">
<Border x:Name="templateRoot" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{x:Static SystemColors.MenuBarBrush}"
SnapsToDevicePixels="True">
<Grid Margin="-1, 2, 0, 2">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="MenuItemIconColumnGroup" Width="0"/>
<ColumnDefinition Width="0"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="0"/>
<ColumnDefinition SharedSizeGroup="MenuItemIGTColumnGroup" Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<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" Width="10" Data="M0,0L4,3.5 0,7z" Fill="#FF212121" Margin="8,0,2,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="#FFF0F0F0" Padding="2">
<ScrollViewer x:Name="SubMenuScrollViewer" Style="{DynamicResource {ComponentResourceKey ResourceId=MenuScrollViewer, TypeInTargetAssembly={x:Type FrameworkElement}}}">
<Grid RenderOptions.ClearTypeHint="Enabled">
<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="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="RightArrow" Value="#FF707070"/>
</Trigger>
<DataTrigger Binding="{Binding Items.Count, RelativeSource={RelativeSource Self}}" Value="0">
<Setter Property="Visibility" TargetName="RightArrow" Value="Collapsed"/>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I have an Expander and it should receive the full width of the column but I cant get it to work.
I tried to add the Horizontal(Content)Alignment = stretch on the TextBlock and on the Expander itself even on the Grid, but it is not working.
What I need is that the Expander takes about 90% of the width and the rest are assigned to the buttons as in the following example:
I want to display e.g. a name and when you press on it, expands down and shows additional information
and if the buttons are pressed, then the commands behind the buttons will be executed (no commands are binded in the example).
<ListView
ItemsSource="{Binding log}"
SelectionMode="Multiple"
Style="{StaticResource ListViewStyle}">
<ListView.ItemTemplate>
<DataTemplate>
<Border BorderThickness="0,0,0,1" BorderBrush="Gray">
<Grid HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100*" />
<ColumnDefinition Width="5*" />
<ColumnDefinition Width="5*" />
</Grid.ColumnDefinitions>
<Expander Grid.Column="0"
HorizontalAlignment="Stretch"
IsExpanded="{Binding Mode=TwoWay, Path=IsSelected, RelativeSource={RelativeSource AncestorType=ListBoxItem, Mode=FindAncestor}}"
Style="{StaticResource ExpanderStyle}">
<Expander.Header>
<TextBlock Text="{Binding Name}" Foreground="White"
HorizontalAlignment="Stretch" />
</Expander.Header>
<TextBlock
VerticalAlignment="Center"
FontSize="16"
Foreground="White"
Text="{Binding Description}" />
</Expander>
<Button Grid.Column="1"
Style="{StaticResource IconButton}">
<Button.Background>
<ImageBrush ImageSource="../icons/edit.png"
Stretch="None" />
</Button.Background>
</Button>
<dialogButton:ConfirmButton Grid.Column="2"
Question="{x:Static language:Strings.confirm}"
Style="{DynamicResource IconButton}"
Margin="0,0,10,0">
<dialogButton:ConfirmButton.Background>
<ImageBrush ImageSource="../icons/delete.png"
Stretch="None" />
</dialogButton:ConfirmButton.Background>
</dialogButton:ConfirmButton>
</Grid>
</Border>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Styles
<Style x:Key="ExpanderDownHeaderStyle" TargetType="{x:Type ToggleButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border Padding="{TemplateBinding Padding}">
<Grid Background="Transparent" SnapsToDevicePixels="False">
<ContentPresenter HorizontalAlignment="Stretch" Margin="0" RecognizesAccessKey="True" SnapsToDevicePixels="True" VerticalAlignment="Center"/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ExpanderStyle" TargetType="{x:Type Expander}">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Stretch"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Expander}">
<Border Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" CornerRadius="3" SnapsToDevicePixels="true">
<DockPanel>
<ToggleButton x:Name="HeaderSite" ContentTemplate="{TemplateBinding HeaderTemplate}" Content="{TemplateBinding Header}" ContentTemplateSelector="{TemplateBinding HeaderTemplateSelector}" DockPanel.Dock="Top" FontStyle="{TemplateBinding FontStyle}" FontStretch="{TemplateBinding FontStretch}" FontWeight="{TemplateBinding FontWeight}" FocusVisualStyle="{StaticResource ExpanderHeaderFocusVisual}" FontFamily="{TemplateBinding FontFamily}" Foreground="{TemplateBinding Foreground}" FontSize="{TemplateBinding FontSize}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" IsChecked="{Binding IsExpanded, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" MinHeight="0" MinWidth="0" Margin="1" Padding="{TemplateBinding Padding}" Style="{StaticResource ExpanderDownHeaderStyle}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
<ContentPresenter x:Name="ExpandSite" DockPanel.Dock="Bottom" Focusable="false" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Visibility="Collapsed"/>
</DockPanel>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="true">
<Setter Property="Visibility" TargetName="ExpandSite" Value="Visible"/>
</Trigger>
<Trigger Property="ExpandDirection" Value="Down">
<Setter Property="DockPanel.Dock" TargetName="ExpandSite" Value="Bottom"/>
<Setter Property="DockPanel.Dock" TargetName="HeaderSite" Value="Top"/>
<Setter Property="Background" Value="Transparent" />
<Setter Property="Style" TargetName="HeaderSite" Value="{StaticResource ExpanderDownHeaderStyle}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I also tried things from the following Threads
wpf - Header of Expander fit contents width?
Problem here is that the Buttons are pushed out of the view
Best Solution would be if the Expander just takes the width of the column so that I can adjust the widths of the element by the Grid.ColumnDefinition.
The issue is that the item container, a ListViewItem does not stretch its content by default. You have to create an item container style in order to set the HorizontalContentAlignment to Stretch.
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListView.ItemContainerStyle>
How do I change a custom menu item's background when I hover it? I changed the background property but it doesn't change, it stays the default blue color.
I also tried to change the trigger style on hover, but again, it doesn't help, it gets ignored.
The idea is to hover the menu item and then a custom color should appear instead of the default blue color.
Here is the code:
<Style TargetType="{x:Type Menu}" x:Key="TopbarMenu" BasedOn="{StaticResource BaseStyle}">
<Setter Property="WindowChrome.IsHitTestVisibleInChrome" Value="True"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Foreground" Value="{StaticResource WhiteBrush}"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="VerticalAlignment" Value="Center"/>
</Style>
<Style TargetType="{x:Type MenuItem}" x:Key="DropdownMenuButton" BasedOn="{StaticResource BaseStyle}">
<Setter Property="TextOptions.TextFormattingMode" Value="Display"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Margin" Value="6 0 6 0"/>
</Style>
I think it is something connected to templates, but I'm not very competent with templates, and I could be fundamentally wrong and the problem could be something else.
This is the way I'm doing it... works perfectly for me:
<ControlTemplate TargetType="{x:Type MenuItem}" x:Key="MenuItemTemplate">
<Border x:Name="Border" Padding="10,5,10,5" BorderThickness="0" Margin="0">
<ContentPresenter ContentSource="Header" x:Name="HeaderHost" RecognizesAccessKey="True" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsHighlighted" Value="true">
<Setter Property="Background" TargetName="Border" Value="Blue"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
and use with:
<MenuItem Template="{StaticResource MenuItemTemplate}" Header="test" />
[EDIT]
As per request here is some stuff to support submenus correctly:
<ControlTemplate TargetType="MenuItem" x:Key="rootMenuItem">
<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="{TemplateBinding Foreground}" 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}"/>
<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="BLUE"/>
<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>
<Style 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" 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="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="#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="{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="BLUE"/>
<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>
</Setter.Value>
</Setter>
</Style>
and the usage test:
<Menu HorizontalAlignment="Center" VerticalAlignment="Center">
<MenuItem Header="test" Template="{StaticResource rootMenuItem}">
<MenuItem Header="test" >
<MenuItem Header="test">
<MenuItem Header="test">
<MenuItem Header="test">
<MenuItem Header="test">
<MenuItem Header="test" />
<MenuItem Header="test" />
</MenuItem>
<MenuItem Header="test" />
</MenuItem>
<MenuItem Header="test" />
</MenuItem>
<MenuItem Header="test" />
</MenuItem>
<MenuItem Header="test">
<MenuItem Header="test">
<MenuItem Header="test" />
<MenuItem Header="test" />
</MenuItem>
<MenuItem Header="test">
<MenuItem Header="test">
<MenuItem Header="test" />
<MenuItem Header="test" />
</MenuItem>
<MenuItem Header="test" />
</MenuItem>
</MenuItem>
</MenuItem>
</MenuItem>
<MenuItem Header="test" Template="{StaticResource rootMenuItem}">
<MenuItem Header="test">
<MenuItem Header="test" />
<MenuItem Header="test" />
</MenuItem>
</MenuItem>
</Menu>
Beware, the root-item has another template than the child-items! in this demo it's done with static template binding for the root elements but in a real use case you can do this with a style selector like this:
<Style TargetType="{x:Type MenuItem}" x:Key="{x:Type MenuItem}">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Style.Triggers>
<Trigger Property="Role" Value="SubmenuHeader">
<Setter Property="Template" Value="{StaticResource {x:Static MenuItem.SubmenuHeaderTemplateKey}}"/>
</Trigger>
<Trigger Property="Role" Value="SubmenuItem">
<Setter Property="Template" Value="{StaticResource {x:Static MenuItem.SubmenuItemTemplateKey}}"/>
</Trigger>
</Style.Triggers>
</Style>
[/EDIT]
[EDIT2]
For the arrow to disappear, you need a StyleSelector as mentioned.
this class has to be implemented assuming yout two styles are named "MenuItemWithChildren" and "MenuItemWithoutChildren"
class ItemStyleSelector : StyleSelector
{
public override Style SelectStyle(object item, DependencyObject container)
{
if(item is MenuItem mItem)
{
if(mItem.Items.Count > 0)
{
return App.Current.Resources["MenuItemWithChildren"] as Style;
}
else
{
return App.Current.Resources["MenuItemWithoutChildren"] as Style;
}
}
return base.SelectStyle(item, container);
}
}
then you have to define two different styles & templates for each of the items, with and without children:
Important: these have to be defined in app.xaml or some resource-dictionary which is linked there, else the ItemStyleSelector class wont find them. E.g. Window.Resources won't be found.
<Style TargetType="MenuItem" x:Key="MenuItemWithChildren">
<Setter Property="ItemContainerStyleSelector" Value="{StaticResource ItemStyleSelector}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type MenuItem}">
[Your Template goes here]
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="MenuItem" x:Key="MenuItemWithoutChildren">
<Setter Property="ItemContainerStyleSelector" Value="{StaticResource ItemStyleSelector}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type MenuItem}">
[Your Template goes here]
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
also your Styleselctor itself and a default style for the menuitem
<local:ItemStyleSelector x:Key="ItemStyleSelector" />
<Style TargetType="MenuItem">
<Setter Property="ItemContainerStyleSelector" Value="{StaticResource ItemStyleSelector}" />
</Style>
and declare the selection in the menu:
<Menu ItemContainerStyleSelector="{StaticResource ItemStyleSelector}">
<MenuItem Header="test" Template="{StaticResource rootMenuItem}">
<MenuItem Header="test">
<MenuItem Header="test" />
<MenuItem Header="test" />
</MenuItem>
</MenuItem>
</Menu>
[/EDIT2]
I am styling a ComboBox, I just copy-paste the default style and changes some stuff already. The problem I have is that the SelectedItem is not being shown.
Maybe a xaml Guru can help me out to find th error.
The combobox will not be editable, so I guess the problem is in the ContentSite but I am not pretty sure how I can make it work.
Thanks in advance!
EDIT:
I have already check that there is a SelectedItem, if I use a normal ComboBox, the item is shown.
CurrentStyle:
<ControlTemplate x:Key="ToggleButton"
TargetType="{x:Type ToggleButton}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="50" />
</Grid.ColumnDefinitions>
<Border x:Name="Border"
Grid.ColumnSpan="2"
Background="{StaticResource ColorMagnoscoGreen}"
BorderBrush="#FF97A0A5"
BorderThickness="1"
CornerRadius="0" />
<Border Grid.Column="0"
Margin="1"
Background="White"
BorderThickness="1"
CornerRadius="0" />
<Path x:Name="Arrow"
Grid.Column="1"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="M0,0 L0,2 L4,6 L8,2 L8,0 L4,4 z"
Fill="White" />
</Grid>
</ControlTemplate>
<ControlTemplate x:Key="ComboBoxTextBox"
TargetType="{x:Type TextBox}">
<Border x:Name="PART_ContentHost"
BorderThickness="1"
Focusable="False">
</Border>
</ControlTemplate>
<Style x:Key="{x:Type ComboBox}"
TargetType="{x:Type ComboBox}">
<Setter Property="SnapsToDevicePixels" Value="true" />
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto" />
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" />
<Setter Property="ScrollViewer.CanContentScroll" Value="true" />
<Setter Property="MinWidth" Value="120" />
<Setter Property="MinHeight" Value="40" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBox}">
<Grid>
<ContentPresenter x:Name="ContentSite"
IsHitTestVisible="False"
Content="{TemplateBinding SelectionBoxItem}"
ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"
Margin="3,3,23,3"
VerticalAlignment="Stretch"
HorizontalAlignment="Left">
</ContentPresenter>
<TextBox x:Name="PART_EditableTextBox"
Style="{x:Null}"
Template="{StaticResource ComboBoxTextBox}"
HorizontalAlignment="Left"
VerticalAlignment="Bottom"
Margin="3,3,23,3"
Focusable="True"
Visibility="Hidden"
IsReadOnly="{TemplateBinding IsReadOnly}" />
<Popup Name="Popup"
AllowsTransparency="False"
Focusable="False"
IsOpen="{TemplateBinding IsDropDownOpen}"
Placement="Bottom"
PopupAnimation="Slide">
<Grid Name="DropDown"
Background="White"
MinWidth="{TemplateBinding ActualWidth}"
MaxHeight="{TemplateBinding MaxDropDownHeight}"
SnapsToDevicePixels="True">
<Border x:Name="DropDownBorder"
BorderBrush="#888888"
BorderThickness="1" />
<ScrollViewer Margin="4,6,4,6"
SnapsToDevicePixels="True">
<StackPanel IsItemsHost="True"
KeyboardNavigation.DirectionalNavigation="Contained" />
</ScrollViewer>
</Grid>
</Popup>
<ToggleButton Name="ToggleButton"
Grid.Column="2"
ClickMode="Press"
Focusable="false"
IsChecked="{Binding Path=IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
Template="{StaticResource ComboBoxToggleButton}" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="HasItems" Value="false">
<Setter TargetName="DropDownBorder" Property="MinHeight" Value="95" />
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#888888" />
</Trigger>
<Trigger Property="IsGrouping" Value="true">
<Setter Property="ScrollViewer.CanContentScroll" Value="false" />
</Trigger>
<Trigger SourceName="Popup" Property="Popup.AllowsTransparency" Value="true">
<Setter TargetName="DropDownBorder" Property="CornerRadius" Value="0" />
<Setter TargetName="DropDownBorder" Property="Margin" Value="0,2,0,0" />
</Trigger>
<Trigger Property="IsEditable" Value="true">
<Setter Property="IsTabStop" Value="false" />
<Setter TargetName="PART_EditableTextBox" Property="Visibility" Value="Visible" />
<Setter TargetName="ContentSite" Property="Visibility" Value="Hidden" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="{x:Type ComboBoxItem}"
TargetType="{x:Type ComboBoxItem}">
<Setter Property="SnapsToDevicePixels" Value="true" />
<Setter Property="Foreground" Value="Black" />
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="FontSize" Value="16"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBoxItem}">
<Border Name="Border"
Padding="2"
SnapsToDevicePixels="true">
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsHighlighted" Value="true">
<Setter TargetName="Border" Property="Background" Value="{StaticResource ColorMagnoscoGreen}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The ToggleButton hides the ContentPresenter in the ControlTemplate. Move the ContentPresenter below the ToggleButton:
<Grid>
<TextBox x:Name="PART_EditableTextBox"
Style="{x:Null}"
Template="{StaticResource ComboBoxTextBox}"
HorizontalAlignment="Left"
VerticalAlignment="Bottom"
Margin="3,3,23,3"
Focusable="True"
Visibility="Hidden"
IsReadOnly="{TemplateBinding IsReadOnly}" />
<Popup Name="Popup"
AllowsTransparency="False"
Focusable="False"
IsOpen="{TemplateBinding IsDropDownOpen}"
Placement="Bottom"
PopupAnimation="Slide">
<Grid Name="DropDown"
Background="White"
MinWidth="{TemplateBinding ActualWidth}"
MaxHeight="{TemplateBinding MaxDropDownHeight}"
SnapsToDevicePixels="True">
<Border x:Name="DropDownBorder"
BorderBrush="#888888"
BorderThickness="1" />
<ScrollViewer Margin="4,6,4,6" SnapsToDevicePixels="True">
<StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained" />
</ScrollViewer>
</Grid>
</Popup>
<ToggleButton Name="ToggleButton"
Grid.Column="2"
ClickMode="Press"
Focusable="false"
IsChecked="{Binding Path=IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
Template="{StaticResource ComboBoxToggleButton}" />
<ContentPresenter x:Name="ContentSite"
IsHitTestVisible="False"
Content="{TemplateBinding SelectionBoxItem}"
ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"
Margin="3,3,23,3"
VerticalAlignment="Stretch"
HorizontalAlignment="Left">
</ContentPresenter>
</Grid>
I am using CheckComboBox of WPF toolkit. I need to change Popup style of CheckComboBox. (I.e. when CheckBox is checked, Backcolor of Item should be changed, and etc). While trying Exploring control with Blend, I could not find any template to edit its item template.
Can anyone suggest how to customize template of CheckComboBox?
I tried this using Blend.
Thanks in anticipation.
May be the question is outdated, but there is some code for mentioned control on git: https://github.com/samoatesgames/mui.extended.toolkit/blob/master/ModernUI.Xceed/ModernUI.Xceed.Toolkit/Assets/Controls/CheckComboBox.xaml
Here is the style of CheckComboBox, where you can find Popup and other elements of template.
<xctk:InverseBoolConverter x:Key="InverseBoolConverter" />
<Geometry x:Key="DownArrowGeometry">M 0,1 C0,1 0,0 0,0 0,0 3,0 3,0 3,0 3,1 3,1 3,1 4,1 4,1 4,1 4,0 4,0 4,0 7,0 7,0 7,0 7,1 7,1 7,1 6,1 6,1 6,1 6,2 6,2 6,2 5,2 5,2 5,2 5,3 5,3 5,3 4,3 4,3 4,3 4,4 4,4 4,4 3,4 3,4 3,4 3,3 3,3 3,3 2,3 2,3 2,3 2,2 2,2 2,2 1,2 1,2 1,2 1,1 1,1 1,1 0,1 0,1 z</Geometry>
<Style x:Key="ComboBoxToggleButton"
TargetType="{x:Type ToggleButton}">
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="IsTabStop" Value="false" />
<Setter Property="Focusable" Value="false" />
<Setter Property="Padding" Value="2" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<xctk:ButtonChrome x:Name="Chrome"
BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}"
CornerRadius="0"
RenderEnabled="{TemplateBinding IsEnabled}"
RenderMouseOver="{Binding IsMouseOver, ElementName=PART_DropDownButton}"
RenderNormal="False"
RenderPressed="{Binding IsPressed, ElementName=PART_DropDownButton}"
SnapsToDevicePixels="true">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition MinWidth="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}" Width="0" />
</Grid.ColumnDefinitions>
<TextBox x:Name="TextBox"
Text="{Binding Content, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
Foreground="{TemplateBinding Foreground}"
BorderThickness="0"
Background="Transparent"
IsReadOnly="True"
Focusable="False"
Cursor="Arrow"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
HorizontalScrollBarVisibility="Hidden"
VerticalScrollBarVisibility="Hidden" />
<Grid Grid.Column="1"
HorizontalAlignment="Right"
Width="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}">
<Path x:Name="Arrow"
Data="{StaticResource DownArrowGeometry}"
Fill="{DynamicResource ItemText}"
HorizontalAlignment="Center"
Margin="3,0,3,0"
VerticalAlignment="Center" />
</Grid>
</Grid>
</xctk:ButtonChrome>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked"
Value="true">
<Setter Property="RenderPressed"
TargetName="Chrome"
Value="true" />
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Fill" TargetName="Arrow" Value="{DynamicResource ItemTextDisabled}" />
</Trigger>
<DataTrigger Binding="{Binding IsEditable, RelativeSource={RelativeSource AncestorType={x:Type xctk:CheckComboBox}}}" Value="True">
<Setter Property="IsReadOnly" Value="False" TargetName="TextBox" />
<Setter Property="Focusable" Value="True" TargetName="TextBox" />
<Setter Property="Cursor" Value="{x:Null}" TargetName="TextBox" />
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type xctk:CheckComboBox}">
<Setter Property="Foreground" Value="{DynamicResource ItemText}" />
<Setter Property="Background" Value="{DynamicResource WindowBackground}" />
<Setter Property="BorderBrush" Value="{DynamicResource ItemBorder}" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto" />
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" />
<Setter Property="Padding" Value="2" />
<Setter Property="ScrollViewer.CanContentScroll" Value="true" />
<Setter Property="ScrollViewer.PanningMode" Value="Both" />
<Setter Property="Stylus.IsFlicksEnabled" Value="False" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type xctk:CheckComboBox}">
<Grid x:Name="MainGrid"
SnapsToDevicePixels="true">
<Popup x:Name="PART_Popup"
AllowsTransparency="true"
IsOpen="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
StaysOpen="False"
Margin="1"
PopupAnimation="{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}"
Placement="Bottom">
<Grid MinWidth="{Binding ActualWidth, ElementName=MainGrid}">
<Border x:Name="DropDownBorder"
Padding="2"
MaxHeight="{Binding MaxDropDownHeight, RelativeSource={RelativeSource TemplatedParent}}"
BorderBrush="{DynamicResource WindowBorderActive}"
BorderThickness="1"
Background="{DynamicResource PopupBackground}">
<ScrollViewer x:Name="DropDownScrollViewer">
<Grid RenderOptions.ClearTypeHint="Enabled">
<Canvas HorizontalAlignment="Left"
Height="0"
VerticalAlignment="Top"
Width="0">
<Rectangle x:Name="OpaqueRect"
Fill="{Binding Background, ElementName=DropDownBorder}"
Height="{Binding ActualHeight, ElementName=DropDownBorder}"
Width="{Binding ActualWidth, ElementName=DropDownBorder}" />
</Canvas>
<ItemsPresenter x:Name="PART_ItemsPresenter"
KeyboardNavigation.DirectionalNavigation="Contained"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Grid>
</ScrollViewer>
</Border>
</Grid>
</Popup>
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" />
<ToggleButton x:Name="PART_DropDownButton"
Content="{Binding Text, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}"
Focusable="False"
IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
Style="{StaticResource ComboBoxToggleButton}"
Padding="{TemplateBinding Padding}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
IsHitTestVisible="{Binding IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource InverseBoolConverter}}" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver"
Value="True">
<Setter Property="BorderBrush" Value="{DynamicResource Accent}" />
</Trigger>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter Property="BorderBrush" Value="{DynamicResource Accent}" />
</Trigger>
</Style.Triggers>
</Style>
However, if you need to change background of selected item, you need to modify SelectorItem Style, something like
<Style TargetType="xctk:SelectorItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type xctk:SelectorItem}">
<Border x:Name="_background"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<CheckBox IsChecked="{Binding IsSelected, RelativeSource={RelativeSource TemplatedParent}}"
Padding="{TemplateBinding Padding}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
<CheckBox.Content>
<ContentControl Content="{TemplateBinding Content}"
ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}"
ContentTemplate="{TemplateBinding ContentTemplate}"
Foreground="{TemplateBinding Foreground}" />
</CheckBox.Content>
</CheckBox>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter TargetName="_background" Property="Background" Value="Red" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>