Reference object inside XAML template - wpf

I have resource dictionary for my radio button which adds textbox to it. I want to add trigger which adds left margin to this textbox but I don't know how to reference it
I marked place where I want to add reference
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style BasedOn="{StaticResource {x:Type ToggleButton}}"
TargetType="{x:Type RadioButton}"
x:Key="MenuButtonTheme">
<Style.Setters>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="RadioButton">
<Grid VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
Background="{TemplateBinding Background}">
<TextBlock Text="{TemplateBinding Property=Content}"
VerticalAlignment="Center"
Margin="20,0,0,0">
</TextBlock>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Background" Value="Transparent"></Setter>
<Setter Property="BorderThickness" Value="0"></Setter>
</Style.Setters>
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Margin" Value="30,0,0,0"></Setter> <!-- Reference TextBlock here -->
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#424549"></Setter>
</Trigger>
</Style.Triggers>
</Style>
</ResourceDictionary>

You need to set triggers not in Style, but in ControlTemplate. Then you can refer to template elements by name:
<ControlTemplate TargetType="RadioButton">
<Grid x:Name="PART_Main" VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
Background="{TemplateBinding Background}">
<TextBlock x:Name="PART_TBlock"
Text="{TemplateBinding Property=Content}"
VerticalAlignment="Center"
Margin="20,0,0,0"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="PART_TBlock" Property="Margin" Value="30,0,0,0"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="PART_Main" Property="Background" Value="#424549"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>

Related

Add border to radioButton with text on isChecked

I want to add border to radiobutton with text on isChecked
I tried Style.Trigger but it didn't seem to have action
Also tried via ControlTemplate.Trigger but referencing to both grid and text box says Parameter is not recognized
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style BasedOn="{StaticResource {x:Type ToggleButton}}"
TargetType="{x:Type RadioButton}"
x:Key="MenuButtonTheme">
<Style.Setters>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="RadioButton">
<Grid VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
Background="{TemplateBinding Background}"
x:Name="GridMain">
<TextBlock Text="{TemplateBinding Property=Content}"
x:Name="ButtonText"
VerticalAlignment="Center"
Margin="20,0,0,0">
</TextBlock>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="ButtonText" Property="Margin" Value="30,0,0,0"></Setter>
<!-- <Setter TargetName="ButtonText" Property="BorderThickness" Value="5"></Setter> -->
<!-- <Setter TargetName="GridMain" Property="BorderThickness" Value="5"></Setter> -->
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="GridMain" Property="Background" Value="#424549"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Background" Value="Transparent"></Setter>
</Style.Setters>
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="BorderThickness" Value="5"></Setter>
<Setter Property="BorderBrush" Value="#7289da"></Setter>
</Trigger>
</Style.Triggers>
</Style>
The TextBlock doesn't have a border, so it's impossible to set a value for the border either.
It can be solved in two ways.
Use instead of TextBlock element TextBox in read-only mode.
<ControlTemplate TargetType="RadioButton">
<Grid VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
Background="{TemplateBinding Background}"
x:Name="GridMain">
<TextBox Text="{TemplateBinding Content}"
x:Name="ButtonText"
VerticalAlignment="Center"
Margin="20,0,0,0"
IsReadOnly="True"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="ButtonText" Property="Margin" Value="30,0,0,0"></Setter>
<Setter TargetName="ButtonText" Property="BorderThickness" Value="5"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="GridMain" Property="Background" Value="#424549"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
Since you have only one element in the panel, you can use Border instead.
<ControlTemplate TargetType="RadioButton">
<Border VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
Background="{TemplateBinding Background}"
x:Name="GridMain">
<TextBlock Text="{TemplateBinding Property=Content}"
x:Name="ButtonText"
VerticalAlignment="Center"
Margin="20,0,0,0">
</TextBlock>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="ButtonText" Property="Margin" Value="30,0,0,0"></Setter>
<Setter TargetName="GridMain" Property="BorderThickness" Value="5"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="GridMain" Property="Background" Value="#424549"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>

