Access Element in ControlTemplate from Style - c#

I want to Style an Border inside a ControlTemplate. But I don't know how to access it. My Style looks like this:
<Style x:Key="RedCell" TargetType="DataGridCell" BasedOn="{StaticResource MYDGCellStyle}">
<Setter Property="Foreground" Value="White" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="DataGridCell">
<Grid>
<Grid Grid.ZIndex="86" x:Name="CellContenGrind" Background="{TemplateBinding Background}" />
<Border Grid.ZIndex="87" x:Name="ContentBorder" BorderBrush="White" Background="Crimson" CornerRadius="25">
<ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<Grid Grid.ZIndex="88" x:Name="CellGridFocused"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter Property="Background" TargetName="CellGridFocused" Value="{DynamicResource Brush_DataGridCellFocused}" />
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" TargetName="CellContenGrind" Value="{DynamicResource Brush_DataGridSelected}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding ungelesen}" Value="0">
<Setter Property="Background" Value="Green"/>
</DataTrigger>
</Style.Triggers>
</Style>
I need the Background="{TemplateBinding Background}" on my CellContentGrind because of some other stuff, so I can't just move that to my Border.
If ungelesen = 0, I want the Background of my ContentBorder to be Green. How can I do that?

Why not move the Style to the Border itself?
<Border Grid.ZIndex="87"x:Name="ContentBorder" BorderBrush="White" CornerRadius="25">
<Border.Style>
<Style TargetType="Border">
<Setter Property="Background" Value="Crimson" />
<Style.Triggers>
<DataTrigger Binding="{Binding ungelesen}" Value="0">
<Setter Property="Background" Value="Green"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
<ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
Note that Background is set with Setter now to make overridable with DataTrigger.

Related

WPF C# ListBox IsMouseOver and IsSelected background

I am have made the following usercontrol, and all works well except the 2 Background setter properties with value transparent for both isMouseOver and IsSelected that do nothing..
<UserControl.Resources>
<DataTemplate x:Key="DeviceItemTemplate">
<Border Padding="10,5" Margin="10" BorderThickness="4" BorderBrush="Green" CornerRadius="20" Height="150" Width="150">
<StackPanel Orientation="Vertical">
<TextBox Name="screenNameTextBox"
Margin="10" Height="20"
Text="{Binding Name}" />
<TextBox
Margin="10" Height="20"
Text="{Binding Location}" />
</StackPanel>
</Border>
</DataTemplate>
<DataTemplate x:Key="DeviceItemTemplateSelected">
<Border Padding="10,5" Margin="10" BorderThickness="4" BorderBrush="Orange" CornerRadius="20" Height="150" Width="150" >
<StackPanel Orientation="Vertical" >
<TextBox Name="screenNameTextBox"
Margin="10" Height="20"
Text="{Binding Name}" />
<TextBox
Margin="10" Height="20"
Text="{Binding Location}" />
</StackPanel>
</Border>
</DataTemplate>
<Style TargetType="{x:Type ListBoxItem}" x:Key="DeviceContainerStyle">
<Setter Property="ContentTemplate" Value="{DynamicResource DeviceItemTemplate}"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True" >
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Background" Value="Transparent" />
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter Property="ContentTemplate" Value="{DynamicResource DeviceItemTemplateSelected}"/>
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Background" Value="Transparent" />
</Trigger>
</Style.Triggers>
</Style>
</UserControl.Resources>
<Border
Grid.Column="0"
Margin="10"
BorderBrush="Silver"
BorderThickness="1">
<ListBox ItemsSource="{Binding Devices, UpdateSourceTrigger=PropertyChanged}"
SelectedItem="{Binding SelectedScreen, Mode=TwoWay}"
ItemContainerStyle="{StaticResource DeviceContainerStyle}"
ScrollViewer.HorizontalScrollBarVisibility="Disabled" >
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel IsItemsHost="True" Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
</Border>
This is how it looks
I also tried white, but got same results. I cannot get rid of this blue background.
What am I overlooking please?
-----After receiving mm8 answer-----
Placed all his code in a resource dictionary, made some changes to the solidcolorbrush and BorderThickness, and modified the style section from previous to:
<Style BasedOn="{StaticResource ListBoxItemSSDS}" TargetType="{x:Type ListBoxItem}" x:Key="DeviceContainerStyle">
<Setter Property="ContentTemplate" Value="{DynamicResource DeviceItemTemplate}"/>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="ContentTemplate" Value="{DynamicResource DeviceItemTemplateSelected}"/>
</Trigger>
</Style.Triggers>
</Style>
You need to define a custom ControlTemplate for the ListBoxItem to be able to the background of it when the IsMouseOver and IsSelected properties are set.
You can right-click on a ListBoxItem in design mode in Visual Studio or in Blend and choose Edit Template->Edit a Copy to copy the default template into your XAML markup and then edit it as per your requirements.
Here is what it looks like and the resources that are involved:
<Style x:Key="FocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="2" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<SolidColorBrush x:Key="Item.MouseOver.Background" Color="#1F26A0DA"/>
<SolidColorBrush x:Key="Item.MouseOver.Border" Color="#a826A0Da"/>
<SolidColorBrush x:Key="Item.SelectedInactive.Background" Color="#3DDADADA"/>
<SolidColorBrush x:Key="Item.SelectedInactive.Border" Color="#FFDADADA"/>
<SolidColorBrush x:Key="Item.SelectedActive.Background" Color="#3D26A0DA"/>
<SolidColorBrush x:Key="Item.SelectedActive.Border" Color="#FF26A0DA"/>
<Style x:Key="ListBoxItemStyle1" TargetType="{x:Type ListBoxItem}">
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="Padding" Value="4,1"/>
<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="Background" Value="Transparent"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True"/>
</MultiTrigger.Conditions>
<Setter Property="Background" TargetName="Bd" Value="{StaticResource Item.MouseOver.Background}"/>
<Setter Property="BorderBrush" TargetName="Bd" Value="{StaticResource Item.MouseOver.Border}"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Selector.IsSelectionActive" Value="False"/>
<Condition Property="IsSelected" Value="True"/>
</MultiTrigger.Conditions>
<Setter Property="Background" TargetName="Bd" Value="{StaticResource Item.SelectedInactive.Background}"/>
<Setter Property="BorderBrush" TargetName="Bd" Value="{StaticResource Item.SelectedInactive.Border}"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Selector.IsSelectionActive" Value="True"/>
<Condition Property="IsSelected" Value="True"/>
</MultiTrigger.Conditions>
<Setter Property="Background" TargetName="Bd" Value="{StaticResource Item.SelectedActive.Background}"/>
<Setter Property="BorderBrush" TargetName="Bd" Value="{StaticResource Item.SelectedActive.Border}"/>
</MultiTrigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="TextElement.Foreground" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
You may for example change the Color of the Item.MouseOver.Background and Item.SelectedActive.Background resources.

