wpf: add style to ComboBoxItem trough binding - wpf

I've a ComboBox and a Style for the items. The style is defined by using Style.Triggers in this way:
<Style>
<Style.Triggers>
<Trigger Property="Tag" Value="false">
<Setter Property="Background" Value="LightBlue"/>
<Setter Property="Foreground" Value="BlueViolet"/>
</Trigger>
<Trigger Property="Tag" Value="true">
<Setter Property="Background" Value="LightGreen"/>
<Setter Property="Foreground" Value="Green"/>
</Trigger>
</Style.Triggers>
</Style>
In order to embed this Style I would write next :
<ComboBox>
<ComboBoxItem Content="xxxx" Tag="true"/>
<ComboBoxItem Content="yyyy" Tag="false"/>
</ComboBox>
but how I can embed this Style in case I use DataContext binding?
Thanks in advance.

You could try adding a style setter to the ComboBox's Resources:
<ComboBox.Resources>
<Style TargetType="{x:Type ComboBoxItem}">
<Setter Property="Tag" Value="{Binding SomeValue}" />
</Style>
</ComboBox.Resources>

Related

How to set the trigger when the value does not equal to a specified value in WPF?

i would like to change the background of a ListBox to red if the SelectedIndex of ListBox greater than -1. but in xaml i only can use "=".
<ListBox.Style>
<Style TargetType="ListBox">
<Style.Triggers>
<Trigger Property="SelectedIndex" Value="-1">
<Setter Property="Background" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
</ListBox.Style>
What i want is:
<ListBox.Style>
<Style TargetType="ListBox">
<Style.Triggers>
<Trigger Property="SelectedIndex" Value>"-1">
<Setter Property="Background" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
</ListBox.Style>
Is it possible to do this in xaml?
Do it the other way round:
<ListBox.Style>
<Style TargetType="ListBox">
<Setter Property="Background" Value="Red"/>
<Style.Triggers>
<Trigger Property="SelectedIndex" Value="-1">
<Setter Property="Background" Value="Transparent"/>
</Trigger>
</Style.Triggers>
</Style>
</ListBox.Style>

WPF Opacity in a general style

I have this style that works as expected. I'm trying to generalize it for all controls.
Issue: if I replace the type ComboBox with Control. It does not work anymore.
I'm trying to avoid creating a style for each type of control.
<Style TargetType="{x:Type ComboBox}">
<Setter Property="IsEnabled" Value="{Binding Path=myProperty}"/>
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="ComboBox.Opacity" Value="1" />
</Trigger>
</Style.Triggers>
</Style>
I don't think there's a way to do exactly what you want. While this won't allow you to avoid defining styles for each type it does cut down on the duplicated code by using BasedOn to inherit the style you define once:
<Resources>
<Style x:Key="InvisibleWhenDisabled" TargetType="{x:Type Control}">
<Setter Property="IsEnabled" Value="{Binding Path=myProperty}"/>
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" Value="0" />
</Trigger>
</Style.Triggers>
</Style>
<Style TargetType="ComboBox" BasedOn="{StaticResource InvisibleWhenDisabled}"/>
<Style TargetType="Button" BasedOn="{StaticResource InvisibleWhenDisabled}"/>
</Resources>

How to inherit custom Textblock style in wpf datagrid?