Remove underline from TabItem header when tabitem is selected

I want to underline the TabItem Header Title when Mousehover on header , and remove the Underline once it is selected.
I have tried below code:
<Style x:Key="N3EntityNavigationItemStyle" TargetType="{x:Type Custom11:TabItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid>
<Border Name="Border" BorderThickness="0,0,1,0" BorderBrush="White" Padding="5,2">
<ContentPresenter x:Name="CP" ContentSource="Header">
</ContentPresenter>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter Property="TextElement.Foreground" TargetName="CP" Value="Black"/>
<Setter TargetName="Border" Property="Background" Value="White" />
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock Text="{Binding}"></TextBlock>
</DataTemplate>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsSelected" Value="False">
<Setter Property="Foreground" Value="White" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock Text="{Binding}" TextDecorations="Underline"></TextBlock>
</DataTemplate>
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
But the tabitem header still remain underline after selecting the tab.

Button IsPressed Trigger Not Working

I have a button with an undo image inside it.
I want the button to make the border appear when user clicks (ispressed) the button.
<Button Margin="0,7,12,0" HorizontalAlignment="Right" Height="20" Width="23">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="White"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter Property="BorderThickness" Value="1"/>
</Trigger>
<Trigger Property="IsPressed" Value="False">
<Setter Property="BorderThickness" Value="0"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
<Image Grid.Column="0" Grid.Row="0" Margin="0,0,0,0" Height="20" Width="20" Source="/Images/Undo.png">
<Image.Style>
<Style TargetType="Image">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Opacity" Value="0.7"/>
</Trigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</Button>
But its not working at all.
Any help will be appreciated!
I did the following changes to your style: 1) moved triggers within ControlTemplate; 2) assigned x:Name to Border so it can be referenced in the trigger; 3) defined BorderBrush.
<Button Margin="0" HorizontalAlignment="Center" Height="25" Width="75" VerticalAlignment="Center">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="White"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="b0" Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter Property="BorderThickness" TargetName="b0" Value="1"/>
<Setter Property="BorderBrush" TargetName="b0" Value="Blue"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Button.Style>
<Image Grid.Column="0" Grid.Row="0" Margin="0,0,0,0" Height="20" Width="20" Source="/Images/Undo.jpg">
<Image.Style>
<Style TargetType="Image">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Opacity" Value="0.7"/>
</Trigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</Button>
It's not working because the button template sets the border thickness to 1 directly, ignoring the border thickness attribute of the button element itself. You're successfully changing a value that isn't used.
You will have to copy and modify the button template if you want to change the border thickness.

Stylling Button in WPF

I have a style for button as per below code.
<Style TargetType="Button" x:Key="TransparentButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border HorizontalAlignment="Center" x:Name="borderTemplate"
Background="Transparent">
<ContentPresenter/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="borderTemplate"
Property="Border.BorderBrush" Value="Gray" />
<Setter TargetName="borderTemplate"
Property="Border.BorderThickness" Value="1" />
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter TargetName="borderTemplate"
Property="Border.BorderBrush" Value="Lime" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I need to set the background of button
1.To gray as soon as “MouseUp“ event occurred.
2.And set it to Default(say white)as soon as Focus Of Button being changed or say Focus Being lost.
Is there any way to solve this using Trigger or EventTrigger??.
See One example for above code with image
Button with Above style.
<Button Background="Black" Style="{StaticResource TransparentButton}"
Content="0123456789" Height="15" HorizontalAlignment="Left"
Name="button2" VerticalAlignment="Top" Margin="70,17,0,0" />
Button will look as per below image after above style being applied.
This can be done by using RadioButton instead of Button
just have a look at this
<Style x:Key="RadioButtonStyle1" TargetType="{x:Type RadioButton}">
<Setter Property="Background" Value="#F4F4F4"/>
<Setter Property="BorderBrush" Value="{StaticResource CheckBoxStroke}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RadioButton}">
<Border HorizontalAlignment="Center" x:Name="borderTemplate" Background="Transparent" VerticalAlignment="Center">
<ContentPresenter x:Name="contentPresenter" VerticalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" TargetName="borderTemplate" Value="#FFE4E4E4"/>
<Setter Property="HorizontalAlignment" TargetName="contentPresenter" Value="Center"/>
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Background" TargetName="borderTemplate" Value="#FFA1A1A1"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Grid x:Name="LayoutRoot">
<StackPanel/>
<RadioButton Content="RadioButton" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="116,86.04,0,0" Style="{StaticResource RadioButtonStyle1}"/>
<RadioButton Content="RadioButton" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="116,106,0,0" Style="{StaticResource RadioButtonStyle1}"/>
</Grid>

