Style expander buttons of TreeView - wpf

Here is my XAML:
<Style x:Key="ExpanderStyle" TargetType="{x:Type ToggleButton}">
<Setter Property="IsEnabled" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Image Source="/Images/SHCalendarLeftArrow.tiff" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
So what I want is so that if the item is expanded, then display a different image.

Nevermind. I used a trigger
<Trigger Property="ToggleButton.IsChecked" Value="False">
<Setter x:Name="Expander_Expanded"
TargetName="Expander_Normal" Property="Source"
Value="/Images/SHCalendarLeftArrow.tiff" />
</Trigger>

Related

How to set a border around listviewitem in WPF

My ListView should have following style:
no border around the whole ListView (achieved)
no highlighting when interacting with ListViewItem (achieved)
border around selected ListViewItem (missing)
My ListView:
<ListView DisplayMemberPath="Name" BorderThickness="0" >
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<!-- get rid of the highlighting -->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<ContentPresenter />
</ControlTemplate>
</Setter.Value>
</Setter>
<!-- style selected item -->
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="FontSize" Value="20" />
<Setter Property="FontWeight" Value="Bold" />
</Trigger>
</Style.Triggers>
</Style>
</ListView.ItemContainerStyle>
</ListView>
I tried this and this, both doesn't work for me. I guess my problem is the template but I have no idea how to put a border around the selected ListViewItem.
Update
Working solution:
<ListView DisplayMemberPath="Name" BorderThickness="0" >
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<!-- get rid of the highlighting -->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<Border x:Name="Border">
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="FontSize" Value="20" />
<Setter Property="FontWeight" Value="Bold" />
<Setter TargetName="Border" Property="BorderBrush" Value="Black"/>
<Setter TargetName="Border" Property="BorderThickness" Value="2"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
</ListView>
Maybe this works. Add a Border around ContentPresenter an use controlTemplate Triggers
<ControlTemplate TargetType="{x:Type ListViewItem}">
<Border x:Name="Border">
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="FontSize" Value="20" />
<Setter Property="FontWeight" Value="Bold" />
<Setter TargetName="Border" Property="BorderBrush" Value="Red"/>
<Setter TargetName="Border" Property="BorderThickness" Value="1"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>

WPF Datagrid Selected Row Color and Centered Text

I have a simple DataGrid where I want to Style the selected row and center the text. I have tried the following and it does not work:
<DataGrid.CellStyle>
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center" />
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="Blue" />
<Setter Property="Foreground" Value="White" />
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.CellStyle>
Why will the above not work together? If I remove the trigger, it will center but the color I want will not be used.
Try add Grid to the ControlTemplate of DataGridCell style:
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Grid Background="{TemplateBinding Background}">
<ContentPresenter Margin="2"
VerticalAlignment="Center"
HorizontalAlignment="Center" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Foreground" Value="White" />
<Setter Property="Background" Value="Blue" />
</Trigger>
</Style.Triggers>
</Style>

How to set a global style to XAML buttons that have exisiting control templates

I'm attempting to create a global style so that the mouse cursor will change to a hand when mouseover on any button in the app. However, my buttons have their own control templates that use the IsMouseOver trigger so my global IsMouseOver trigger isn't working. Is there any way to get around this without having to add the setter for the trigger to every button style?
Here is the global style:
<Style TargetType="{x:Type Button}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Cursor" Value="Hand"/>
</Trigger>
</Style.Triggers>
</Style>
And here is a button:
<Style x:Key="VideoVolumeButtonBaseStyle" TargetType="{x:Type Button}">
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Foreground" Value="{StaticResource DefaultColorBrush}"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="Height" Value="27"/>
<Setter Property="Width" Value="31"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="ContentBorder" CornerRadius="3" Background="Transparent" BorderBrush="Transparent" BorderThickness="2">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
<ContentPresenter Name="contentPresenter" Content="{TemplateBinding Content}" VerticalAlignment="Center" HorizontalAlignment="Left"/>
</StackPanel>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsDefaulted" Value="true"/>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Foreground" Value="{StaticResource FocusedColorBrush}"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Foreground" Value="{StaticResource FocusedColorBrush}"/>
<Setter Property="Margin" Value="1,-2,0,0" TargetName="contentPresenter"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{StaticResource DisabledColorBrush}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
You can just use the Style.BasedOn property to base your later Styles on your global Style:
<Style x:Key="GlobalStyle" TargetType="{x:Type Button}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Cursor" Value="Hand"/>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="ButtonStyle" TargetType="{x:Type Button}"
BasedOn="{StaticResource GlobalStyle}">
...
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
...
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
If you don't want to name your global Style, you can simply base it on this named Style:
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource GlobalStyle}" />