WPF: Move focus to previous control (SHIFT + Tab) when using ControlTemplate with Placeholder Textbox

I created a WPF TextBox with Placeholder text by creating a customized Style that overlays one TextBox (as a placholder text) on another TextBox in the ControlTemplate.
Here's the Style definition:
<Style x:Key="TextBoxFormBaseStyle"
BasedOn="{StaticResource {x:Type TextBox}}"
TargetType="{x:Type TextBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Grid>
<TextBox x:Name="_textSource"
Panel.ZIndex="2"
Background="Transparent"
Text="{Binding Path=Text, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<TextBox x:Name="_textTag"
Panel.ZIndex="1"
Focusable="False"
Text="{TemplateBinding Tag}">
<TextBox.Style>
<Style TargetType="{x:Type TextBox}">
<Setter Property="Foreground" Value="Transparent" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Text, Source={x:Reference _textSource}}" Value="">
<Setter Property="Foreground" Value="{Binding Path=OpacityMask, Source={x:Reference _textSource}}" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
</Grid>
<!-- Move Focus to child control -->
<ControlTemplate.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter TargetName="_textSource" Property="FocusManager.FocusedElement" Value="{Binding ElementName=_textSource}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
A Trigger on Property IsFocused allows focusing the the child TextBox control (named _textSource) when navigating through multiple TextBox's by Tab key.
Navigating to the previous element by pressing SHIFT + Tab is not working. How can I get SHIFT + Tab to set the focus to the previous element?
There are better ways to add a watermark if you want the TextBox to actuallty behave and get focused like a built-in TextBox. Try this style:
<Style x:Key="TextBoxFormBaseStyle" BasedOn="{StaticResource {x:Type TextBox}}" TargetType="{x:Type TextBox}">
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
<Grid>
<TextBox x:Name="_textTag"
Focusable="False"
Text="{TemplateBinding Tag}"
BorderThickness="0">
<TextBox.Style>
<Style TargetType="{x:Type TextBox}">
<Setter Property="Foreground" Value="Transparent" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Text, RelativeSource={RelativeSource AncestorType=TextBox}}" Value="">
<Setter Property="Foreground" Value="{Binding Path=OpacityMask, RelativeSource={RelativeSource AncestorType=TextBox}}" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
<ScrollViewer x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Opacity" TargetName="border" Value="0.56"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="#FF7EB4EA"/>
</Trigger>
<Trigger Property="IsKeyboardFocused" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="#FF569DE5"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Sample usage:
<TextBox OpacityMask="Red" Tag="Red Watermark" Text="text" Style="{StaticResource TextBoxFormBaseStyle}" />
<TextBox OpacityMask="Green" Tag="Green Watermark" Text="text" Style="{StaticResource TextBoxFormBaseStyle}" />