WPF Binding & Converters

I've been recently playing with WPF and I've come across a number of problems that I can't solve. I have the following code in my generic.xaml:
<Style TargetType="{x:Type local:ClearButton}">
<Style.Resources>
<con:ValueConverter x:Key="converter" />
</Style.Resources>
<Setter Property="Width" Value="20" />
<Setter Property="Height" Value="20" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:ClearButton}">
<Grid>
<Image Width="{TemplateBinding Width}" Height="{TemplateBinding Height}">
<Image.Style>
<Style TargetType="{x:Type Image}">
<Setter Property="Source" Value="/WPF-Libraries;component/Resources/ClearEnabled.png" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BitmapEffect">
<Setter.Value>
<OuterGlowBitmapEffect Opacity="0.5" GlowColor="Red" GlowSize="3" />
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Source"
Value="/WPF-Libraries;component/Resources/ClearDisabled.png" />
</Trigger>
<!--Binding #1-->
<Trigger Property="{TemplateBinding local:ClearButton.IsPressed}" Value="True">
<Setter Property="RenderTransform">
<Setter.Value>
<!--Binding #2-->
<ScaleTransform CenterX="CONVERTER BINDING:PASS WIDTH TO CONVERTER" CenterY="CONVERTER BINDING:PASS HEIGHT TO CONVERTER" ScaleX="0.75" ScaleY="0.75" />
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I can't get Binding #1 to work. I want to bind the trigger to the IsPressed property of the button, what should the binding be? Also what should the binding be for Binding #2 if I want to pass the button's Width and Height to the converter?
Also I could set the trigger this way instead:
<Style TargetType="{x:Type local:ClearButton}">
<Style.Resources>
<con:ValueConverter x:Key="converter" />
</Style.Resources>
<Setter Property="Width" Value="20" />
<Setter Property="Height" Value="20" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:ClearButton}">
<!--Abbreviated-->
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<!--Binding #1-->
<Trigger Property="{TemplateBinding local:ClearButton.IsPressed}" Value="True">
<Setter Property="RenderTransform">
<Setter.Value>
<!--Binding #2-->
<ScaleTransform CenterX="CONVERTER BINDING" CenterY="CONVERTER BINDING" ScaleX="0.75" ScaleY="0.75" />
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
Which one is better and what would the binding be for Binding #1 and #2?
Both approaches are a little bit off. Your first approach is struggling to reach the IsPressed property using binding, however the Property property of the Trigger object is not a DependencyProperty so it doesn't support binding.
Your second approach is closer to the mark but still wrong, again uses binding on the Property property of the Trigger.
Check this out instead:
<Style TargetType="Button" x:Key="ClearButtonStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<TextBlock
Name="x"
Text="I will change my color when ou press me"
TextAlignment="Center"
VerticalAlignment="Center"
Foreground="Red"
TextWrapping="Wrap"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter
TargetName="x"
Property="Foreground"
Value="Green"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Notice that I put the trigger logic on the control template level (specifying the target element), not on the individual element (the TextBlock in this case).

Resources