On my DataGridTextColumn I would like to run a DataTrigger but only when Validation.HasError is False
This is what I have at the moment:
<DataGridTextColumn Header="Volts"
Binding="{Binding DcVolts, Converter={StaticResource StringToDecimalConverter}}"
Width="Auto">
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}"
BasedOn="{StaticResource DataGridTextColumnElementErrorStyle}">
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=Validation.HasError}"
Value="False" />
<Condition Value="False">
<Condition.Binding>
<MultiBinding Converter="{StaticResource EqualityConverter}">
<Binding Path="DcVolts" />
<Binding Path="DcSpecVolts" />
</MultiBinding>
</Condition.Binding>
</Condition>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter Property="Background" Value="Orange" />
</MultiDataTrigger.Setters>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.ElementStyle>
The thinking behind is that Validation.HasError has to be False for the MultiDataTrigger to set the BackGround to Orange if the result of the EqualityConverter is False
This is because if Validation.HasError is True then I want the usual Pink background that my DataGridTextColumnElementErrorStyle provides when a rule I have set on the Property fails.
I actually got closer with this:
<DataGridTextColumn Header="Volts"
Binding="{Binding DcVolts, Converter={StaticResource StringToDecimalConverter}}"
Width="Auto">
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}" BasedOn="{StaticResource DataGridTextColumnElementErrorStyle}">
<Style.Triggers>
<DataTrigger Value="False">
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource EqualityConverter}" >
<Binding Path="DcVolts" />
<Binding Path="DcSpecVolts" />
</MultiBinding>
</DataTrigger.Binding>
<Setter Property="Background" Value="Orange" />
</DataTrigger>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="Background" Value="Pink" />
</Trigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.ElementStyle>
But the problem was that on Validation.HasError the messages provided (by the rules I have created) in the ToolTip where duplicated.
Any advice is greatly appreciated.
You should add parentheses around the binding path since Validation.HasError is an attached property:
<Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.HasError)}"
Value="True" />
Related
I wanted to create a cell style to show errors and a text with the tooltip.
My style in the xaml dictionary file is this:
<Style TargetType="{x:Type DataGridCell}" x:Key="DataGridCellConErrores">
<Setter Property="ToolTipService.ShowOnDisabled" Value="True"/>
<Setter Property="ToolTipService.InitialShowDelay" Value="5000"/>
<Setter Property="ToolTipService.ShowDuration" Value="60000"/>
<Setter Property="ToolTip">
<Setter.Value>
<MultiBinding Converter="{StaticResource ResourceKey=dlgEnviarAlbaranCantidadParaDescontarTooltipMultivalueConverter}">
<MultiBinding.Bindings>
<Binding Path="(ap:CeldasDatagridConErroresAttachedProperty.TextoTooltip01)"/>
<Binding Path="(ap:CeldasDatagridConErroresAttachedProperty.TextoTooltip02)"/>
</MultiBinding.Bindings>
</MultiBinding>
</Setter.Value>
</Setter>
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Path=(ap:CeldasDatagridConErroresAttachedProperty.EsDatoCorrecto)}" Value="false"/>
</MultiDataTrigger.Conditions>
<Setter Property="Background" Value="Orange"/>
</MultiDataTrigger>
</Style.Triggers>
</Style>
This is how I am trying to use in my column of the datagrid:
<DataGridTextColumn Header="Cantidad Para Descontar" Binding="{Binding CantidadParaDescontar, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay, ValidatesOnDataErrors=True}" Width="AUTO" IsReadOnly="false"
ap:CeldasDatagridConErroresAttachedProperty.TextoTooltip01="{Binding Path=DescripcionCantidadParaDescontar}"
ap:CeldasDatagridConErroresAttachedProperty.TextoTooltip02="{Binding Path=MotivoCantidadParaDescontarIncorrecta}"
ap:CeldasDatagridConErroresAttachedProperty.EsDatoCorrecto="{Binding Path=EsCantidadParaDescontarCorrecta}"
CellStyle="{StaticResource DataGridCellConErrores}"/>
I can compile and run, but the text of tooltip is always empty and also it doesn't change the color of the background if the data is not correct.
How should I bind the attached properties?
Thanks.
You should bind to the attached property of the column. Try this:
<Binding Path="Column.(ap:CeldasDatagridConErroresAttachedProperty.TextoTooltip01)"/>
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}">
I want to change the row color of a DataGrid based on a boolean value. I've looked at https://stackoverflow.com/questions/18580612/wpf-datagrid-trigger-row-colour-based-on-value and tried it in a similar manner (defining the style locally instead of defining it in the usercontrol's ressources), but the row background won't change when the editable property changes. I don't know what's wrong and would be glad to have some new things to try.
<DataGrid ItemsSource="{Binding ReportSampleExaminationList}" CanUserDeleteRows="False" PreviewKeyDown="deleteRow" AutoGenerateColumns="False" HorizontalAlignment="Stretch"
RowBackground="Wheat" AlternatingRowBackground="WhiteSmoke" VerticalGridLinesBrush="Transparent" HorizontalGridLinesBrush="Gray">
<DataGrid.CellStyle >
<Style TargetType="DataGridCell">
<Style.Triggers>
<Trigger Property="IsSelected"
Value="True">
<Setter Property="Background"
Value="LightBlue" />
<Setter Property="Foreground"
Value="Black" />
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.CellStyle>
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Style.Triggers>
<DataTrigger Binding="{Binding Editable}" Value="False">
<Setter Property="Background" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
<DataGrid.Columns>
<DataGridCheckBoxColumn Header="Editable" Binding="{Binding Editable}"/>
<DataGridTextColumn Header="Probe" Binding="{Binding SampleNumber}" IsReadOnly="True" />
</DataGrid.Columns>
</DataGrid>
If you take out the RowBackground and AlternatingRowBackground from the DataGrid, it works. You will have to put those into a style for the DataGrid if you want to use them.
<DataGrid ItemsSource="{Binding ReportSampleExaminationList}" CanUserDeleteRows="False" PreviewKeyDown="deleteRow" AutoGenerateColumns="False" HorizontalAlignment="Stretch"
VerticalGridLinesBrush="Transparent" HorizontalGridLinesBrush="Gray">
<DataGrid.Style>
<Style TargetType="DataGrid">
<Setter Property="RowBackground" Value="Wheat" />
<Setter Property="AlternatingRowBackground" Value="WhiteSmoke" />
</Style>
</DataGrid.Style>
<DataGrid.CellStyle >
<Style TargetType="DataGridCell">
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="LightBlue" />
<Setter Property="Foreground" Value="Black" />
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.CellStyle>
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Style.Triggers>
<DataTrigger Binding="{Binding Editable}" Value="False">
<Setter Property="Background" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
<DataGrid.Columns>
<DataGridCheckBoxColumn Header="Editable" Binding="{Binding Editable,UpdateSourceTrigger=PropertyChanged}"/>
<DataGridTextColumn Header="Probe" Binding="{Binding SampleNumber}" IsReadOnly="True" />
</DataGrid.Columns>
</DataGrid>
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>
How can I make columns coloring in DataGrid if I also want use AlternatingRowBackground property?
I have some ideas, but it doesn't work :(.
<de:DataGrid Name="dataGrid1"
AlternationCount="2"
AlternatingRowBackground="Salmon"
>
<de:DataGrid.Columns>
<de:DataGridTextColumn Binding="{Binding Path=Phrase}"
Header="Phrase">
<de:DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Style.Triggers>
<Trigger Property="ItemsControl.AlternationIndex" Value="0">
<Setter Property="Background" Value="Green"></Setter>
</Trigger>
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
<Setter Property="Background" Value="Red"></Setter>
</Trigger>
</Style.Triggers>
</Style>
</de:DataGridTextColumn.ElementStyle>
</de:DataGridTextColumn>
</de:DataGrid.Columns>
</de:DataGrid>
Maybe somebody knows working solution? Thanks.
You are searching AlternationIndex property in the wrong control. This property belongs to DataGridRow.
<DataGrid ItemsSource="{Binding}" AlternationCount="2" AutoGenerateColumns="False" AlternatingRowBackground="Salmon">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Path=Phrase}" Header="Phrase">
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Style.Triggers>
<DataTrigger Binding="{Binding AlternationIndex, RelativeSource={RelativeSource AncestorType=DataGridRow}}" Value="0">
<Setter Property="Background" Value="Green"></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding AlternationIndex, RelativeSource={RelativeSource AncestorType=DataGridRow}}" Value="1">
<Setter Property="Background" Value="Red"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>