I set the Validation.ErrorTemplate property via a DataTrigger. The template includes the Border around my DatePicker and second Border with a TextBlock inside.
I am trying to visible the second Border when DatePickerTextBox IsFocused property is True only.
Below my code I have so far (it is just a shortened version):
<Style x:Key="CustomDatePickerStyle" TargetType="{x:Type DatePicker}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DatePicker}">
<Border Background="{DynamicResource Control.Background}" Padding="0" BorderThickness="0" CornerRadius="3">
<Button x:Name="PART_Button" Grid.Column="1" Foreground="{TemplateBinding Foreground}" Focusable="False" HorizontalAlignment="Left" Margin="3,0,3,0" Grid.Row="0" Template="{StaticResource DropDownButtonTemplate}" VerticalAlignment="Center" Width="20"/>
<DatePickerTextBox x:Name="PART_TextBox" Height="14" Margin="3 0 0 0" Grid.Column="0" Focusable="{TemplateBinding Focusable}"
HorizontalContentAlignment="Stretch" Grid.Row="0" VerticalContentAlignment="Center">
<DatePickerTextBox.Template>
<ControlTemplate TargetType="DatePickerTextBox">
<Border x:Name="Border" BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" CornerRadius="3" Opacity="1">
<Grid x:Name="WatermarkContent" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
<Border x:Name="ContentElement" BorderBrush="Red" BorderThickness="0"/>
<ScrollViewer x:Name="PART_ContentHost" Background="{TemplateBinding Background}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
<Border x:Name="FocusVisual" BorderBrush="Red" CornerRadius="3" IsHitTestVisible="False" Opacity="0"/>
</Grid>
</Border>
</ControlTemplate>
</DatePickerTextBox.Template>
</DatePickerTextBox>
</Grid>
</Border>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsReadOnly}" Value="false">
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<StackPanel>
<Border BorderThickness="1" BorderBrush="Red" CornerRadius="3" HorizontalAlignment="Left">
<AdornedElementPlaceholder x:Name="textBox"/>
</Border>
<Border Background="{DynamicResource Control.Validation.Background}" BorderBrush="{DynamicResource Control.Validation.Border}" BorderThickness="1" CornerRadius="3" >
<TextBlock Text="{Binding [0].ErrorContent}" Padding="3 0 3 0" Foreground="{DynamicResource Control.Validation.Foreground}" Margin="1"/>
<Border.Style>
<Style>
<Setter Property="Border.Visibility" Value="Collapsed"></Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding AdornedElement.(DatePicker.IsFocused), ElementName=textBox}" Value="True">
<Setter Property="Border.Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
</Border>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I think it is possible by accessing via ElementName = PART_TextBox, Path=IsFocused but I always get the Error: PART_TextBox not found
The DatePicker also has a IsKeyboardFocusWithin Property which is True if the focus is in the Textbox of the DatePicker. This helps out, i had the same problem.
<Style TargetType="DatePicker">
<Style.Triggers>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter Property="Background" Value="Green"/>
</Trigger>
</Style.Triggers>
</Style>
Related
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.
Trying to style my datagrid column headers, I encounter two problems.
What I want : I'd like my headers to be written in a border with the border drawn and a margin. See the picture :
What I get : I found that the border are drawn between 2 headers, plus I can't get rid of the shadow of the grip (white grip, grey shadow), as you as see in the picture
Here is my style for the headers :
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Height" Value="30" />
<Setter Property="SeparatorBrush" Value="{StaticResource ScbWhite}" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="Foreground" Value="{StaticResource ScbBlue1}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
<Grid Margin="{TemplateBinding Padding}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Border x:Name="columnHeaderBorder"
TextBlock.FontWeight="Bold"
TextBlock.Foreground="{StaticResource ScbBlue1}"
BorderThickness="2"
BorderBrush="{StaticResource ScbBlue1}"
Background="{StaticResource ScbWhite}"
Width="{TemplateBinding Width}"
Margin="3,3,3,3"
Padding="3,0,3,0">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Border>
<!--BorderBrush="{Binding VerticalGridLinesBrush, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}"-->
<Thumb x:Name="PART_RightHeaderGripper" Grid.Column="1"
HorizontalAlignment="Right"
Width="6" BorderThickness="0"
BorderBrush="{StaticResource ScbWhite}"
Background="{StaticResource ScbWhite}"
Cursor="SizeWE">
<Thumb.BitmapEffect>
<DropShadowBitmapEffect Color="Transparent" Opacity="0"/>
</Thumb.BitmapEffect>
</Thumb>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Please, what can I do to get what I want?
DataGrid adds empty column header to fill space for situations when other columns don't cover full width. That header has null Content. I added a ControlTemplate Trigger to make border transparent for header without content.
To change Thumb apperance I changed Thumb.Template and made it a flat white rectangle
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
<Grid Margin="{TemplateBinding Padding}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Border x:Name="columnHeaderBorder"
TextBlock.FontWeight="Bold"
TextBlock.Foreground="blue"
BorderThickness="2"
BorderBrush="blue"
Background="white"
Width="{TemplateBinding Width}"
Margin="3,3,3,3"
Padding="3,0,3,0">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Border>
<!--BorderBrush="{Binding VerticalGridLinesBrush, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}"-->
<Thumb x:Name="PART_RightHeaderGripper" Grid.Column="1"
HorizontalAlignment="Right"
Width="6" BorderThickness="0"
Margin="0,3"
BorderBrush="white"
Background="white"
Cursor="SizeWE">
<Thumb.Template>
<ControlTemplate>
<Border Background="{TemplateBinding Background}"></Border>
</ControlTemplate>
</Thumb.Template>
</Thumb>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="Content" Value="{x:Null}">
<!--<Setter Property="BorderBrush" Value="Red" TargetName="columnHeaderBorder"/>-->
<Setter Property="BorderBrush" Value="Transparent" TargetName="columnHeaderBorder"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
// I replaced some StaticResources in a template to make my project compile. please restore them back or copy only modified parts of template
In my application, I need to make the combobox that I am using have rounded corners. I started with the XAML posted in the answer to this question and have made some modifications. I decided I didn't like the way that one looked as much, so I tried to style it and make it look a bit more like the default combobox. Now my combobox looks like this: ,
and when dropped down:
The issue is that when the user places their mouse over the combobox, it looks like this: . If I use Snoop, I can see this info:
It says
that the value of that border background is being set to "#FFBEE6FD", which is the color that shows when the mouse is over the combobox. The value source is "ParentTemplateTrigger". My issue is that I don't know where this border is coming from or why it's getting that value. I have tried to add template triggers with setters to set the background to white, but I don't know where to set the value for this mysterious border.
Here is the XAML for my ComboBox:
<ComboBox x:Name="ScanSizesComboBox"
Style="{StaticResource roundedCornersComboBox}"
Grid.ZIndex="4"
ItemsSource="{Binding ScanSizes}"
SelectedItem="{Binding SelectedScanSize, Mode=TwoWay}"
ToolTip="{Binding (Validation.Errors)[0].ErrorContent}"
Margin="0,10,89,0"
HorizontalAlignment="Right"
Width="61"
Height="26"
VerticalAlignment="Top"
Grid.Row="4">
</ComboBox>
And here is the style:
<Style x:Key="ComboBoxTextBoxStyle" TargetType="{x:Type TextBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Grid>
<Border Name="ComboBoxTextBoxStyleBorder" CornerRadius="2"
BorderThickness="0,1,0,1"
Margin="0,0,1,1"
Background="{TemplateBinding Background}">
<Border.Style>
<Style TargetType="Border">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" Value="White"/>
</Trigger>
</Style.Triggers>
</Style>
</Border.Style>
<ScrollViewer x:Name="PART_ContentHost"/>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="IsReadOnly" Value="True"/>
</Style>
<!--Rounded corners combo box-->
<Style TargetType="{x:Type ComboBox}" x:Key="roundedCornersComboBox">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBox}">
<Border Name="roundedCornerComboBoxBorder" BorderBrush="#CCCCCC" BorderThickness="1" CornerRadius="3" ClipToBounds="True" Background="White">
<Border.Style>
<Style TargetType="Border">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" Value="White"/>
</Trigger>
</Style.Triggers>
</Style>
</Border.Style>
<Canvas>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBox Name="PART_EditableTextBox"
Panel.ZIndex="0"
Style="{StaticResource ComboBoxTextBoxStyle}"
Padding="0,0,0,0"
IsHitTestVisible="False"
Height="{TemplateBinding Height}">
</TextBox>
<ToggleButton Grid.Column="1" Margin="0, 0, 0, 0"
Panel.ZIndex="1"
HorizontalAlignment="Center"
VerticalAlignment="Center"
BorderBrush="Transparent"
Background="Transparent"
Height="{TemplateBinding Height}"
Width="60"
IsChecked="{Binding Path=IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
HorizontalContentAlignment="Right"
ClickMode="Press">
<ToggleButton.Style>
<Style TargetType="ToggleButton">
<Style.Triggers>
<Trigger Property="IsMouseOver"
Value="true">
<Setter Property="Background"
Value="White" />
</Trigger>
</Style.Triggers>
</Style>
</ToggleButton.Style>
<Path Grid.Column="1"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="M 0 0 L 4 4 L 8 0 Z"
Fill="DodgerBlue" />
</ToggleButton>
<ContentPresenter Name="ContentSite"
Cursor="Arrow"
Content="{TemplateBinding SelectionBoxItem}"
ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"
VerticalAlignment="Center"
HorizontalAlignment="Left"
Margin="3,0,0,0">
</ContentPresenter>
<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"
BorderThickness="1"
CornerRadius="5"
Background="White"
BorderBrush="Black"/>
<ScrollViewer Margin="4,6,4,6" SnapsToDevicePixels="True">
<StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained" />
</ScrollViewer>
</Grid>
</Popup>
</Grid>
</Canvas>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Ultimately, I would like for the user to be able to place his/her mouse over the combobox, and have it just look the same as it does when it is not highlighted. Any help is appreciated. Thanks.
Continuing from our comments conversation (which generally SO tries to avoid so much noise) this may get on you track.
So if I grab just all the template stuff to a bare bones basic default ComboBox and ComboBoxItem from a fresh WPF app, this is the output. Granted you won't need all of it, but it should ensure to an extent all expected functionality and DOM parts are here for reference so you have all the stuff like Triggers, Template Binding pieces etc, all available.
Notice the various Border and Rectangle elements in the various parts that would need to be altered in order to achieve the rounding of everything. I can't however provide any insight into how it would effect anything with MahApps as my experience with that is pretty limited since I've always just made my own stuff to accomplish what it essentially does.
Hope it helps. It's too long for SO's submission requirements though so here's the PasteBin link.
<Style x:Key="ComboBoxTextBoxStyle" TargetType="{x:Type TextBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Grid>
<Border CornerRadius="5,0,0,5"
BorderThickness="1"
Background="{TemplateBinding Background}"
BorderBrush="Black">
<ScrollViewer x:Name="PART_ContentHost"/>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type ComboBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBox}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition MaxWidth="18"/>
</Grid.ColumnDefinitions>
<TextBox Name="PART_EditableTextBox"
Style="{StaticResource ComboBoxTextBoxStyle}"
Padding="5,0,0,0"
Height="{TemplateBinding Height}"/>
<ToggleButton Grid.Column="1" Margin="0"
Height="{TemplateBinding Height}"
Style="{StaticResource ComboBoxButtonStyle}"
Focusable="False"
IsChecked="{Binding Path=IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
ClickMode="Press">
<Path Grid.Column="1"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="M 0 0 L 4 4 L 8 0 Z"
Fill="DodgerBlue" />
</ToggleButton>
<ContentPresenter Name="ContentSite"
Content="{TemplateBinding SelectionBoxItem}"
ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"
VerticalAlignment="Center"
HorizontalAlignment="Left"
Margin="5,0,0,0"/>
<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"
BorderThickness="1"
CornerRadius="5"
Background="Azure"
BorderBrush="Black"/>
<ScrollViewer Margin="4,6,4,6" SnapsToDevicePixels="True">
<StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained" />
</ScrollViewer>
</Grid>
</Popup>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
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>
<Style x:Key="FavouriteMenuItemStyle" TargetType="{x:Type MenuItem}" BasedOn="{StaticResource BasicFavouriteItemStyle}">
<Setter Property="Width" Value="Auto"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type MenuItem}">
<Grid>
<ToggleButton x:Name="Bd"
Content="{Binding Header}"
Style="{StaticResource FolderButtonStyle}"
Height="{TemplateBinding Height}"
Width="{TemplateBinding Width}"
Margin="{TemplateBinding Margin}"
Padding="{TemplateBinding Padding}"
Focusable="False"/>
<Popup x:Name="PopupMenu"
IsOpen="False"
Placement="Bottom"
PopupAnimation="{DynamicResource {x:Static SystemParameters.MenuPopupAnimationKey}}"
AllowsTransparency="True"
Focusable="False"
StaysOpen="False">
<Border BorderBrush="{StaticResource MpButtonNormalStrokeBrush}"
Background="{StaticResource MpButtonNormalFillBrush}"
BorderThickness="1"
CornerRadius="3"
Padding="4">
<ItemsControl ItemsSource="{Binding Favourites}" ItemTemplate="{StaticResource FavouriteMenuItemDataTemplate}"/>
</Border>
</Popup>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" SourceName="Bd" Value="True">
<Setter Property="IsOpen" TargetName="PopupMenu" Value="True"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I have the following style defined. I would like to bind the Popup's IsOpen property to the ToggleButton's IsChecked property.
I was trying to use FindAncestor to find the grid and work from there, but I wasn't able to get it right. Is there a way to bind these two objects? If so how?
This should work:
IsOpen="{Binding ElementName=Bd, Path=IsChecked}"