I am attempting to create a user control in WPF that allows the user to select specific regions of a shoe (heel, edge, sole etc)
The idea is that you have an image (drawing) of a shoe which you can click on individual parts and select the regions.
I am using a set of check boxes which are templated.
There is a single check box with a path that defines the edge and then a set of rectangles which define the individual areas.
This works well except obviously it doesn't look good. To make it look better I want to hide everything that is not inside the original shoe path.
The rectangles are all on a seperate row in a grid and the background shoe spans all of the rows.
I tried to set the Clip property of the parent grid to the same path as the background shoe edge but got some weird results:
I am pretty sure I am on the right lines with the Grid clipping but I dont understand what is happening here.
If anybody can help with this issue or suggest a better way of doing the same task I would be grateful.
<Geometry x:Key="ShoeEdgeGeometry">M26.25,0.5 C40.471332,0.5 52,17.625107 52,38.75 52,51.292905 47.935695,62.425729 41.656635,69.401079 L41.349452,69.733874 42.012107,70.457698 C45.421829,74.364614 47.5,79.554564 47.5,85.25 47.5,97.400265 38.042015,107.25 26.375,107.25 14.707984,107.25 5.2499995,97.400265 5.2499991,85.25 5.2499995,79.554564 7.3281701,74.364614 10.737891,70.457698 L11.276058,69.869853 10.843364,69.401079 C4.5643053,62.425729 0.49999952,51.292905 0.5,38.75 0.49999952,17.625107 12.028667,0.5 26.25,0.5 z</Geometry>
<Grid Margin="0"
Clip="{StaticResource ShoeEdgeGeometry}">
<Grid.RowDefinitions>
<RowDefinition Height="2*" />
<RowDefinition Height="4*" />
<RowDefinition Height="2*" />
<RowDefinition Height="2*" />
<RowDefinition Height="2*" />
</Grid.RowDefinitions>
<!-- The edge check box-->
<CheckBox x:Name="ShoeEdgeRegion"
Grid.Row="0"
Grid.RowSpan="5">
<CheckBox.Style>
<Style TargetType="CheckBox">
<Setter Property="Cursor"
Value="Hand" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<Grid>
<Path x:Name="MainPath"
Data="{StaticResource ShoeEdgeGeometry}"
Fill="{StaticResource TransparentBrush}"
Stroke="Black"
Stretch="Fill" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked"
Value="True">
<Setter TargetName="MainPath"
Property="Stroke"
Value="{StaticResource RedBrush}" />
</Trigger>
<Trigger Property="IsMouseOver"
Value="True">
<Setter TargetName="MainPath"
Property="Stroke"
Value="{StaticResource RedBrush}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</CheckBox.Style>
</CheckBox>
<!-- The Toe check box-->
<CheckBox x:Name="ShoeToeRegion"
Grid.Row="0">
<CheckBox.Style>
<Style TargetType="CheckBox">
<Setter Property="Cursor"
Value="Hand" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<Grid>
<Rectangle x:Name="MainPath"
StrokeThickness="1"
Fill="{StaticResource TransparentBrush}"
Stroke="Black" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked"
Value="True">
<Setter TargetName="MainPath"
Property="Stroke"
Value="{StaticResource RedBrush}" />
</Trigger>
<Trigger Property="IsMouseOver"
Value="True">
<Setter TargetName="MainPath"
Property="Stroke"
Value="{StaticResource RedBrush}" />
</Trigger>
<Trigger Property="IsChecked"
Value="True">
<Setter TargetName="MainPath"
Property="Fill"
Value="{StaticResource RedBrush}" />
</Trigger>
<Trigger Property="IsMouseOver"
Value="True">
<Setter TargetName="MainPath"
Property="Fill"
Value="{StaticResource RedBrush}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</CheckBox.Style>
</CheckBox>
<!-- The Sole check box-->
<CheckBox x:Name="ShoeSoleRegion"
Grid.Row="1"
Margin="0,-1,0,0">
<CheckBox.Style>
<Style TargetType="CheckBox">
<Setter Property="Cursor"
Value="Hand" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<Grid>
<Rectangle x:Name="MainPath"
StrokeThickness="1"
Fill="{StaticResource TransparentBrush}"
Stroke="Black" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked"
Value="True">
<Setter TargetName="MainPath"
Property="Stroke"
Value="{StaticResource RedBrush}" />
</Trigger>
<Trigger Property="IsMouseOver"
Value="True">
<Setter TargetName="MainPath"
Property="Stroke"
Value="{StaticResource RedBrush}" />
</Trigger>
<Trigger Property="IsChecked"
Value="True">
<Setter TargetName="MainPath"
Property="Fill"
Value="{StaticResource RedBrush}" />
</Trigger>
<Trigger Property="IsMouseOver"
Value="True">
<Setter TargetName="MainPath"
Property="Fill"
Value="{StaticResource RedBrush}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</CheckBox.Style>
</CheckBox>
<!-- The Instep check box-->
<CheckBox x:Name="ShoeInstepRegion"
Margin="0,-1,0,0"
Grid.Row="2">
<CheckBox.Style>
<Style TargetType="CheckBox">
<Setter Property="Cursor"
Value="Hand" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<Grid>
<Rectangle x:Name="MainPath"
StrokeThickness="1"
Fill="{StaticResource TransparentBrush}"
Stroke="Black" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked"
Value="True">
<Setter TargetName="MainPath"
Property="Stroke"
Value="{StaticResource RedBrush}" />
</Trigger>
<Trigger Property="IsMouseOver"
Value="True">
<Setter TargetName="MainPath"
Property="Stroke"
Value="{StaticResource RedBrush}" />
</Trigger>
<Trigger Property="IsChecked"
Value="True">
<Setter TargetName="MainPath"
Property="Fill"
Value="{StaticResource RedBrush}" />
</Trigger>
<Trigger Property="IsMouseOver"
Value="True">
<Setter TargetName="MainPath"
Property="Fill"
Value="{StaticResource RedBrush}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</CheckBox.Style>
</CheckBox>
<!-- The Lower heel check box-->
<CheckBox x:Name="ShoeLowerHeelRegion"
Grid.Row="3"
Margin="0,-1,0,0">
<CheckBox.Style>
<Style TargetType="CheckBox">
<Setter Property="Cursor"
Value="Hand" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<Grid>
<Rectangle x:Name="MainPath"
StrokeThickness="1"
Fill="{StaticResource TransparentBrush}"
Stroke="Black" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked"
Value="True">
<Setter TargetName="MainPath"
Property="Stroke"
Value="{StaticResource RedBrush}" />
</Trigger>
<Trigger Property="IsMouseOver"
Value="True">
<Setter TargetName="MainPath"
Property="Stroke"
Value="{StaticResource RedBrush}" />
</Trigger>
<Trigger Property="IsChecked"
Value="True">
<Setter TargetName="MainPath"
Property="Fill"
Value="{StaticResource RedBrush}" />
</Trigger>
<Trigger Property="IsMouseOver"
Value="True">
<Setter TargetName="MainPath"
Property="Fill"
Value="{StaticResource RedBrush}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</CheckBox.Style>
</CheckBox>
<!-- The heel check box-->
<CheckBox x:Name="ShoeHeelRegion"
Grid.Row="4"
Margin="0,-1,0,0">
<CheckBox.Style>
<Style TargetType="CheckBox">
<Setter Property="Cursor"
Value="Hand" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<Grid>
<Rectangle x:Name="MainPath"
StrokeThickness="1"
Fill="{StaticResource TransparentBrush}"
Stroke="Black" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked"
Value="True">
<Setter TargetName="MainPath"
Property="Stroke"
Value="{StaticResource RedBrush}" />
</Trigger>
<Trigger Property="IsMouseOver"
Value="True">
<Setter TargetName="MainPath"
Property="Stroke"
Value="{StaticResource RedBrush}" />
</Trigger>
<Trigger Property="IsChecked"
Value="True">
<Setter TargetName="MainPath"
Property="Fill"
Value="{StaticResource RedBrush}" />
</Trigger>
<Trigger Property="IsMouseOver"
Value="True">
<Setter TargetName="MainPath"
Property="Fill"
Value="{StaticResource RedBrush}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</CheckBox.Style>
</CheckBox>
</Grid>
DIAGNOSIS
Basing on the code you've provided I've reproduced the issue you described. We'll assume that the grid is of size 100x200. First of all, here's how the grid looks without and with clip set:
Obviously the result is the same. But here's how it looks if we add some background to the grid (red is the background of the grid, and blue is the background "behind" the grid):
Now we can clearly see what happened here - the geometry (roughly of size 50x100) was not automatically scaled to the size of the grid, but rather it's original size was maintained, thus clipping whole lot more that we'd like. Here's how it looks like if we resize the grid to match the size of the geometry:
PRELIMINARIES
In order to make our work a bit easier I've extracted the geometry figure definition to a resource and normalized it so that it is of size 1x1, which will make scaling a lot easier. So here are the resources:
<PathFigureCollection x:Key="ShoeEdgeFigures">
M 0.5048,0
C 0.7783,0 1,0.164 1,0.361 1,0.478 0.9218,0.582 0.8011,0.647
L 0.7952,0.65 0.8079,0.657
C 0.8735,0.693 0.9135,0.742 0.9135,0.795 0.9135,0.908 0.7316,1 0.5072,1
0.2828,1 0.101,0.908 0.101,0.795 0.101,0.742 0.1409,0.693 0.2065,0.657
L 0.2168,0.651 0.2085,0.647
C 0.0878,0.582 0,0.478 0,0.361 0,0.164 0.2313,0 0.5048,0
Z
</PathFigureCollection>
<PathGeometry x:Key="ShoeEdgeGeometry" Figures="{StaticResource ShoeEdgeFigures}" />
SOLUTION
In order to make the grid look as we expect we'll need to scale the geometry - this can be done by means of Geometry.Transform property. I think it is beneficial to define new geometry for that purpose. Then we only need to set ScaleTransform on the geometry with ScaleX and ScaleY equal to the width and height of the grid respectively. That's because the initial size of the geometry is 1x1. Here's the code:
<Grid Width="100" Height="200" (...)>
<Grid.Resources>
<PathGeometry x:Key="StaticClipGeometry" Figures="{StaticResource ShoeEdgeFigures}">
<PathGeometry.Transform>
<ScaleTransform ScaleX="100" ScaleY="200" />
</PathGeometry.Transform>
</PathGeometry>
</Grid.Resources>
<Grid.Clip>
<StaticResource ResourceKey="StaticClipGeometry" />
</Grid.Clip>
(...)
</Grid>
This however is somewhat limiting, because the size of the grid needs to be constant and known at compile-time.
To make the clip geometry adjust to the size of the grid dynamically we'll need to bind the Geometry.Transform property, and because we will bind to both Grid.ActualWidth and Grid.ActualHeight, we are going to need a simple converter:
public class SizeToScaleConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
return new ScaleTransform
{
ScaleX = (double)values[0],
ScaleY = (double)values[1],
};
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Then we define the grid:
<Grid (...)>
<Grid.Resources>
<PathGeometry x:Key="DynamicClipGeometry" Figures="{StaticResource ShoeEdgeFigures}">
<PathGeometry.Transform>
<MultiBinding>
<MultiBinding.Converter>
<local:SizeToScaleConverter />
</MultiBinding.Converter>
<Binding RelativeSource="{RelativeSource AncestorType=Grid}"
Path="ActualWidth" />
<Binding RelativeSource="{RelativeSource AncestorType=Grid}"
Path="ActualHeight" />
</MultiBinding>
</PathGeometry.Transform>
</PathGeometry>
</Grid.Resources>
<Grid.Clip>
<StaticResource ResourceKey="DynamicClipGeometry" />
</Grid.Clip>
(...)
</Grid>
And the end result looks like this:
It seems the Dimensions of your path are quite not fitting, but as an acceptable workaround i'd suggest you to surround your Grid with an ViewBox.
Full Code
<Window.Resources>
<Geometry x:Key="ShoeEdgeGeometry" >
M26.25,0.5 C40.471332,0.5 52,17.625107 52,38.75 52,51.292905 47.935695,62.425729 41.656635,69.401079 L41.349452,69.733874 42.012107,70.457698 C45.421829,74.364614 47.5,79.554564 47.5,85.25 47.5,97.400265 38.042015,107.25 26.375,107.25 14.707984,107.25 5.2499995,97.400265 5.2499991,85.25 5.2499995,79.554564 7.3281701,74.364614 10.737891,70.457698 L11.276058,69.869853 10.843364,69.401079 C4.5643053,62.425729 0.49999952,51.292905 0.5,38.75 0.49999952,17.625107 12.028667,0.5 26.25,0.5 z
</Geometry>
<SolidColorBrush x:Key="RedBrush" Color="Red"></SolidColorBrush>
<SolidColorBrush x:Key="TransparentBrush" Color="Transparent"></SolidColorBrush>
</Window.Resources>
<Viewbox Stretch="Fill">
<Grid Margin="0" Clip="{StaticResource ShoeEdgeGeometry}" >
<Grid.RowDefinitions>
<RowDefinition Height="0.2*" />
<RowDefinition Height="0.4*" />
<RowDefinition Height="0.2*" />
<RowDefinition Height="0.2*" />
<RowDefinition Height="0.2*" />
</Grid.RowDefinitions>
<!-- The edge check box-->
<CheckBox x:Name="ShoeEdgeRegion" Grid.Row="0" Grid.RowSpan="5">
<CheckBox.Style>
<Style TargetType="CheckBox">
<Setter Property="Cursor"
Value="Hand" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<Grid>
<Path x:Name="MainPath"
Data="{StaticResource ShoeEdgeGeometry}"
Fill="{StaticResource TransparentBrush}"
Stroke="Black"
Stretch="Fill" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked"
Value="True">
<Setter TargetName="MainPath"
Property="Stroke"
Value="{StaticResource RedBrush}" />
</Trigger>
<Trigger Property="IsMouseOver"
Value="True">
<Setter TargetName="MainPath"
Property="Stroke"
Value="{StaticResource RedBrush}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</CheckBox.Style>
</CheckBox>
<!-- The Toe check box-->
<CheckBox x:Name="ShoeToeRegion"
Grid.Row="0">
<CheckBox.Style>
<Style TargetType="CheckBox">
<Setter Property="Cursor"
Value="Hand" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<Grid>
<Rectangle x:Name="MainPath"
StrokeThickness="1"
Fill="{StaticResource TransparentBrush}"
Stroke="Black" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked"
Value="True">
<Setter TargetName="MainPath"
Property="Stroke"
Value="{StaticResource RedBrush}" />
</Trigger>
<Trigger Property="IsMouseOver"
Value="True">
<Setter TargetName="MainPath"
Property="Stroke"
Value="{StaticResource RedBrush}" />
</Trigger>
<Trigger Property="IsChecked"
Value="True">
<Setter TargetName="MainPath"
Property="Fill"
Value="{StaticResource RedBrush}" />
</Trigger>
<Trigger Property="IsMouseOver"
Value="True">
<Setter TargetName="MainPath"
Property="Fill"
Value="{StaticResource RedBrush}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</CheckBox.Style>
</CheckBox>
<!-- The Sole check box-->
<CheckBox x:Name="ShoeSoleRegion"
Grid.Row="1"
Margin="0,-1,0,0">
<CheckBox.Style>
<Style TargetType="CheckBox">
<Setter Property="Cursor"
Value="Hand" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<Grid>
<Rectangle x:Name="MainPath"
StrokeThickness="1"
Fill="{StaticResource TransparentBrush}"
Stroke="Black" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked"
Value="True">
<Setter TargetName="MainPath"
Property="Stroke"
Value="{StaticResource RedBrush}" />
</Trigger>
<Trigger Property="IsMouseOver"
Value="True">
<Setter TargetName="MainPath"
Property="Stroke"
Value="{StaticResource RedBrush}" />
</Trigger>
<Trigger Property="IsChecked"
Value="True">
<Setter TargetName="MainPath"
Property="Fill"
Value="{StaticResource RedBrush}" />
</Trigger>
<Trigger Property="IsMouseOver"
Value="True">
<Setter TargetName="MainPath"
Property="Fill"
Value="{StaticResource RedBrush}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</CheckBox.Style>
</CheckBox>
<!-- The Instep check box-->
<CheckBox x:Name="ShoeInstepRegion"
Margin="0,-1,0,0"
Grid.Row="2">
<CheckBox.Style>
<Style TargetType="CheckBox">
<Setter Property="Cursor"
Value="Hand" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<Grid>
<Rectangle x:Name="MainPath"
StrokeThickness="1"
Fill="{StaticResource TransparentBrush}"
Stroke="Black" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked"
Value="True">
<Setter TargetName="MainPath"
Property="Stroke"
Value="{StaticResource RedBrush}" />
</Trigger>
<Trigger Property="IsMouseOver"
Value="True">
<Setter TargetName="MainPath"
Property="Stroke"
Value="{StaticResource RedBrush}" />
</Trigger>
<Trigger Property="IsChecked"
Value="True">
<Setter TargetName="MainPath"
Property="Fill"
Value="{StaticResource RedBrush}" />
</Trigger>
<Trigger Property="IsMouseOver"
Value="True">
<Setter TargetName="MainPath"
Property="Fill"
Value="{StaticResource RedBrush}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</CheckBox.Style>
</CheckBox>
<!-- The Lower heel check box-->
<CheckBox x:Name="ShoeLowerHeelRegion"
Grid.Row="3"
Margin="0,-1,0,0">
<CheckBox.Style>
<Style TargetType="CheckBox">
<Setter Property="Cursor"
Value="Hand" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<Grid>
<Rectangle x:Name="MainPath"
StrokeThickness="1"
Fill="{StaticResource TransparentBrush}"
Stroke="Black" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked"
Value="True">
<Setter TargetName="MainPath"
Property="Stroke"
Value="{StaticResource RedBrush}" />
</Trigger>
<Trigger Property="IsMouseOver"
Value="True">
<Setter TargetName="MainPath"
Property="Stroke"
Value="{StaticResource RedBrush}" />
</Trigger>
<Trigger Property="IsChecked"
Value="True">
<Setter TargetName="MainPath"
Property="Fill"
Value="{StaticResource RedBrush}" />
</Trigger>
<Trigger Property="IsMouseOver"
Value="True">
<Setter TargetName="MainPath"
Property="Fill"
Value="{StaticResource RedBrush}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</CheckBox.Style>
</CheckBox>
<!-- The heel check box-->
<CheckBox x:Name="ShoeHeelRegion"
Grid.Row="4"
Margin="0,-1,0,0">
<CheckBox.Style>
<Style TargetType="CheckBox">
<Setter Property="Cursor"
Value="Hand" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<Grid>
<Rectangle x:Name="MainPath"
StrokeThickness="1"
Fill="{StaticResource TransparentBrush}"
Stroke="Black" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked"
Value="True">
<Setter TargetName="MainPath"
Property="Stroke"
Value="{StaticResource RedBrush}" />
</Trigger>
<Trigger Property="IsMouseOver"
Value="True">
<Setter TargetName="MainPath"
Property="Stroke"
Value="{StaticResource RedBrush}" />
</Trigger>
<Trigger Property="IsChecked"
Value="True">
<Setter TargetName="MainPath"
Property="Fill"
Value="{StaticResource RedBrush}" />
</Trigger>
<Trigger Property="IsMouseOver"
Value="True">
<Setter TargetName="MainPath"
Property="Fill"
Value="{StaticResource RedBrush}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</CheckBox.Style>
</CheckBox>
</Grid>
</Viewbox>
Outcome
Hope this'll work for you
Related
I wanted to add a style to a DataGridCell in my app to have the effect of a watermarked "hint" in case the cell is empty to give the user a hint about what he needs to type in the cell.
<Window.Resources>
<Style x:Key="WatermarkTextBox" TargetType="{x:Type DataGridCell}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Grid>
<Border x:Name="BorderBase" Background="White" BorderThickness="1.4,1.4,1,1" BorderBrush="Red">
<Label x:Name="TextPrompt"
Content="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=Tag}"
Background="{TemplateBinding Background}" Visibility="Visible"
Focusable="False" Foreground="Silver"/>
</Border>
<!--<ScrollViewer Margin="0" x:Name="PART_ContentHost" Foreground="Black"/>-->
</Grid>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsFocused" Value="False"/>
<Condition Property="Content" Value=""/>
</MultiTrigger.Conditions>
<Setter Property="Visibility" TargetName="TextPrompt" Value="Visible"/>
</MultiTrigger>
<Trigger Property="IsFocused" Value="True">
<Setter Property="BorderBrush" TargetName="BorderBase" Value="Black"/>
<Setter Property="Visibility" TargetName="TextPrompt" Value="Collapsed"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="DimGray" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
And this is my code:
Style style = this.FindResource("WatermarkTextBox") as Style;
myCell.Tag = "input position here please";
myCell.Style = style;
And it works fine. When this code is executed, the watermark style is applied correctly. But when I focus on the cell, I cannot write anything.
I mean, the "IsFocused" trigger is executed and the Label is collapsed (it disappears) but I cannot input anything inside the cell.
You are missing a ContentPresenter:
<Style x:Key="WatermarkTextBox" TargetType="{x:Type DataGridCell}">
<Setter Property="Tag" Value="insert" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Grid>
<Border x:Name="BorderBase" Background="White" BorderThickness="1.4,1.4,1,1" BorderBrush="Red">
<Label x:Name="TextPrompt"
Content="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=Tag}"
Background="{TemplateBinding Background}" Visibility="Visible"
Focusable="False" Foreground="Silver"/>
</Border>
<ContentPresenter x:Name="cp" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Grid>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsFocused" Value="False"/>
<Condition Property="Content" Value=""/>
</MultiTrigger.Conditions>
<Setter Property="Visibility" TargetName="TextPrompt" Value="Visible"/>
<Setter Property="Visibility" TargetName="cp" Value="Collapsed"/>
</MultiTrigger>
<Trigger Property="IsFocused" Value="True">
<Setter Property="BorderBrush" TargetName="BorderBase" Value="Black"/>
<Setter Property="Visibility" TargetName="TextPrompt" Value="Collapsed"/>
<Setter Property="Visibility" TargetName="cp" Value="Visible"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="DimGray" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Try This, Updated
<Style x:Key="WatermarkTextBox" TargetType="{x:Type TextBox}">
<Setter Property="FontSize" Value="12" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBoxBase}">
<Grid>
<Border
x:Name="border"
SnapsToDevicePixels="True">
<ScrollViewer
x:Name="PART_ContentHost"
Focusable="False"
HorizontalScrollBarVisibility="Hidden"
VerticalScrollBarVisibility="Hidden" />
</Border>
<TextBlock
x:Name="placeholder"
VerticalAlignment="Center"
IsHitTestVisible="False"
Text="{TemplateBinding Tag}">
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Visibility" Value="Collapsed" />
<Style.Triggers>
<DataTrigger Binding="{Binding Text, RelativeSource={RelativeSource TemplatedParent}}" Value="">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="border" Property="Opacity" Value="0.56" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="border" Property="BorderBrush" Value="#FF7EB4EA" />
</Trigger>
<Trigger Property="IsKeyboardFocused" Value="True">
<Setter TargetName="border" Property="BorderBrush" Value="#FF569DE5" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Usage
<DataGrid.Columns>
<DataGridTemplateColumn Header=" Tags ">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Style="{StaticResource WatermarkTextBox}"
FontSize="12"
VerticalAlignment="Center"
Tag="Stage Name .."
Width="60"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
I am trying to set my property in XAML to have a sunken effect when the button is pressed. I do this by increasing the border thickness.
It gives me an error saying the specific value cannot be assigned. What am I making mistake here?
Note: I tried using the DropShadowEffect and it works but Border effect does not work.
Here is my XAML:
<Style x:Key="DefaultLanguageButtonStyle" TargetType="{x:Type Button}" > <!--BasedOn="{StaticResource DefaultButton}" >-->
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="border" BorderThickness="0" BorderBrush="DarkGray" Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="border" Property="BorderBrush" Value="Black" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Effect">
<Setter.Value>
<Border BorderThickness="5,5,0,0" >
</Border>
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="FontSize" Value="30" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Foreground" Value="{DynamicResource RedBrush}" />
<Setter Property="Background" Value="{DynamicResource WhiteBrush}" />
<Setter Property="BorderThickness" Value="{DynamicResource NoBorder}" />
<Setter Property="Height" Value="100" />
</Style>
Why not have your trigger like this:
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="border" Property="BorderThickness" Value="5,5,0,0"/>
<Setter TargetName="border" Property="Effect" Value="..."/>
</Trigger>
EDIT:
Here is a short example where I change the BorderThickness of a Border within a ControlTemplate through Triggers:
<Button>
<Button.Template>
<ControlTemplate TargetType="Button">
<Border x:Name="Border" BorderBrush="HotPink" BorderThickness="0" Background="Aqua" Width="50" Height="50"/>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="Border" Property="BorderThickness" Value="20"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
</Button>
Excuse the shoddy proportions on those images.
Define style in resources:
<Style TargetType="Button" x:Key="SunkenEffectStyle">
<Style.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<ThicknessAnimationUsingKeyFrames Storyboard.TargetProperty="BorderThickness" BeginTime="00:00:00">
<SplineThicknessKeyFrame KeyTime="00:00:01" Value="10,10,0,0" />
<SplineThicknessKeyFrame KeyTime="00:00:03" Value="0,0,0,0" />
</ThicknessAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
</Style>
Usage:
<Button Content="Click Me" Style="{StaticResource SunkenEffectStyle}"
Height="50" Width="100"/>
this answer also covers your previous question here
i have used keyframes here since you wanted animation to be faster at start and slower while returning
i want to change color of thumb/scrollbox from RichTextBox.
I'm using, but it doesn't changes color of thumb
<RichTextBox x:Name="richTextBox" HorizontalAlignment="Left" Height="285" VerticalAlignment="Top" Width="880" VerticalScrollBarVisibility="Visible" IsReadOnly="True" Foreground="#FFA02626" Background="{x:Null}">
<RichTextBox.Resources>
<Style TargetType="ScrollBar">
<Setter Property="Foreground" Value="Red"/>
</Style>
</RichTextBox.Resources>
</RichTextBox>
I don't find any easy way to do this. But you can define your custom ScrollBar style.
Here is my example I just wrote. It's look so ugly because I'm going to bed.
<RichTextBox>
<RichTextBox.Resources>
<Style x:Key="ScrollThumb" TargetType="{x:Type Thumb}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
<Rectangle x:Name="Rectangle1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Fill="Transparent" SnapsToDevicePixels="True"/>
<ControlTemplate.Triggers>
<Trigger Property="Tag" Value="Horizontal">
<Setter TargetName="Rectangle1" Property="Width" Value="Auto" />
<Setter TargetName="Rectangle1" Property="Height" Value="7" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="{x:Type ScrollBar}" TargetType="{x:Type ScrollBar}">
<Setter Property="Stylus.IsFlicksEnabled" Value="false" />
<Setter Property="Foreground" Value="Red" />
<Setter Property="Background" Value="DarkGray" />
<Setter Property="Width" Value="10" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ScrollBar}">
<Grid x:Name="GridRoot" Width="19" Background="{TemplateBinding Background}">
<Grid.RowDefinitions>
<RowDefinition Height="0.00001*" />
</Grid.RowDefinitions>
<Track x:Name="PART_Track" Grid.Row="0" IsDirectionReversed="true" Focusable="false">
<Track.Thumb>
<Thumb x:Name="Thumb" Background="{TemplateBinding Foreground}" Style="{DynamicResource ScrollThumbs}" />
</Track.Thumb>
<Track.IncreaseRepeatButton>
<RepeatButton x:Name="PageUp" Command="ScrollBar.PageDownCommand" Opacity="0" Focusable="false" />
</Track.IncreaseRepeatButton>
<Track.DecreaseRepeatButton>
<RepeatButton x:Name="PageDown" Command="ScrollBar.PageUpCommand" Opacity="0" Focusable="false" />
</Track.DecreaseRepeatButton>
</Track>
</Grid>
<ControlTemplate.Triggers>
<Trigger SourceName="Thumb" Property="IsMouseOver" Value="true">
<Setter Value="{DynamicResource ButtonSelectBrush}" TargetName="Thumb" Property="Background" />
</Trigger>
<Trigger SourceName="Thumb" Property="IsDragging" Value="true">
<Setter Value="{DynamicResource DarkBrush}" TargetName="Thumb" Property="Background" />
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter TargetName="Thumb" Property="Visibility" Value="Collapsed" />
</Trigger>
<Trigger Property="Orientation" Value="Horizontal">
<Setter TargetName="GridRoot" Property="LayoutTransform">
<Setter.Value>
<RotateTransform Angle="-90" />
</Setter.Value>
</Setter>
<Setter TargetName="PART_Track" Property="LayoutTransform">
<Setter.Value>
<RotateTransform Angle="-90" />
</Setter.Value>
</Setter>
<Setter Property="Width" Value="Auto" />
<Setter Property="Height" Value="12" />
<Setter TargetName="Thumb" Property="Tag" Value="Horizontal" />
<Setter TargetName="PageDown" Property="Command" Value="ScrollBar.PageLeftCommand" />
<Setter TargetName="PageUp" Property="Command" Value="ScrollBar.PageRightCommand" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</RichTextBox.Resources>
</RichTextBox>
You can improve it follow MS guide here : https://msdn.microsoft.com/en-us/library/ms742173(v=vs.110).aspx
Or here: https://www.google.com
I need to create a tab like below.
Using the code as follows i am getting some what near.
<TabControl Margin="-2,0,0,0" Background="#37e8f9" BorderBrush="Red" BorderThickness="0" TabStripPlacement="Left" HorizontalAlignment="Left" Width="261" >
<TabControl.Resources>
<Style TargetType="TabItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TabItem">
<Grid VerticalAlignment="Center" HorizontalAlignment="Center">
<Border Name="Border" BorderThickness="1" BorderBrush="Transparent" CornerRadius="5,0,0,5" Margin="10,0,-1,0" >
<ContentPresenter x:Name="ContentSite"
VerticalAlignment="Center"
HorizontalAlignment="Center"
ContentSource="Header" Width="100" TextBlock.TextAlignment="Center" TextBlock.LineHeight="100" TextBlock.LineStackingStrategy="BlockLineHeight" MaxHeight="100"
/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Foreground" Value="#805e00" />
<Setter Property="FontSize" Value="14" />
<Setter Property="Padding" Value="12,10"/>
<Setter TargetName="Border" Property="Background" Value="#37e8f9" />
</Trigger>
<Trigger Property="IsSelected" Value="False">
<Setter Property="Foreground" Value="Red" />
<Setter Property="FontSize" Value="14" />
<Setter Property="Padding" Value="12,10"/>
<Setter Property="Background" Value="Red" />
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True" />
<Condition Property="IsSelected" Value="False" />
</MultiTrigger.Conditions>
<Setter TargetName="Border" Property="BorderBrush" Value="White" />
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</TabControl.Resources>
<TabItem Header="Tab 1" />
<TabItem Header="Tab 2" />
<TabItem Header="Tab 3" />
And the output is as follows.
Now if i add image the tab header area becomes un clickable over the image and throughout the header; except for the header text which is clickable. How do I make the entire header area clickable with image and text inside it?
Thanks in advance.
Try this Style :
<Style TargetType="TabItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TabItem">
<Grid VerticalAlignment="Center" HorizontalAlignment="Center">
<Border Name="Border" BorderThickness="1" BorderBrush="Transparent" CornerRadius="5,0,0,5" Margin="10,0,-1,0" >
<StackPanel>
<Image Source="Image_Source"/>
<ContentPresenter x:Name="ContentSite"
VerticalAlignment="Center"
HorizontalAlignment="Center"
ContentSource="Header" TextBlock.TextAlignment="Center" TextBlock.LineStackingStrategy="BlockLineHeight"
/>
</StackPanel>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Foreground" Value="#805e00" />
<Setter Property="FontSize" Value="14" />
<Setter Property="Padding" Value="12,10"/>
<Setter TargetName="Border" Property="Background" Value="#37e8f9" />
</Trigger>
<Trigger Property="IsSelected" Value="False">
<Setter Property="Foreground" Value="Red" />
<Setter Property="FontSize" Value="14" />
<Setter Property="Padding" Value="12,10"/>
<Setter Property="Background" Value="Red" />
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True" />
<Condition Property="IsSelected" Value="False" />
</MultiTrigger.Conditions>
<Setter TargetName="Border" Property="BorderBrush" Value="White" />
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I have a following problem: I have two treeview controls in my WPF app and when I click on one of the items in first tree and then click on one of the items in second tree, then the item in first tree changes it backgroud color. I tried to change the background color in the multitrigger
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true"/>
<Condition Property="IsSelectionActive" Value="false"/>
</MultiTrigger.Conditions>
for template property but with no effect. How can I disable this behaviour ? Here Is my sample window code(Im not changing the treeview control in code behind)
<Window x:Class="StackOverflowTests.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<SolidColorBrush x:Key="ListBorder" Color="#828790"/>
<Style x:Key="TreeViewStyle1" TargetType="{x:Type TreeView}">
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
<Setter Property="BorderBrush" Value="{StaticResource ListBorder}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.PanningMode" Value="Both"/>
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TreeView}">
<Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels="true">
<ScrollViewer x:Name="_tv_scrollviewer_" Background="{TemplateBinding Background}" CanContentScroll="false" Focusable="false" HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}">
<ItemsPresenter/>
</ScrollViewer>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
</Trigger>
<Trigger Property="VirtualizingPanel.IsVirtualizing" Value="true">
<Setter Property="CanContentScroll" TargetName="_tv_scrollviewer_" Value="true"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="VirtualizingPanel.IsVirtualizing" Value="true">
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<VirtualizingStackPanel/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="TreeViewItemFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<SolidColorBrush x:Key="TreeViewItem.TreeArrow.Static.Checked.Fill" Color="#FF595959"/>
<SolidColorBrush x:Key="TreeViewItem.TreeArrow.Static.Checked.Stroke" Color="#FF262626"/>
<SolidColorBrush x:Key="TreeViewItem.TreeArrow.MouseOver.Stroke" Color="#FF1BBBFA"/>
<SolidColorBrush x:Key="TreeViewItem.TreeArrow.MouseOver.Fill" Color="Transparent"/>
<SolidColorBrush x:Key="TreeViewItem.TreeArrow.MouseOver.Checked.Stroke" Color="#FF262626"/>
<SolidColorBrush x:Key="TreeViewItem.TreeArrow.MouseOver.Checked.Fill" Color="#FF595959"/>
<PathGeometry x:Key="TreeArrow" Figures="M0,0 L0,6 L6,0 z"/>
<SolidColorBrush x:Key="TreeViewItem.TreeArrow.Static.Fill" Color="Transparent"/>
<SolidColorBrush x:Key="TreeViewItem.TreeArrow.Static.Stroke" Color="#FF989898"/>
<Style x:Key="ExpandCollapseToggleStyle" TargetType="{x:Type ToggleButton}">
<Setter Property="Focusable" Value="False"/>
<Setter Property="Width" Value="16"/>
<Setter Property="Height" Value="16"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border Background="Transparent" Height="16" Padding="5,5,5,5" Width="16">
<Path x:Name="ExpandPath" Data="{StaticResource TreeArrow}" Fill="{StaticResource TreeViewItem.TreeArrow.Static.Fill}" Stroke="{StaticResource TreeViewItem.TreeArrow.Static.Stroke}">
<Path.RenderTransform>
<RotateTransform Angle="135" CenterY="3" CenterX="3"/>
</Path.RenderTransform>
</Path>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="RenderTransform" TargetName="ExpandPath">
<Setter.Value>
<RotateTransform Angle="180" CenterY="3" CenterX="3"/>
</Setter.Value>
</Setter>
<Setter Property="Fill" TargetName="ExpandPath" Value="{StaticResource TreeViewItem.TreeArrow.Static.Checked.Fill}"/>
<Setter Property="Stroke" TargetName="ExpandPath" Value="{StaticResource TreeViewItem.TreeArrow.Static.Checked.Stroke}"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Stroke" TargetName="ExpandPath" Value="{StaticResource TreeViewItem.TreeArrow.MouseOver.Stroke}"/>
<Setter Property="Fill" TargetName="ExpandPath" Value="{StaticResource TreeViewItem.TreeArrow.MouseOver.Fill}"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True"/>
<Condition Property="IsChecked" Value="True"/>
</MultiTrigger.Conditions>
<Setter Property="Stroke" TargetName="ExpandPath" Value="{StaticResource TreeViewItem.TreeArrow.MouseOver.Checked.Stroke}"/>
<Setter Property="Fill" TargetName="ExpandPath" Value="{StaticResource TreeViewItem.TreeArrow.MouseOver.Checked.Fill}"/>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="TreeViewItemStyle1" TargetType="{x:Type TreeViewItem}">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
<Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
<Setter Property="Padding" Value="1,0,0,0"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="FocusVisualStyle" Value="{StaticResource TreeViewItemFocusVisual}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TreeViewItem}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="19" Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<ToggleButton x:Name="Expander" ClickMode="Press" IsChecked="{Binding IsExpanded, RelativeSource={RelativeSource TemplatedParent}}" Style="{DynamicResource ToggleButtonStyle1}"/>
<Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.Column="1" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
<ContentPresenter x:Name="PART_Header" ContentSource="Header" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
<ItemsPresenter x:Name="ItemsHost" Grid.ColumnSpan="2" Grid.Column="1" Grid.Row="1"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="false">
<Setter Property="Visibility" TargetName="ItemsHost" Value="Collapsed"/>
</Trigger>
<Trigger Property="HasItems" Value="false">
<Setter Property="Visibility" TargetName="Expander" Value="Hidden"/>
</Trigger>
<Trigger Property="IsSelected" Value="true">
<Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true"/>
<Condition Property="IsSelectionActive" Value="false"/>
</MultiTrigger.Conditions>
<Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
</MultiTrigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="VirtualizingPanel.IsVirtualizing" Value="true">
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<VirtualizingStackPanel/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="ToggleButtonStyle1" TargetType="{x:Type ToggleButton}">
<Setter Property="Focusable" Value="False"/>
<Setter Property="Width" Value="16"/>
<Setter Property="Height" Value="16"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border Background="Transparent" Height="16" Padding="5,5,5,5" Width="16">
<Path x:Name="ExpandPath" Data="{StaticResource TreeArrow}" Fill="{DynamicResource {x:Static SystemColors.HotTrackBrushKey}}" Stroke="{StaticResource TreeViewItem.TreeArrow.Static.Stroke}">
<Path.RenderTransform>
<RotateTransform Angle="135" CenterY="3" CenterX="3"/>
</Path.RenderTransform>
</Path>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="RenderTransform" TargetName="ExpandPath">
<Setter.Value>
<RotateTransform Angle="180" CenterY="3" CenterX="3"/>
</Setter.Value>
</Setter>
<Setter Property="Fill" TargetName="ExpandPath" Value="{StaticResource TreeViewItem.TreeArrow.Static.Checked.Fill}"/>
<Setter Property="Stroke" TargetName="ExpandPath" Value="{StaticResource TreeViewItem.TreeArrow.Static.Checked.Stroke}"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Stroke" TargetName="ExpandPath" Value="{StaticResource TreeViewItem.TreeArrow.MouseOver.Stroke}"/>
<Setter Property="Fill" TargetName="ExpandPath" Value="{StaticResource TreeViewItem.TreeArrow.MouseOver.Fill}"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True"/>
<Condition Property="IsChecked" Value="True"/>
</MultiTrigger.Conditions>
<Setter Property="Stroke" TargetName="ExpandPath" Value="{StaticResource TreeViewItem.TreeArrow.MouseOver.Checked.Stroke}"/>
<Setter Property="Fill" TargetName="ExpandPath" Value="{StaticResource TreeViewItem.TreeArrow.MouseOver.Checked.Fill}"/>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<StackPanel Orientation="Horizontal">
<TreeView x:Name="XX" HorizontalAlignment="Left" Height="100" VerticalAlignment="Top" Width="100" Style="{DynamicResource TreeViewStyle1}" Background="#7B898C">
<TreeViewItem Header="XXXX_1" Style="{StaticResource TreeViewItemStyle1}">
<TreeViewItem Header="XXXX_2" HorizontalAlignment="Left" />
</TreeViewItem>
</TreeView>
<TreeView x:Name="XX2" Margin="10,0,0,0" HorizontalAlignment="Left" Height="100" VerticalAlignment="Top" Width="100" Style="{DynamicResource TreeViewStyle1}" Background="#7B898C">
<TreeViewItem Header="XXXX_3" Style="{StaticResource TreeViewItemStyle1}">
<TreeViewItem Header="XXXX_4" HorizontalAlignment="Left" />
</TreeViewItem>
</TreeView>
</StackPanel>
</Grid>
Only thing I can see wrong in the code you've posted is your Trigger's Setter sets both Background and Foreground to the same color {DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}
You could also maybe try setting the MultiTrigger condition as Selector.IsSelectionActive to be explicit:
I tried your posted code with these changes (Works fine for me in Windows-8):
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected"
Value="true" />
<Condition Property="Selector.IsSelectionActive"
Value="false" />
</MultiTrigger.Conditions>
<Setter TargetName="Bd"
Property="Background"
Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" />
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}" />
</MultiTrigger>
Output:
Note:
Your only setting Style for the Top TreeViewItem as TreeViewItemStyle1. Hence the default Style gets applied to the Child TreeViewItem's which don't specify a Style. If you want it to apply automatically to all TreeViewItem's just remove the Style Key in declaration and it should be applied automatically based on the TargetType