I have this textblock with default foreground color is white
<TextBlock Text="First Cmd" Grid.Row="0" TextAlignment="Center" Margin="4" TextWrapping="Wrap" Foreground="White" Style="{DynamicResource ABC}">
<TextBlock.InputBindings>
<MouseBinding Command="{Binding AAA}" MouseAction="LeftClick" />
</TextBlock.InputBindings>
</TextBlock>
When the mouse is over the textblock, the forground color must change in black, but this Style doesn't work. Why ?
<Style x:Key="ABC" TargetType="{x:Type TextBlock}">
<Style.Triggers>
<Trigger Property ="IsMouseOver" Value="True">
<Setter Property= "Foreground" Value="Black">
</Trigger>
</Style.Triggers>
</Style>
You set the Foreground for TextBlock locally, so the Trigger setter cannot override that. You need to use a Style setter to set the initial Foreground:
<Style x:Key="ABC" TargetType="{x:Type TextBlock}">
<Setter Property="Foreground" Value="White"/>
<Style.Triggers>
<Trigger Property ="IsMouseOver" Value="True">
<Setter Property= "Foreground" Value="Black">
</Trigger>
</Style.Triggers>
</Style>
The Foreground="White" should be removed from the <TextBlock ....
Understand more about Dependency Property Value Precedence.
Related
I want to know how to change the WrapPanel orientation property by triggers.
I use trigger to change the wrap panel orientation property, but it doesn't work.
<WrapPanel Orientation="Horizontal">
<WrapPanel.Style>
<Style TargetType="WrapPanel">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" Value="Red"/>
<Setter Property="Orientation" Value="Vertical"/>
</Trigger>
</Style.Triggers>
</Style>
</WrapPanel.Style>
<Button Content="button1" Margin="10"/>
<Button Content="button2" Margin="10"/>
</WrapPanel>
I expect the button to be Vertical and the background to be Red, but the result is Horizontal button and Red background. Background is changed right, but orientation is not changed.
set default Orientation value via Style Setter. Orientation="Horizontal" is a local value, which cannot be reset by Style Trigger
<WrapPanel>
<WrapPanel.Style>
<Style TargetType="WrapPanel">
<Setter Property="Orientation" Value="Horizontal"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" Value="Red"/>
<Setter Property="Orientation" Value="Vertical"/>
</Trigger>
</Style.Triggers>
</Style>
</WrapPanel.Style>
<Button Content="button1" Margin="10"/>
<Button Content="button2" Margin="10"/>
</WrapPanel>
I have the following style:
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock x:Name="Text" Text="{Binding Name}" Margin="0, 5" FontSize="16"/>
</DataTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
I want to change the foreground color of "Text" if the "ListBoxItem" is selected. I know from here: Change WPF DataTemplate for ListBox item if selected how to change the DataTemplate. but since I just want to change colors, this solution makes unnecessary duplication in codd - It would be a greater problem if my DataTemplate would be very complex and long.
How do I achieve change of a single property of an object inside the DataTemplate?
If you actually want the same item template always (whether the item is selected or not), but you want a different foreground color when the item is selected, that's easy. Don't set the ContentTemplate in a trigger, because ContentTemplate doesn't change. Just set the foreground color with a trigger. If you don't mess with the foreground color in the template, it will inherit whatever the ListBoxItem has for that property.
<Style TargetType="ListBoxItem">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock
x:Name="Text"
Text="{Binding Name}"
Margin="0, 5"
FontSize="16"
/>
</DataTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Foreground" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
A more elaborate version of the same style:
<Style TargetType="ListBoxItem">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Ellipse
Height="12"
Width="12"
VerticalAlignment="Center"
x:Name="Ellipse"
Fill="Yellow"
Stroke="DeepSkyBlue"
StrokeThickness="1"
/>
<TextBlock
x:Name="Text"
Text="{Binding Name}"
Margin="5,5,0,5"
FontSize="16"
/>
</StackPanel>
<DataTemplate.Triggers>
<DataTrigger
Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType=ListBoxItem}}"
Value="True"
>
<Setter
TargetName="Ellipse"
Property="Stroke"
Value="Orange"
/>
<Setter
TargetName="Ellipse"
Property="StrokeThickness"
Value="3"
/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Foreground" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
I've got the following pure XAML:
<DockPanel>
<ComboBox Name="combo" Height="24" Width="60">
<Border Background="Gray" Padding="20,10">
<Border.Style>
<Style TargetType="Border">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=combo, Path=IsDropDownOpen}" Value="True">
<Setter Property="Background" Value="Red"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
</Border>
</ComboBox>
<TextBlock Text="{Binding ElementName=combo, Path=IsDropDownOpen}"></TextBlock>
</DockPanel>
I would expect the datatrigger to change the background colour of the border object to red as soon as the combobox is opened, but instead nothing happens.
Since you have set the background property directly on the ComboBox the trigger is not going to override that value.
This behavior is explained on MSDN.
You have to set it in the style instead like this:
<Border Padding="20,10">
<Border.Style>
<Style TargetType="Border">
<Setter Property="Background" Value="Gray" />
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=combo, Path=IsDropDownOpen}" Value="True">
<Setter Property="Background" Value="Red"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
</Border>
I am going crazy here! What am I missing and why it is not styling anything:
<Style x:Key="textBoxStyle" TargetType="{x:Type TextBox}">
<Style.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter Property="Background" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
<TextBox Width="100" Style="{StaticResource textBoxStyle}" Height="20" Background="Yellow" ></TextBox>
The above code does not do anything. It does not highlight the TextBox control!
This occurs because local values override style values. (Properties set directly on an element have very high precedence.) You are setting Background directly on the TextBox, so WPF is going, "Well, he normally wants textBoxStyle backgrounds to be Red when focused, but for this particular TextBox, he's said he specifically wants Background to be Yellow, so Yellow it is."
So the fix is to move the Yellow background to be part of the Style:
<Style x:Key="textBoxStyle" TargetType="{x:Type TextBox}">
<Setter Property="Background" Value="Yellow" />
<Style.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter Property="Background" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
and remove it from the TextBox:
<TextBox Width="100" Style="{StaticResource textBoxStyle}" Height="20" />
Define your Style before the TextBox or use DynamicResource instead of StaticResource
I have a custom window which have two depencency properties: Boolean? ValidationStatus, and string ValidationMessage. Binding these properties works fine but trigger doesn't seem to be triggered when these values change. What am I doing wrong?
<TextBlock x:Name="validationTextBox"
Grid.Row="1"
Grid.ColumnSpan="2"
Text="{Binding ElementName=_this, Path=ValidationMessage}"
TextAlignment="Center"
Background="Green">
<TextBlock.Style>
<Style>
<Style.Triggers>
<DataTrigger Value="False" Binding="{Binding ElementName=_this, Path=ValidationStatus}">
<Setter Property="Panel.Background" Value="Red"/>
<Setter Property="TextBox.Text" Value="Outer checkbox is not checked"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
Style Setters do not override local attribute settings. Therefore the data trigger's values are being ignored because you have specified the Text and Background properties on the TextBlock. To fix the problem set the default values of these properties in the style as shown in the following code:
<TextBlock x:Name="validationTextBox"
Grid.Row="1"
Grid.ColumnSpan="2"
TextAlignment="Center">
<TextBlock.Style>
<Style>
<Setter Property="TextBox.Text" Value="{Binding ElementName=_this, Path=ValidationMessage}"/>
<Setter Property="TextBox.Background" Value="Green"/>
<Style.Triggers>
<DataTrigger Value="False" Binding="{Binding ElementName=_this, Path=ValidationStatus}">
<Setter Property="TextBox.Background" Value="Red"/>
<Setter Property="TextBox.Text" Value="Outer checkbox is not checked"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>