I have TextBlock in the DataGridTemplateColumn in WPF Datagrid. when I check "IsEnable" false to inherit the Textblock Style inside the DatagridTemplateColumn. Here is XAML code i'm using:
<Style TargetType="{x:Type DataGrid}" >
<Setter Property="Template" >
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGrid }">
<ControlTemplate.Resources >
<Style TargetType="{x:Type TextBlock }">
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="{StaticResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</Style.Triggers>
</Style>
</ControlTemplate.Resources>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
This did not work and later i tried:
<Style TargetType="TextBlock" >
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="{StaticResource {x:Static SystemColors.GrayTextBrushKey}}" />
</Trigger>
</Style.Triggers>
</Style>
Any Thoughts on how to check if the Texblock inside the Datagrid "IsEnabled" and inherit the Style?.
WPF does not apply implicit styles inside templates unless the TargetType derives from Control. Since TextBlock doesn't derive from Control, its style is not applied. So you either have to manually apply the style to every non-Control or define the implicit style inside the template.
Define your styles inside datagrid resources as
<DataGrid.Resources>
<Style TargetType="{x:Type TextBlock}">
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="Red"/>
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.Resources>
I'm going to assume you are trying to toggle the foreground color based on the IsEnabled state of the TextBlock.
Where are you setting the IsEnabled = true Foreground color? You have not given the code for the actual TextBlock you are going to style.
Try this:
<Style TargetType="{x:Type TextBlock}">
<Style.Triggers>
<Trigger Property="IsEnabled" Value="True">
<Setter Property="Foreground" Value="Red" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="Green" />
</Trigger>
</Style.Triggers>
</Style>
If this doesn't work, it means wherever your Textblock is defined, you are doing this -
<TextBlock .... Foreground="SomeColor" />
and you need to remove the Foreground setting directly on the TextBlock so that the Foreground color can be set by the style.

wpf datagrid alternate row coloring

I have tried this method.. without luck..
<Style TargetType="{x:Type DataGridRow}">
<Style.Triggers>
<Trigger Property="ItemsControl.AlternationIndex" Value="0">
<Setter Property="Foreground" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
Is there a way to get the row Index?
I have even tried
<DataTrigger Binding="{Binding AlternationIndex}" Value="0">
<Setter Property="Foreground" Value="Green"></Setter>
</DataTrigger>
Finally, this is what I ended up with for generically setting alternate row colors.
<Style TargetType="{x:Type DataGrid}">
<Setter Property="Background" Value="#FFF" />
<Setter Property="AlternationCount" Value="2" />
</Style>
<Style TargetType="{x:Type DataGridRow}">
<Style.Triggers>
<Trigger Property="ItemsControl.AlternationIndex" Value="0">
<Setter Property="Background" Value="#CCC"></Setter>
</Trigger>
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
<Setter Property="Background" Value="#EEE"></Setter>
</Trigger>
</Style.Triggers>
</Style>
Unless already done, you have to set the AlternationCount property of DataGrid:
<DataGrid AlternationCount="2"
... />
You should additionally check whether the Foreground property is used for any Control in the DataGridRow. Try setting the Background property to test the alternation stuff.
Try setting the alternating background like this:
AlternationCount="2" AlternatingRowBackground="Bisque"
Try this
<DataGrid AlternationCount="2"
AlternatingRowBackground="Salmon" ........
Finally I used combination of Robin Maben and Th3G33k solution, because I want the alternation colour to override with my own, when some condition is met.
Thanks both.
<DataGrid x:Name="gridCustomerOrderItems" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" AutoGenerateColumns="False"
AlternationCount="2"
IsReadOnly="True" CanUserReorderColumns="True"
ScrollViewer.CanContentScroll="True"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.HorizontalScrollBarVisibility="Auto">
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Style.Triggers>
<!--first alteraniting colour-->
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
<Setter Property="Background" Value="#EEE"></Setter>
</Trigger>
<!--then override with my own colour-->
<DataTrigger Binding="{Binding InvoiceSet}" Value="True">
<Setter Property="Background" Value="Green"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>

WPF TextBox trigger to clear Text

I have many TextBox controls and I'm trying to write a style that clears the Text property when the Control is disabled.
I don't want to have Event Handlers in code behind.
I wrote this:
<Style TargetType="{x:Type TextBox}">
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Text" Value="{x:Null}" />
</Trigger>
</Style.Triggers>
</Style>
The problem is that if the TextBox is defined like:
<TextBox Text={Binding Whatever} />
then the trigger does not work (probably because it's bound)
How to overcome this problem?
Because you're explicitly setting the Text in the TextBox, the style's trigger can't overwrite it. Try this:
<TextBox>
<TextBox.Style>
<Style TargetType="{x:Type TextBox}">
<Setter Property="Text" Value="{Binding Whatever}" />
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Text" Value="{x:Null}" />
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>

Resources