WPF buttons (image & label) shadowing

I want to create buttons which have a image and a text included and get a nice shadowing. Particularly, I want the image and label have a light grey shadowing, but when moving the mouse over the button I'd like a kind of blue shadowing. Moving away sets it back to light grey. I would need some help as I just can't figure out how to achive it (I'm new to WPF).
The Buttons looks like ...
<Button>
<Button.Content>
<StackPanel Orientation="Vertical">
<Image Source="Images/preferences-system.png" />
<Label HorizontalAlignment="Center">Settings</Label>
</StackPanel>
</Button.Content>
</Button>
The Canvas goes ...
<Canvas DockPanel.Dock="Left" Background="#FF349EBC">
<Canvas.Resources>
<DropShadowEffect x:Key="dropMouseOverShadow" Color="#FFD9EDF3" Opacity="80" Direction="270" />
<DropShadowEffect x:Key="dropLightShadow" Color="LightGrey" Opacity="10" Direction="270" BlurRadius="20" />
<Style TargetType="{x:Type Button}">
<Style.Setters>
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Foreground" Value="{x:Null}" />
<Setter Property="BorderBrush" Value="{x:Null}" />
<Setter Property="Background" Value="{x:Null}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}" CornerRadius="2">
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Effect" Value="{StaticResource dropMouseOverShadow}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style.Setters>
</Style>
<Style TargetType="{x:Type Image}">
<Style.Setters>
<Setter Property="Effect" Value="{StaticResource dropLightShadow}" />
</Style.Setters>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Effect" Value="{x:Null}" />
</Trigger>
</Style.Triggers>
</Style>
<Style TargetType="{x:Type Label}">
<Style.Setters>
<Setter Property="FontSize" Value="18" />
<Setter Property="FontWeight" Value="Normal" />
<Setter Property="FontFamily" Value="Gill Sans MT" />
<Setter Property="Effect" Value="{StaticResource dropLightShadow}" />
</Style.Setters>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Effect" Value="{x:Null}" />
</Trigger>
</Style.Triggers>
</Style>
</Canvas.Resources>
What I get is a light grey shadowing on image and labels on begin. Moving the mouse over the button the grey and light blue get mixed. When moving further on the image it gets the light blue only. The same goes for the label.
How can I achive switching the shadowning to light blue when I mouse over the button and not the image and label itself? Anyone an idea or an completly other approach?
Apply the LightGray Effect to the ContentPresenter. Then on the IsMouseOver Trigger, set the Effect property of the ContentPresenter to the blue Effect.
NOTE: Accomplish this by setting the x:Name attribute of the ContentPresenter, then accessing the ContentPresenter by name via the Setter using TargetName.
NOTE: Remove the various other Effect settings in the styles of the child elements. Applying the Effect to the ContentPresenter causes the child elements to inherit the Effect.
<Canvas DockPanel.Dock="Left" Background="#FF349EBC">
<Canvas.Resources>
<DropShadowEffect x:Key="dropMouseOverShadow" Color="#FFD9EDF3" Opacity="80" Direction="270" />
<DropShadowEffect x:Key="dropLightShadow" Color="LightGrey" Opacity="10" Direction="270" BlurRadius="20" />
<Style TargetType="{x:Type Button}">
<Style.Setters>
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Foreground" Value="{x:Null}" />
<Setter Property="BorderBrush" Value="{x:Null}" />
<Setter Property="Background" Value="{x:Null}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}" CornerRadius="2">
<ContentPresenter x:Name="cp" Effect="{StaticResource dropLightShadow}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="cp" Property="Effect" Value="{StaticResource dropMouseOverShadow}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style.Setters>
</Style>
<Style TargetType="{x:Type Label}">
<Style.Setters>
<Setter Property="FontSize" Value="18" />
<Setter Property="FontWeight" Value="Normal" />
<Setter Property="FontFamily" Value="Gill Sans MT" />
</Style.Setters>
</Style>

Change Image OnMouseOver in ControlTemplate

Here is my XAML:
<Style x:Key="ExpanderStyle" TargetType="{x:Type ToggleButton}">
<Setter Property="IsEnabled" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Image Source="/Images/SHCalendarLeftArrow.tiff" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
So how can I add a Trigger to that OnMouseOver the image in the ControlTemplate changes to a different image.
Try using a Trigger inside your template:
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Image x:Name="PART_img" Source="/Images/SHCalendarLeftArrow.tiff" />
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="PART_img"
Property="Source"
Value="/Images/SomeOtherImage.tiff" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>

Resources