Can't get underline to show up when triggered - wpf

I have the following style, but when the mouse over trigger is true, no underline shows up on the text.
<Style x:Key="HyperlinkToggleButtonStyle" TargetType="ToggleButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<TextBlock x:Name="TextBlock">
<ContentPresenter Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}"/>
</TextBlock>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="false">
<Setter Property="Background" Value="{StaticResource StandardBackground}"/>
<Setter Property="Foreground" Value="Black" />
<Setter Property="FontSize" Value="12"/>
<Setter Property="FontStyle" Value="Normal"/>
<Setter Property="FontWeight" Value="Normal"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" Value="{StaticResource StandardBackground}"/>
<Setter Property="Foreground" Value="{StaticResource StandardBlue}" />
<Setter Property="Cursor" Value="Hand" />
<Setter Property="FontSize" Value="12"/>
<Setter Property="FontStyle" Value="Normal"/>
<Setter Property="FontWeight" Value="Normal"/>
<Setter Property="TextBlock.TextDecorations" Value="Underline"/>
</Trigger>
</Style.Triggers>
</Style>

This might not be an ideal solution, but you could define the trigger in your control template. Don't forget to reference your TextBlock with the TargetName property on the setter.
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<TextBlock x:Name="TextBlock">
<ContentPresenter Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}"/>
</TextBlock>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="TextBlock" Property="TextBlock.TextDecorations" Value="Underline"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>

The TextDecorations property is not inherited so setting the value on the Button (which is what your trigger is targeting), will not accomplish what you want. You can probably use a StoryBoard to do that, but I can't remember if a storyboard can target an element defined in a template (only way to find out is to do it).

Related

Problem with disabled button style in WPF

I use bellow style in App.xaml file. I want my buttons(SendCommandBtn) have #5e95a7 color when they are enabled with no rounded border and some other styles.
<Style TargetType="{x:Type Button}" x:Key="SendCommandBtn">
<Setter Property="Height" Value="28"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="BorderBrush" Value="#5e95a7"/>
<Setter Property="FontSize" Value="16"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}" >
<Border CornerRadius="0" BorderThickness="0" Height="28" Margin="0,0,10,0" >
<ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Background" Value="#f2f2f2"/>
<Setter Property="Foreground" Value="Red"/>
<Setter Property="Cursor" Value="No"/>
</Trigger>
<Trigger Property="IsEnabled" Value="True">
<Setter Property="Background" Value="#5e95a7"/>
<Setter Property="Foreground" Value="#fff"/>
<Setter Property="Cursor" Value="Hand"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type Button}" x:Key="NormalBtn">
<Setter Property="Background" Value="#5e95a7"/>
<Setter Property="Height" Value="28"/>
<Setter Property="Foreground" Value="#fff"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="BorderBrush" Value="#5e95a7"/>
<Setter Property="FontSize" Value="16"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}" >
<Border CornerRadius="0" BorderThickness="0" Background="#5e95a7" Height="28" Margin="0,0,10,0" >
<ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Now when I have below button:
<Button Name="BtnSIM2" Content=" SIM 2" Grid.Column="2" Click="BtnSIM2_Click" Style="{DynamicResource SendCommandBtn}"></Button>
when the button is enable, the background color is transparent and the foreground is white.
When the button is disable again the background is transparent and foreground is Red.
Can any one help me to understand what is wrong with my style?
You have replaced the control template, therefore you have to change the background of Border that is your "main control" now.
To do so, set the name for your Border inside and change the color of that border instead like this(by targeting that border by its name):
<Style TargetType="{x:Type Button}" x:Key="SendCommandBtn">
...
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}" >
<Border CornerRadius="0" BorderThickness="0" Height="28" Margin="0,0,10,0" x:Name="ButtonBorder" >
<ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Background" TargetName="ButtonBorder" Value="#f2f2f2"/>
<Setter Property="Foreground" TargetName="ButtonBorder" Value="Red"/>
<Setter Property="Cursor" TargetName="ButtonBorder" Value="No"/>
</Trigger>
<Trigger Property="IsEnabled" TargetName="ButtonBorder" Value="True">
<Setter Property="Background" TargetName="ButtonBorder" Value="#5e95a7"/>
<Setter Property="Foreground" TargetName="ButtonBorder" Value="#fff"/>
<Setter Property="Cursor" TargetName="ButtonBorder" Value="Hand"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

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

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