Custom Control Background Color in WPF

I have created a custom control as you see below (Generic.xaml):
<Style TargetType="{x:Type local:MyCC}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:MyCC}">
<Grid Name="grd" Height="{Binding Height}" Width="{Binding Width}">
<Rectangle Name="FirstRec" Fill="Blue"/>
<Rectangle Name="SecondRec" Fill="Black" Margin="1"/>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property = "IsMouseOver" Value = "True">
<Setter Property = "Background" Value = "Red" />
</Trigger>
</Style.Triggers>
</Style>
For FirstRec I want to get the Foreground color of the CC (instead of blue) and for the SecondRec I need to get the Background (instead of black). Therefore now the trigger does not work properly! I also don't want to bind the Height and Width of the Grid because the CC has its own height and width but I don't know how to use it! Would you please help me?!
EDIT:
It is actually a switch that has a status. if status == 0 it shows an empty rectangle. if status == 1 it shows a filled rectangle. if status == 3 || status == 4 it shows a red cross on it. here is the cc:
<Style TargetType="{x:Type local:BreakerCC}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:BreakerCC}">
<Grid Name="grd" Background="{TemplateBinding Background}" >
<Rectangle Name="MainRectangle" StrokeThickness="1" Stroke="{TemplateBinding Foreground}"/>
<Path Name="Line1" Stroke="Red" StrokeThickness="1" Stretch="Fill">
<Path.Data>
<LineGeometry StartPoint="0,0" EndPoint="1,1" />
</Path.Data>
<Path.Style>
<Style TargetType="Path">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Status}" Value="0x00">
<Setter Property="Visibility" Value="Hidden"/>
</DataTrigger>
<DataTrigger Binding="{Binding Path=Status}" Value="0x01">
<Setter Property="Visibility" Value="Hidden"/>
</DataTrigger>
<DataTrigger Binding="{Binding Path=Status}" Value="0x02">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
<DataTrigger Binding="{Binding Path=Status}" Value="0x03">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Path.Style>
</Path>
<Path Name="Line2" Stroke="Red" StrokeThickness="1" Stretch="Fill">
<Path.Data>
<LineGeometry StartPoint="0,1" EndPoint="1,0" />
</Path.Data>
<Path.Style>
<Style TargetType="Path">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Status}" Value="0x00">
<Setter Property="Visibility" Value="Hidden"/>
</DataTrigger>
<DataTrigger Binding="{Binding Path=Status}" Value="0x01">
<Setter Property="Visibility" Value="Hidden"/>
</DataTrigger>
<DataTrigger Binding="{Binding Path=Status}" Value="0x02">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
<DataTrigger Binding="{Binding Path=Status}" Value="0x03">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Path.Style>
</Path>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
And this is the definition in MainWindow.xaml
<Window.Resources>
<Style x:Key="230KV" TargetType="Control">
<Setter Property="Background" Value="Black"/>
<Setter Property="Foreground" Value="Red"/>
</Style>
<Style x:Key="132KV" TargetType="Control">
<Setter Property="Background" Value="Black"/>
<Setter Property="Foreground" Value="Green"/>
</Style>
<Style x:Key="400KV" TargetType="Control">
<Setter Property="Background" Value="Black"/>
<Setter Property="Foreground" Value="Purple"/>
</Style>
</Window.Resources>
<Grid>
<StackPanel>
<CC:BreakerCC Status="{Binding Status}" Style="{StaticResource 132KV}" Height="20" Width="20"/>
</StackPanel>
</Grid>
But when the status is 3 or 4 i need to change the Foreground to Red and that doesn't work!
Use TemplateBindings for the Brushes. Binding Width and Height is not at all necessary.
<Style TargetType="local:MyCC">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:MyCC">
<Grid>
<Rectangle Fill="{TemplateBinding Foreground}"/>
<Rectangle Fill="{TemplateBinding Background}" Margin="1"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
As a note, instead of a Grid you would usually have a Border element and assign TemplateBindings to its Background, BorderBrush and BorderThickness properties - as done by default by Visual Studio when you create a new custom control.
EDIT: It seems that you do not need a custom control at all. Just create ContentControl styles like these:
<Window.Resources>
<Style TargetType="ContentControl" x:Key="BaseStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ContentControl">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Path x:Name="path" Stroke="{TemplateBinding Foreground}"
Data="{TemplateBinding Content}" Stretch="Fill"/>
</Border>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding Path=Status}" Value="0">
<Setter TargetName="path"
Property="Visibility" Value="Hidden"/>
</DataTrigger>
<DataTrigger Binding="{Binding Path=Status}" Value="1">
<Setter TargetName="path"
Property="Visibility" Value="Hidden"/>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Background" Value="Black"/>
<Setter Property="BorderBrush" Value="{Binding Foreground,
RelativeSource={RelativeSource Self}}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Width" Value="20"/>
<Setter Property="Height" Value="20"/>
</Style>
<Style x:Key="230KV" TargetType="ContentControl" BasedOn="{StaticResource BaseStyle}">
<Setter Property="Foreground" Value="Red"/>
</Style>
<Style x:Key="132KV" TargetType="ContentControl" BasedOn="{StaticResource BaseStyle}">
<Setter Property="Foreground" Value="Green"/>
</Style>
<Style x:Key="400KV" TargetType="ContentControl" BasedOn="{StaticResource BaseStyle}">
<Setter Property="Foreground" Value="Purple"/>
</Style>
</Window.Resources>
<StackPanel>
<ContentControl Style="{StaticResource 230KV}">
<PathGeometry>M0,0 L1,1 M0,1 L1,0</PathGeometry>
</ContentControl>
<ContentControl Style="{StaticResource 132KV}">
<PathGeometry>M0,0 L1,1 M0,1 L1,0</PathGeometry>
</ContentControl>
<ContentControl Style="{StaticResource 400KV}">
<PathGeometry>M0,0 L1,1 M0,1 L1,0</PathGeometry>
</ContentControl>
</StackPanel>

