Problem with disabled button style in WPF - 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>

Related

Why does my IsMouseOver event only work if my CheckBox is true?

I have a DataGrid in which I can change the respective colors when my CheckBox is activated. However, my IsMouseOver event only works if my CheckBox is true. As soon as my CheckBox is set to false, my IsMouseOver Effect no longer works, why? Do I have to set a trigger somewhere?
My Code from my DataGrid:
<DataGrid x:Name="datagrid" ItemsSource="{Binding}"
CanUserAddRows="False" CanUserDeleteRows="False"
CanUserResizeRows="True" GridLinesVisibility="None"
ColumnWidth="*" DockPanel.Dock="Bottom"
Background="#222831" Foreground="White"
AutoGenerateColumns="True">
<DataGrid.ContextMenu>
<ContextMenu>
<MenuItem Command="Copy"/>
</ContextMenu>
</DataGrid.ContextMenu>
<DataGrid.Resources>
<!--Design kopfzeile-->
<Style TargetType="{x:Type DataGridColumnHeader}" x:Name="test" >
<Setter Property="Background" Value="#292F3B"/>
<Setter Property="Foreground" Value="LightBlue"/>
<Setter Property="FontWeight" Value="SemiBold"/>
<Setter Property="Height" Value="30"/>
<Setter Property="FontSize" Value="15"/>
<Setter Property="BorderThickness" Value="0,0,2,0" />
<Setter Property="BorderBrush" Value="#333333"/>
<Setter Property="Padding" Value="10 0 0 0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
<Border x:Name="insideHeader" Background="#242A36">
<Border x:Name="borderHeader" BorderThickness="1"
CornerRadius="6"
Background="#2D2D30"
Padding="10,0,0,0"
Margin="2">
<ContentPresenter/>
</Border>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="borderHeader" Property="Background" Value="#4182C6"/>
</Trigger>
<DataTrigger Binding="{Binding ElementName=toogleButton,Path=IsChecked}" Value="False">
<Setter TargetName="borderHeader" Property="Background" Value="#FA9F34"/>
<Setter Property="Foreground" Value="#2B2B2B"/>
<Setter TargetName="insideHeader" Property="Background" Value="#00336E"/>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--Deaktivieren Des rowheader-->
<Style TargetType="{x:Type DataGridRowHeader}">
<Setter Property="Background" Value="Transparent"/>
</Style>
<!--Cellen Design-->
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="Background" Value="#292F3B"/>
<Setter Property="Foreground" Value="LightBlue"/>
<Setter Property="BorderThickness" Value="0,0,2,0" />
<Setter Property="BorderBrush" Value="#333333"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Border x:Name="insideBorder" Background="#242A36">
<Border x:Name="BorderCell" BorderThickness="1"
CornerRadius="6"
Background="#292F3B"
Padding="10,0,0,0"
Margin="2">
<ContentPresenter/>
</Border>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="BorderCell" Property="Background" Value="#4182C6"/>
</Trigger>
<DataTrigger Binding="{Binding ElementName=toogleButton,Path=IsChecked}" Value="False">
<Setter TargetName="BorderCell" Property="Background" Value="#0051B0"/>
<Setter TargetName="insideBorder" Property="Background" Value="#00336E"/>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</DataGrid.Resources>
</DataGrid>
change triggers' order. they both set Background. at the moment DataTrigger for IsChecked=false overrides Trigger for IsMouseOver=true, when CheckBox is unchecked, because DataTrigger is applied last.
<DataTrigger Binding="{Binding ElementName=toogleButton,Path=IsChecked}" Value="False">
<Setter TargetName="borderHeader" Property="Background" Value="#FA9F34"/>
<Setter Property="Foreground" Value="#2B2B2B"/>
<Setter TargetName="insideHeader" Property="Background" Value="#00336E"/>
</DataTrigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="borderHeader" Property="Background" Value="#4182C6"/>
</Trigger>

WPF Alternation and selected background color doesn't work together

