Button is applied with a Foreground when it is enabled. If it is Set as Disabled, default Button's Disabled Foreground need to apply.
<Button Width="150"
Height="50"
Content="Test"
Foreground="Red"
IsEnabled="False" />
I have Triggers for this button like
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#FFADADAD"/>
</Trigger>
This Foreground is not applied when it is enabled.
Any idea on this?
Need like below,
If you set the properties locally the trigger will not be able to change the value due to precedence.
Move the Foreground and IsEnabled property into the style:
<StackPanel>
<StackPanel.Resources>
<Style TargetType="{x:Type Button}">
<Setter Property="Foreground" Value="Red"/>
<Setter Property="IsEnabled" Value="True"/>
<Style.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#FFADADAD"/>
</Trigger>
</Style.Triggers>
</Style>
</StackPanel.Resources>
<Button Width="150"
Height="50"
Content="Test">
</Button>
I am not sure I understand the question properly, because those codes posted in question should work fine. Following is a working sample to produce a Button exactly as the captured image shows. I put the Style as resource in the Button's container control -StackPanel in this case- :
<StackPanel>
<StackPanel.Resources>
<Style TargetType="{x:Type Button}">
<Setter Property="Foreground" Value="Red"/>
<Style.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#FFADADAD"/>
</Trigger>
</Style.Triggers>
</Style>
</StackPanel.Resources>
<Button Width="150"
Height="50"
Content="Test"
IsEnabled="True">
</Button>
</StackPanel>
If you edit Button's default template you can find the following trigger inside control template.
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Background" TargetName="border" Value="#FFF4F4F4"/>
<Setter Property="BorderBrush" TargetName="border" Value="#FFADB2B5"/>
<Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="#FF838383"/>
</Trigger>
This trigger set Foreground to the content presenter using TargetName. No template binding used here. It directly assigns value. So the values you set for Foreground in Style Triggers will not be applied. You can edit the control template to achieve your requirement. This limitation not only for Foreground, for Background and BorderBrush also have this.
The following code is working for me:
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Grid x:Name="grid" Background="{StaticResource FlatButtonNavigation}">
<Border Name="ButtonBorder" CornerRadius="5,5,5,5"
BorderBrush="Gray" BorderThickness="2">
<ContentPresenter Name="MyContentPresenter"
HorizontalAlignment="center"
RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
TextBlock.FontSize="{TemplateBinding FontSize}"
TextBlock.Foreground="{StaticResource LeftPanelFontColor}"
Margin="10"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="ButtonBorder" Property="Background" Value="LightGray"/>
<Setter TargetName="ButtonBorder" Property="BorderBrush" Value="#FFADB2B5"/>
<Setter TargetName="MyContentPresenter" Property="TextBlock.Foreground" Value="White"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
Can be worked using styles as mentioned in the other answers, but there is no need to go outside the button to define the style, you can define a style explicitly related to the particular button:
<Button Width="150" Height="50" Content="Test">
<Button.Style>
<Style TargetType="Button">
<Setter Property="Foreground" Value="Red"/>
<Setter Property="IsEnabled" Value="True"/>
<Style.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#FFADADAD"/>
</Trigger>
</Style.Triggers>
</Button.Style>
</Button>
</StackPanel>
Related
I have three buttons on my Xaml
<Page.Resources>
<Style x:Key="GroupToggleStyle" TargetType="RadioButton" BasedOn="{StaticResource {x:Type ToggleButton}}">
<Setter Property="Background" Value="BlueViolet"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsChecked, RelativeSource={RelativeSource Self}}"
Value="True">
<DataTrigger.Setters>
<Setter Property="Background" Value="Red"/>
</DataTrigger.Setters>
</DataTrigger>
</Style.Triggers>
</Style>
</Page.Resources>
<Grid>
<RadioButton GroupName="LanguageGroup" Command="{Binding LanguageChangeCommand}" IsChecked="{Binding Button0}"
CommandParameter="English" Content="English" Foreground="White" Width="80"
Style="{StaticResource GroupToggleStyle}" FontSize="15" Grid.Row="3" Grid.Column="2" BorderBrush="#0000ffff" Height="30" Margin="8,5,162,21" Grid.ColumnSpan="2" Background="BlueViolet">
<RadioButton.Resources>
<Style TargetType="Border">
<Setter Property="CornerRadius" Value="5"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="False">
<Setter Property="Background" Value="Red"></Setter>
</Trigger>
</Style.Triggers>
</Style>
</RadioButton.Resources>
</RadioButton>
<Grid/>
But when I put mouse over my button, button's background changes to default windows gray background.
What's The Problem?
Here is a photo of my buttons
The ToggleButton defines animations inside its ControlTemplate to control the e.g., checked and hover behavior/states. You will have to override the default ControlTemplate in order to implement your custom animations and triggers.
Additionally, you must also move the mouse over trigger to the RadioButton template too.
You can find examples of the default styles and templates at Control Styles and Templates or use the XAML designer (or Blend) to edit a copy of the elements template.
<Style x:Key="GroupToggleStyle"
TargetType="RadioButton"
BasedOn="{StaticResource {x:Type ToggleButton}}">
<Setter Property="Background"
Value="BlueViolet" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="RadioButton">
<Border x:Name="Border"
CornerRadius="5"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled"
Value="False">
<Setter Property="Background"
Value="Gray" />
</Trigger>
<Trigger Property="IsChecked"
Value="True">
<Setter TargetName="Border"
Property="Background"
Value="Red" />
</Trigger>
<Trigger Property="IsMouseOver"
Value="True">
<!-- Target the border to allow local Background values on the templated control -->
<Setter TargetName="Border"
Property="Background"
Value="Green" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
In case you want to change individual buttons only, simply base the individual Style on the common base Style (but note that you have to remove the local Style assignment as the local value has a higher precedence than the implicit Style).
I want to achieve similar effect, which can be seen in Notepad++: dividing TabContol into two TabControls. Obviously both will have selected tab on their own, but still only one of them will be active.
For those who doesn't know Notepad++, this is how it looks like:
For that I'll need to introduce "Active" property on TabControl (not Focused, because when one of TabControls loses focus, its selected tab still remains active). However, I have no idea how to craft trigger on TabItem's ControlTemplate, which will allow me to distinguish selected and selected+active tab.
This is how my current TabItem template look:
<Style x:Key="BaseRootTabItem" TargetType="TabItem">
<Style.Setters>
<Setter Property="Background" Value="{StaticResource NormalTabBackgroundBrush}" />
<Setter Property="TextBlock.Foreground" Value="{StaticResource NormalTabForegroundBrush}" />
</Style.Setters>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.Setters>
<Setter Property="Background" Value="{StaticResource HoverTabBackgroundBrush}" />
<Setter Property="TextBlock.Foreground" Value="{StaticResource HoverTabForegroundBrush}" />
</Trigger.Setters>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="DocumentTabItem" TargetType="TabItem" BasedOn="{StaticResource BaseRootTabItem}">
<Style.Setters>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TabItem">
<Border x:Name="TabBorder" BorderThickness="1,1,1,0" BorderBrush="Transparent"
Background="{TemplateBinding Background}" TextBlock.Foreground="{TemplateBinding Foreground}">
<ContentPresenter x:Name="ContentSite" HorizontalAlignment="Center" VerticalAlignment="Center" ContentSource="Header" Margin="6,2" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style.Setters>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Trigger.Setters>
<Setter Property="Background" Value="{StaticResource SelectedDocumentTabBackgroundBrush}" />
<Setter Property="Foreground" Value="{StaticResource SelectedDocumentTabForegroundBrush}" />
</Trigger.Setters>
</Trigger>
</Style.Triggers>
</Style>
I need something like:
<Trigger Property="(Owning TabControlEx's Active property)" Value="True">
<Trigger.Setters>
...
</Trigger.Setters>
</Trigger>
Or maybe there's some other solution?
Since Active property doesn't belong to TabItem, Trigger won't work. Use DataTrigger with binding to parent:
<DataTrigger Binding="{Binding Active, RelativeSource={RelativeSource AncestorType=TabControlEx}}"
Value="True">
</DataTrigger>
I am trying to define a Style that could be used where Button holds a TextBlock as its Content and when Button has IsEnabled=False I want to set TextBlock's Foregroung color.
<Button Style="{StaticResource TransparentButtonStyle}"
IsEnabled="{Binding IsAllowed}">
<TextBlock Text="Click Me"
Style="{StaticResource HyperLinkStyle}">
</TextBlock>
</Button>
<Style x:Key="TransparentButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Background="Transparent">
<ContentPresenter/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="HyperLinkStyle" TargetType="TextBlock">
<Setter Property="Foreground" Value="Blue" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Cursor" Value="Hand" />
<Setter Property="Foreground" Value="LightBlue" />
<Setter Property="TextDecorations" Value="Underline" />
</Trigger>
</Style.Triggers>
</Style>
Can I modify the TextBlock's Style to grab the parent Button's IsEnabled value somehow to be able to set the Foreground color ?
you can just add <Trigger Property="IsEnabled" Value="False"> to your HyperLinkStyle, but I recommend you to create LinkButtonStyle instead, so you final markup fill be much cleaner:
<Button Content="Link text" Style="{StaticResource LinkButtonStyle}" />
this just makes your views much cleaner...
here's my LinkButton template:
<Style x:Key="LinkButtonStyle" TargetType="Button">
<Setter Property="Foreground" Value="{StaticResource LinkButtonText}" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<TextBlock x:Name="ContentPresenter" Background="{TemplateBinding Background}"
Text="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="ContentPresenter" Property="Foreground" Value="{DynamicResource LinkButtonDisabled}" />
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True" />
<Condition Property="IsEnabled" Value="True" />
</MultiTrigger.Conditions>
<Setter TargetName="ContentPresenter" Property="TextDecorations" Value="Underline"/>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
If you want to get to Button you can use DataTrigger with RalativeSource binding
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<!-- Setters -->
</Trigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Button}}, Path=IsEnabled}" Value="False">
<!-- Setters -->
</DataTrigger>
</Style.Triggers>
but if you want to make your Style independent of what is the parent then normal Trigger on IsEnabled property should work just as good
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<!-- Setters -->
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<!-- Setters -->
</Trigger>
</Style.Triggers>
normal Trigger should work because IsEnabled value is influenced by UIElement.IsEnabledCore which
Gets a value that becomes the return value of IsEnabled in derived classes
...
The default implementation of this property caches the value and also calculates whether the parent element of this element is enabled. (If the parent is not enabled, the child element cannot be effectively enabled in practical user interface (UI).)
so basically if parent Button is disabled child TextBlock will be disabled as well
I just want to give an initial style to my radiobutton group, before one of the radiobuttons is checked or unchecked:
<Style x:Key="RadioButtonStyle" TargetType="{x:Type RadioButton}">
<Setter Property="Foreground" Value="Red"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RadioButton}">
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="true">
<Setter Property="Foreground" Value="Blue"/>
</Trigger>
<Trigger Property="IsChecked" Value="false">
<Setter Property="Foreground" Value="Green"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
In this example, all my radiobuttons are unfortunately green, whereas I would like them to be red until the user clicks on one of them (at this point, the clicked button turns blue, and the others turn green).
How can i do that?
You just have to set the isChecked property for each RadioButton. Like this
<RadioButton GroupName="players" Grid.Column="2" Grid.Row="1" Name="hvP1" IsChecked="True"/>
<RadioButton GroupName="players" Grid.Column="2" Grid.Row="2" Name="hvP2" IsChecked="False"/>
...
I am new in WPF.
What the way to change a togglebutton behavior.
to
with black baground and no border.
Is need to use Control Template?
You have to modify the Control Template or Style to change the look and feel of the existing Control available. Have a look at this sample which is some what similar to your requirement. what i have done is i changed the Chrome (default style of windows) and created my own style with Border and content presenter. Then i have created the Triggers for the style. For visualization, in the mouseover and ischecked event i am changing background color of the Border.
<Window.Resources>
<Style x:Key="ToggleButtonStyle1" TargetType="{x:Type ToggleButton}">
<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 ToggleButton}">
<Border x:Name="border">
<ContentPresenter
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
RecognizesAccessKey="True" TextElement.Foreground="White" HorizontalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsKeyboardFocused" Value="true"/>
<Trigger Property="IsChecked" Value="true">
<Setter Property="Background" TargetName="border" Value="#FF6C6C6C"/>
<Setter Property="CornerRadius" TargetName="border" Value="5"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" TargetName="border" Value="#FF282828"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#ADADAD"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid x:Name="LayoutRoot">
<ToggleButton HorizontalAlignment="Left" Margin="136,59,0,0" Style="{DynamicResource ToggleButtonStyle1}" VerticalAlignment="Top" Width="27" Height="24" Content="-" FontSize="21.333" FontWeight="Bold" HorizontalContentAlignment="Center" Padding="0" VerticalContentAlignment="Center" IsThreeState="True"/>
</Grid>
Yes, you want to use a ControlTemplate to change how the ToggleButton looks. Take a look at the page for the ToggleButton as well as this article:
Customizing the Appearance of an Existing Control by Creating a ControlTemplate
to get you started.