Disable Button but keep the color of the background

i have the following button style which works fine:
<Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border x:Name="Border"
CornerRadius="2" BorderThickness="1"
Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}">
<ContentPresenter Margin="2" HorizontalAlignment="Center" VerticalAlignment="Center" RecognizesAccessKey="True"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter TargetName="Border" Property="Background" Value="{StaticResource DisabledBackgroundBrush}" />
<Setter TargetName="Border" Property="BorderBrush" Value="{StaticResource DisabledBorderBrush}" />
<Setter Property="Foreground" Value="{StaticResource DisabledForegroundBrush}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
with more styles defined at the button itself i change the buttons background (green for active)
<Button>
<Button.Style>
<Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
<Style.Triggers>
<DataTrigger Binding="{Binding MainStatus.Restart}" Value="true">
<Setter Property="Background" Value="LimeGreen" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
now if i disable the button, the button gets gray, because of the template. is there a way of making the current background more 'gray' but keeping the base color. so if the button was green, the color remains basically green?
Instead of setting background gray, you can set opacity to give it a disabled look (this will retain your background) something like this:
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<!--<Setter TargetName="Border" Property="Background"
Value="{StaticResource DisabledBackgroundBrush}" />-->
<Setter TargetName="Border" Property="Opacity" Value="0.4"/>
<Setter TargetName="Border" Property="BorderBrush"
Value="{StaticResource DisabledBorderBrush}" />
<Setter Property="Foreground"
Value="{StaticResource DisabledForegroundBrush}"/>
</Trigger>
</ControlTemplate.Triggers>
Create style:
<Style.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#FFADADAD"/>
</Trigger>
</Style.Triggers>

Setting a different color for each tab using the same style

So I have the following style in my Window.Resources:
<Style TargetType="TabItem" x:Key="tiS">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TabItem">
<Grid Height="40" Width="186">
<Border Name="tiBorder" Background="Transparent">
<ContentPresenter ContentSource="Header"
VerticalAlignment="Center"
HorizontalAlignment="Center"
TextBlock.FontSize="20"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Panel.ZIndex" Value="90"/>
<Setter TargetName="tiBorder" Property="Background" Value="{DynamicResource tiB}"/>
<!--<Setter TargetName="tiBorder" Property="Margin" Value="0,-4,0,-4"/>-->
<Setter TargetName="tiBorder" Property="BorderThickness" Value="0,0,0,1"/>
<Setter TargetName="tiBorder" Property="BorderBrush" Value="{StaticResource tiLineFade}"/>
</Trigger>
<Trigger Property="IsSelected" Value="False">
<Setter Property="Panel.ZIndex" Value="80"/>
<Setter TargetName="tiBorder" Property="BorderThickness" Value="0,0,0,1"/>
<Setter TargetName="tiBorder" Property="BorderBrush" Value="{StaticResource tiLineFade}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
This style is used on 5 TabItems, each with a different color given by 'DynamicResource tiB' in the trigger.
In each TabItem I have the following resource placed (Color1 is set in the Window.Resources):
<TabItem.Resources>
<SolidColorBrush x:Key="tiB" Color="{StaticResource Color1}"/>
</TabItem.Resources>
I was wondering, is there an easier way to do this or am I doing it right? This is the first time I'm working with styles in WPF so I want to do it right. (This code is working! Looking for a better (if there is one) solution to my situation.)
Here is the full code: http://pastebin.com/igwxgp6M
I believe this will work
<TabControl ...>
<TabControl.ItemsContainerStyle>
<Style TargetType="TabItem">
//Put triggers here
</Style>
<TabControl.ItemsContainerStyle>
</TabControl>

