DataTrigger setter doesn't fire up - wpf

I have a two radioButtons and two textboxs
<RadioButton x:Name="AdmLnkRadio1" GroupName="AdmLnkgr1" Content="Link #1"/>
<RadioButton x:Name="AdmLnkRadio2" GroupName="AdmLnkgr1" Content="Link #2"/>
<TextBox x:Name="AdmLnkTextBoxName1" />
<TextBox x:Name="AdmLnkTextBoxName2" IsEnabled="False" >
<TextBox.Style>
<Style BasedOn="{StaticResource TextBoxBase}" TargetType="TextBox" >
<Style.Triggers>
<!--Trigger 1 -->
<DataTrigger Binding="{Binding ElementName=AdmLnkRadio1, Path=IsChecked}" Value="True">
<Setter Property="Text" Value="{Binding ElementName=AdmLnkTextBoxName1, Path=Text}"></Setter>
<Setter Property="IsEnabled" Value="False"></Setter>
</DataTrigger>
<!--Trigger 2 - Doesn't Fires UP!!!! -->
<DataTrigger Binding="{Binding ElementName=AdmLnkRadio2, Path=IsChecked}" Value="True">
<Setter Property="Text" Value=""></Setter>
<Setter Property="IsEnabled" Value="True"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
When user checks radiobutton 1 the trigger 1 works and second textbox text binds to the text of the first one. But when the second radiobutton is checked, the second trigger should fire up, but it doesn't. Thanks for any help

It does fire but because you're setting IsEnabled to fixed False value your style does not override it (Dependency Property Setting Precedence List). Try setting IsEnabled in your Style, like this
<TextBox x:Name="AdmLnkTextBoxName1" />
<TextBox x:Name="AdmLnkTextBoxName2">
<TextBox.Style>
<Style TargetType="TextBox" >
<Setter Property="IsEnabled" Value="False"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=AdmLnkRadio1, Path=IsChecked}" Value="True">
<Setter Property="Text" Value="{Binding ElementName=AdmLnkTextBoxName1, Path=Text}"/>
<Setter Property="IsEnabled" Value="False"/>
</DataTrigger>
<DataTrigger Binding="{Binding ElementName=AdmLnkRadio2, Path=IsChecked}" Value="True">
<Setter Property="Text" Value=""/>
<Setter Property="IsEnabled" Value="True"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>

Related

How to change the text color for an unchecked row in xaml

I would like to gray out the text associated to an unchecked row in my application using xaml. I tried the following, but it is getting overwritten:
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox Name="cbkSelect"
IsChecked="{Binding Path=IsSelectedForOrder, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<CheckBox.Style>
<Style TargetType="{x:Type CheckBox}">
<Setter Property="Visibility" Value="Hidden"/>
<Style.Triggers>
<Trigger Property="IsChecked" Value="False">
<Setter Property="Foreground" Value="Gray"/>
</Trigger>
<DataTrigger Binding="{Binding IsMouseOver, RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}}}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</CheckBox.Style>
</CheckBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
As the Foreground color should be applied to all cells of a given row, you can remove the trigger. The trigger inside the CellTemplate will only apply to to the CheckBox that the style is applied to.
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox Name="cbkSelect"
IsChecked="{Binding Path=IsSelectedForOrder, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<CheckBox.Style>
<Style TargetType="{x:Type CheckBox}">
<Setter Property="Visibility" Value="Hidden"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsMouseOver, RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}}}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</CheckBox.Style>
</CheckBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
If you want to apply the foreground color in normal state, but not in selected state, add this RowStyle.
<DataGrid.RowStyle>
<Style TargetType="{x:Type DataGridRow}" BasedOn="{StaticResource {x:Type DataGridRow}}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsSelectedForOrder}" Value="True">
<Setter Property="Foreground" Value="Gray"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
If you want to apply the style in selected state, too, add this CellStyle. In this case a RelativeSource binding is used to access the data context of the row which contains IsSelectedForOrder.
<DataGrid.CellStyle>
<Style TargetType="{x:Type DataGridCell}" BasedOn="{StaticResource {x:Type DataGridCell}}">
<Style.Triggers>
<DataTrigger Binding="{Binding DataContext.IsSelectedForOrder, RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}}}" Value="True">
<Setter Property="Foreground" Value="Gray"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.CellStyle>

CheckBox text to change based on its IsChecked

I want a CheckBox text to changed based on the IsChecked status.
Tried with the following, but it complains about not having the property Content
<CheckBox Name="IsManualInput" IsChecked="{Binding Path=IsManual, Mode=TwoWay}" >
<CheckBox.Style>
<Style>
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsChecked}" Value="True" >
<Setter Property="Content" Value="Manual" />
<Setter Property="IsReadOnly" Value="True"/>
</DataTrigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsChecked}" Value="True" >
<Setter Property="Content" Value="Define manually..." />
<Setter Property="IsReadOnly" Value="True"/>
</DataTrigger>
</Style.Triggers>
</Style>
</CheckBox.Style>
</CheckBox>
It's a simple mistake, you need to include TargetType in your Style.
e.g.
<Style TargetType="{x:Type CheckBox}">

Why is this DataTrigger not working after a PropertyChanged?