I struggle with Alternation style and selected row background color style in ListViewItem. I could make that they work separately, but together they does not work. Maybe someone know problem?
Code:
<AlternationConverter x:Key="BackgroundConverter">
<SolidColorBrush Color="#19f39611" />
<SolidColorBrush Color="#19000000" />
</AlternationConverter>
<Style x:Key="Style2" TargetType="ListViewItem">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewItem">
<Border
Name="Border"
Padding="2"
SnapsToDevicePixels="true"
Background="Transparent">
<GridViewRowPresenter
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter TargetName="Border"
Property="Background" Value="Red"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground"
Value="Beige"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="Style1" TargetType="{x:Type ListViewItem}" BasedOn="{StaticResource Style2}">
<Setter Property="Background" Value="{Binding RelativeSource={RelativeSource Self},
Path=(ItemsControl.AlternationIndex),
Converter={StaticResource BackgroundConverter}}"/>
</Style>
.....
<ListView AlternationCount="2" ItemContainerStyle="{StaticResource Style1}" >
I found other way how to do it:
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="FontSize" Value="21"/>
<Setter Property="Height" Value="40"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<Border Background="{TemplateBinding Background}" BorderThickness="1" BorderBrush="#E6E6E6"
Name="Border" Padding="2" SnapsToDevicePixels="true">
<GridViewRowPresenter Content="{TemplateBinding Content}"
Columns="{TemplateBinding GridView.ColumnCollection}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
</GridViewRowPresenter>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter TargetName="Border"
Property="Background" Value="#FFD65E"/>
<Setter TargetName="Border" Property="BorderThickness" Value="1"/>
<Setter TargetName="Border" Property="BorderBrush" Value="#FFBA59"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<!-- setting up triggers for alternate background colors -->
<Trigger Property="ItemsControl.AlternationIndex" Value="0">
<Setter Property="Background" Value="#FFFFFF"></Setter>
</Trigger>
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
<Setter Property="Background" Value="#F7F7F7"></Setter>
</Trigger>
</Style.Triggers>
</Style>

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

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

In WPF: how to disable the animation when the button after be pressed?

I want no animation when button is pressed, but only the foreground and the background are changed, just like metro style. I'm so perplexed.
Edit:
I create a sample in Expression Blend 4.
There are 3 states: Normal, IsMouseOver, IsPressed:
Edit 2:
I just modify the Title "In WPF: how to disable the animation when the button is pressed?" to "In WPF: how to disable the animation when the button after be pressed?"
I find some problems:
When the mouse is over or press the button, the backgroud of button is not changed;
The animation run after the button has be pressed, I just want to disable the animation.
Edit 3:
This .xaml can run in VS.
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="WpfApplication17.MainWindow"
x:Name="Window"
Title="MainWindow"
Width="640" Height="480">
<Window.Resources>
<Style x:Key="ButtonStyle1" TargetType="{x:Type Button}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="White"/>
<Setter Property="BorderBrush" Value="Black"/>
<Setter Property="Background" Value="Black"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="Black"/>
<Setter Property="BorderBrush" Value="Black"/>
<Setter Property="Foreground" Value="Red"/>
</Trigger>
</Style.Triggers>
<Setter Property="Background" Value="White"/>
<Setter Property="BorderBrush" Value="White"/>
<Setter Property="Foreground" Value="Black" />
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="1"/>
</Style>
</Window.Resources>
<Grid x:Name="LayoutRoot" >
<Button Content="Button"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Width="75"
Style="{DynamicResource ButtonStyle1}"/>
</Grid>
Try this (create a new project and just paste it beneath your definition) :
<Window.Resources>
<Style x:Key="NoAnimations" TargetType="{x:Type Button}" >
<Setter Property="Foreground" Value="Black" />
<Setter Property="Background" Value="White"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border BorderBrush="Black" BorderThickness="1">
<Border Name="border" Background="{TemplateBinding Background}" Padding="3">
<Grid>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" Name="content" />
</Grid>
</Border>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Black"></Setter>
<Setter Property="Foreground" Value="White"></Setter>
</Trigger>
<Trigger Property="IsMouseOver" Value="False">
<Setter Property="Background" Value="White"></Setter>
<Setter Property="Foreground" Value="Black"></Setter>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="Black"></Setter>
<Setter Property="Foreground" Value="Red"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<StackPanel>
<Button Style="{StaticResource NoAnimations}"
Content="Testing"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Margin="20"
/>
</StackPanel>

Can't get underline to show up when triggered

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).

Resources