How to I stop Vista from pulsating my focused XAML buttons?

I've created a style for buttons in my WPF application.
However, on Vista, when a button is focused, it pulsates with a light blue that doesn't look good in the design.
How can I override this automatic pulsating?
<Style x:Key="NavigationButtonStyle" TargetType="Button">
<Setter Property="Width" Value="400"/>
<Setter Property="Height" Value="100"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="FontSize" Value="56"/>
<Setter Property="Foreground" Value="#aaa"/>
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="#ddd" />
</Trigger>
<Trigger Property="IsEnabled" Value="True">
<Setter Property="Foreground" Value="#aaa" />
</Trigger>
</Style.Triggers>
</Style>
Tried "IsFocused":
Adding this doesn't have any effect on Vista, the button still looks the same and is pulsating in Vista when focused:
<Trigger Property="IsFocused" Value="True">
<Setter Property="Background" Value="Red" />
<Setter Property="Foreground" Value="Blue" />
</Trigger>
Tried "ControlTemplate" solution:
Still no effect:
<Style x:Key="ButtonFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle SnapsToDevicePixels="true" Margin="2" Stroke="Black" StrokeDashArray="1 2" StrokeThickness="1"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="NavigationButtonStyle" TargetType="Button">
<Setter Property="Width" Value="400"/>
<Setter Property="Height" Value="100"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="FontSize" Value="56"/>
<Setter Property="Foreground" Value="#aaa"/>
<Setter Property="FocusVisualStyle" Value="{StaticResource ButtonFocusVisual}"/>
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="#ddd" />
</Trigger>
<Trigger Property="IsEnabled" Value="True">
<Setter Property="Foreground" Value="#aaa" />
</Trigger>
</Style.Triggers>
</Style>
This effect is being set in response IsKeyboardFocused, not just standard focus.
In Blend if you edit the control template for a standard button, you'll see that on the IsKeyboardFocused=true trigger is responsible for this effect.
<Style x:Key="Button_NonGlow" TargetType="{x:Type Button}">
<Setter Property="FocusVisualStyle" Value="{StaticResource ButtonFocusVisual}"/>
<Setter Property="Background" Value="{StaticResource ButtonNormalBackground}"/>
<Setter Property="BorderBrush" Value="{StaticResource ButtonNormalBorder}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Microsoft_Windows_Themes:ButtonChrome SnapsToDevicePixels="true" x:Name="Chrome" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" RenderDefaulted="{TemplateBinding IsDefaulted}" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderPressed="{TemplateBinding IsPressed}">
<ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" RecognizesAccessKey="True"/>
</Microsoft_Windows_Themes:ButtonChrome>
<ControlTemplate.Triggers>
<Trigger Property="IsKeyboardFocused" Value="true">
<Setter Property="RenderDefaulted" TargetName="Chrome" Value="true"/>
</Trigger>
<Trigger Property="ToggleButton.IsChecked" Value="true">
<Setter Property="RenderPressed" TargetName="Chrome" Value="true"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#ADADAD"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
What you are looking for is the IsFocused trigger property. Sorry that I do not have a working example for you right here.
UPDATE:
I found this small piece of code that I once used. I am not sure if is works and I can not test it (I am on an XP box):
<Style x:Key="ButtonFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle SnapsToDevicePixels="true" Margin="2" Stroke="Black" StrokeDashArray="1 2" StrokeThickness="1"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type Button}">
<Setter Property="FocusVisualStyle" Value="{StaticResource ButtonFocusVisual}"/>
</Style>
Depending on your specific requirements you can simply ensure the button never gets keyboard focus by setting IsTabStop="False" and IsDefault="False".

Resources