The following triggers work almost as expected:
<Style.Triggers>
<Trigger Value="True" Property="IsSelected">
<Setter Property="Foreground" Value="White" />
</Trigger>
<DataTrigger Value="True" Binding="{Binding UpdateSourceTrigger=PropertyChanged, Converter={StaticResource InUseConverter}}">
<Setter Property="Foreground" Value="OrangeRed" />
</DataTrigger>
</Style.Triggers>
After loading the view, the colors are correct.
Then I execute an async taks en when it has finished I give the propertychanged on the object that has the binding to my datagrid-row.
But why is the DataTrigger not fired (I have to refresh the view to see the effect)?
EDIT:
My problem is that I don't now which property I have to give the PropertyChanged.
Some details about the datagrid (Projects is an ObservableCollection):
DataGrid SelectedItem="{Binding Project}" ItemsSource="{Binding Projects}">
The property of object Project that the binding must use is:
Project.Variants[0].InUse
I tried also the triggers:
<DataTrigger Value="True" Binding="{Binding Path=Variants[0].InUse, Converter={StaticResource NotNullConverter}}">
<DataTrigger Value="True" Binding="{Binding Path=., Converter={StaticResource InUseConverter}}">
In the view model I have tried after Project.Variants[0].InUse = null;:
Project.OnPropertyChanged("InUse");
Project.Variants[0].OnPropertyChanged("InUse");
raisePropertyChanged("Project.Variants[0].InUse");
raisePropertyChanged("Variants[0].InUse");
raisePropertyChanged("Projects");
raisePropertyChanged("Project");
raisePropertyChanged("InUse");
At last it works using:
<DataTrigger Value="True" Binding="{Binding Path=Variants[0].InUse, Converter={StaticResource NotNullConverter}}">
<Setter Property="Foreground" Value="OrangeRed" />
</DataTrigger>
Project.Variants[0].OnPropertyChanged("InUse");
Try to set Foreground property in your style to change it dynamically at runtime
<Setter Property="Foreground" Value="White"/>
<Style.Triggers>
<Trigger Value="True" Property="IsSelected">
<Setter Property="Foreground" Value="White" />
</Trigger>
<DataTrigger Value="True" Binding="{Binding UpdateSourceTrigger=PropertyChanged, Converter={StaticResource InUseConverter}}">
<Setter Property="Foreground" Value="OrangeRed" />
</DataTrigger>
</Style.Triggers>

WPF listview. How to support simultaneously row background color and alternateIndex for this row

I have a listview that contains log messages. I want to set the background color for each row in listview according to the severity of its corresponding entry. I do this using DataTrigger (see the example).
I would also like to support AlternationIndex for listview.
How can I combine them in xaml DataTrigger abd Trigger for background color of row?
For set background color for row I use the following code:
<ListView ... >
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Severity} Value="Info">
<Setter
Property="Background"
Value="{Binding Path=Severity,
Converter=
{StaticResource msgSeverityToColorConverter}}"
/>
</DataTrigger>
<DataTrigger Binding="{Binding Path=Severity} Value="Error">
<Setter
Property="Background"
Value="{Binding Path=Severity,
Converter=
{StaticResource msgSeverityToColorConverter}}"
/>
</DataTrigger>
</Style.Triggers>
</Style>
</ListView.ItemContainerStyle>
</ListView>
And for AlternateIndex I have the following code:
<Style.Triggers>
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
<Setter Property="Background" Value="LightBlue"></Setter>
</Trigger>
<Trigger Property="ItemsControl.AlternationIndex" Value="2">
<Setter Property="Background" Value="LightGray"></Setter>
</Trigger>
</Style.Triggers>
I need that when row with message is not Info or Error, it will be of color from AlternationIndex property.
It's all due to order of declarations of triggers. First declare the alternation triggers and then the severity triggers.
<Style.Triggers>
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
<Setter Property="Background" Value="LightBlue"></Setter>
</Trigger>
<Trigger Property="ItemsControl.AlternationIndex" Value="2">
<Setter Property="Background" Value="LightGray"></Setter>
</Trigger>
<DataTrigger Binding="{Binding Path=Severity} Value="Info">
<Setter Property="Background"
Value="{Binding Path=Severity,
Converter="{StaticResource msgSeverityToColorConverter}}" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=Severity} Value="Error">
<Setter Property="Background"
Value="{Binding Path=Severity,
Converter="{StaticResource msgSeverityToColorConverter}}" />
</DataTrigger>
</Style.Triggers>

Why can't I use a DataTrigger to set TextBox.IsEnabled = True?

In my application, I have a TextBox that I want to enable/disable based on an enum in my datacontext. The enum has three values (Anyone, Me, Someone) and I want to enable the Textbox when the value "Someone" is set. I am able to hack a solution by setting the value in reverse (see below). However, can someone please explain why the first solution didn't work?
This does not work...
<TextBox Text="{Binding ModifiedUser, UpdateSourceTrigger=PropertyChanged}"
IsEnabled="False">
<TextBox.Style>
<Style TargetType="{x:Type TextBox}">
<Style.Triggers>
<DataTrigger Binding="{Binding ModifiedBy}"
Value="Someone">
<Setter Property="IsEnabled"
Value="True" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
Strangely, this code does work.
<TextBox Text="{Binding ModifiedUser, UpdateSourceTrigger=PropertyChanged}">
<TextBox.Style>
<Style TargetType="{x:Type TextBox}">
<Style.Triggers>
<DataTrigger Binding="{Binding ModifiedBy}"
Value="Anyone">
<Setter Property="IsEnabled"
Value="False" />
</DataTrigger>
<DataTrigger Binding="{Binding ModifiedBy}"
Value="Me">
<Setter Property="IsEnabled"
Value="False" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
you have to set the initial isEnabled in your style too. otherwise your "local" IsEnabled=false will always win!
change your style and it will work.
<TextBox Text="{Binding ModifiedUser, UpdateSourceTrigger=PropertyChanged}">
<TextBox.Style>
<Style TargetType="{x:Type TextBox}">
<Setter Property="IsEnabled" Value="False" />
<Style.Triggers>
<DataTrigger Binding="{Binding ModifiedBy}"
Value="Someone">
<Setter Property="IsEnabled"
Value="True" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>

Resources