WPF DataGridCell watermark style. Cannot edit the cell

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>

Change the focus color on button when pressing tab on it

I have button with a black background. When you tab to the Button, you don't see that focus is now on the Button because of the Button's background color. How can I change the focus frame to be red?
(When you have focus on the Button, you see some frame with points in the button)
<Border x:Name="border" Background="{TemplateBinding Background}">
<ContentPresenter x:Name="contentPresenter"
ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}"
ContentStringFormat="{TemplateBinding ContentStringFormat}"
Focusable="False"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Opacity" Value="1" />
</Trigger>
....
Try this
<Style TargetType="Button">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="FocusVisualStyle">
<Setter.Value>
<Style TargetType="Control">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle x:Name="bd" Stroke="Red" SnapsToDevicePixels="True" StrokeThickness="1" StrokeDashCap="Triangle" StrokeDashArray="1,2" Margin="1" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border x:Name="border" BorderBrush="Transparent" BorderThickness="1" Background="{TemplateBinding Background}">
<ContentPresenter x:Name="contentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center" ContentStringFormat="{TemplateBinding ContentStringFormat}" Focusable="False"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="border" Property="BorderBrush" Value="Black"></Setter>
<Setter TargetName="border" Property="Margin" Value="1"></Setter>
</Trigger>
<Trigger Property="IsFocused" Value="True">
<Setter Property="Foreground" Value="Red"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Button Content="Hello World" Background="Gray" Height="35" Width="200" ></Button>
Update
As per my Knowledge Elements that are not enabled do not participate in hit testing or focus and therefore will not be sources of input events.so one has to use workaround like this:
<Window.Resources>
<Style x:Key="FocusVisualStyle">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle x:Name="bd" Stroke="Red" SnapsToDevicePixels="True" StrokeThickness="1" StrokeDashCap="Triangle" StrokeDashArray="1,2" Margin="1" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="Buttonstyle" TargetType="Button">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="IsEnabled" Value="True"/>
<Setter Property="FocusVisualStyle" Value="{DynamicResource FocusVisualStyle}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border x:Name="border" Focusable="False" BorderBrush="Transparent" BorderThickness="1" Background="{TemplateBinding Background}">
<ContentPresenter x:Name="contentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center" ContentStringFormat="{TemplateBinding ContentStringFormat}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="border" Property="BorderBrush" Value="Black"></Setter>
<Setter TargetName="border" Property="Margin" Value="1"></Setter>
</Trigger>
<Trigger Property="IsFocused" Value="True">
<Setter Property="Foreground" Value="Red"></Setter>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" Value="0.3"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid x:Name="gd" Height="35" Width="200">
<Grid.Style>
<Style TargetType="Grid">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=bt,Path=IsEnabled}" Value="False">
<Setter Property="Focusable" Value="True"></Setter>
<Setter Property="FocusVisualStyle" Value="{DynamicResource FocusVisualStyle}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Grid.Style>
<Button x:Name="bt" IsEnabled="False" Style="{StaticResource Buttonstyle}" Content="Hello World" IsTabStop="True" Background="Gray"/>
</Grid>
Use the IsFocused dependency property in your triggers. I suggest you to change the border width, or its colour, to differentiate the button from the unfocused ones. The dashed rectangle that indicates focus is, as far as I know, implemented in the built controls only. If you make a template, you should override it to suit your needs.

Categories

Resources