I am trying to collapse a column according to a condition with this code:
<DataGridTextColumn Header="MyColumn" Binding="{Binding MyProperty}">
<DataGridTextColumn.HeaderStyle>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="Width" Value="0cm"/>
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=ThisView, Path=DataContext.MyboolProperty}" Value="true">
<Setter Property="Width" Value="2.5cm"/>
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.HeaderStyle>
</DataGridTextColumn>
The problem is that the column is not complete collapsed, I can see a part of the column.
I have tried this code too:
<DataGridTextColumn Header="MyColumn" Binding="{Binding MyProperty}"
Width="0cm"
Visibility="Collapsed">
<DataGridTextColumn.HeaderStyle>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=ThisView, Path=DataContext.MyboolProperty}" Value="true">
<Setter Property="Width" Value="2.5cm"/>
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.HeaderStyle>
</DataGridTextColumn>
In this case the column is collapsed as expected, but then if the property if the trigger is true, the column is still collapsed.
Also I have tried this option:
<DataGridTextColumn Header="MyColumn" Binding="{Binding MyProperty}">
<DataGridTextColumn.HeaderStyle>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=ThisView, Path=DataContext.MyboolProperty}" Value="true">
<Setter Property="Width" Value="2.5cm"/>
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
<DataTrigger Binding="{Binding ElementName=ThisView, Path=DataContext.MyboolProperty}" Value="false">
<Setter Property="Width" Value="0cm"/>
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.HeaderStyle>
</DataGridTextColumn>
But the behavior is the same than first option, it is not full collapsed but it works when the property of the trigger is true.
Your data trigger is located inside column header template, therefore it can only change properties of column header (not a complete column, i.e. cells).
There is no Style for DataGridTextColumn, so you can't use DataTrigger. But converter should do.
However, another problem is that columns aren't in visual tree, so you can't use ElementName or RelativeSource, they simply won't work. There is an easy workaround however. Then your column will look like this:
<Window.Resources>
<BooleanToVisibilityConverter x:Key="converter" />
<local:BindingProxy x:Key="proxy" Data="{Binding}" />
</Window.Resources>
...
<DataGridTextColumn Header="MyColumn"
Binding="{Binding MyProperty}"
Visibility="{Binding Data.MyboolProperty, Source={StaticResource proxy}, Converter={StaticResource converter}}" />
Related
I am currently working on a small c# wpf project. I fill my datagrid programmatically and I want to change one cells color in the style without affecting the whole row. I do this after changing the DataGrid Rowstyle.
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Gebucht}" Value="True">
<Setter Property="Background" Value="Green"/>
</DataTrigger>
<DataTrigger Binding="{Binding Path=dringendeBuchung}" Value="True">
<Setter Property="Background" Value="Yellow"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
<DataGrid.CellStyle>
<Style TargetType="DataGridCell">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Dringend}" Value="True">
<Setter Property="Background" Value="Red"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.CellStyle>
The rowstyle works fine, but if for example "Gebucht" is true and Dringend is true too I want to display the whole row in green except for the Cell which has the Dringend boolean.
Thank you for your help
The rowstyle works fine, but if for example "Gebucht" is true and Dringend is true too I want to display the whole row in green except for the Cell which has the Dringend boolean.
Then you should set the CellStyle property of the specific column instead of setting the CellStyle property for the entire DataGrid, e.g.:
<DataGrid ... >
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Gebucht}" Value="True">
<Setter Property="Background" Value="Green"/>
</DataTrigger>
<DataTrigger Binding="{Binding Path=dringendeBuchung}" Value="True">
<Setter Property="Background" Value="Yellow"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Dringend}" Header="Dringend">
<DataGridTextColumn.CellStyle>
<Style TargetType="DataGridCell">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Dringend}" Value="True">
<Setter Property="Background" Value="Red"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.CellStyle>
</DataGridTextColumn>
<!-- + other columns... -->
</DataGrid.Columns>
</DataGrid>
I have this DataGrid and I have been playing with setting the background colour of selected cells:
<DataGridTextColumn Header="Next Study" Binding="{Binding NextStudy}">
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Style.Triggers>
<Trigger Property="Text" Value="25">
<Setter Property="Background" Value="Red"/>
</Trigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.ElementStyle>
<DataGridTextColumn.CellStyle>
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="ToolTip" Value="{Binding NextStudyDescription}" />
</Style>
</DataGridTextColumn.CellStyle>
</DataGridTextColumn>
It works as you can see:
But that is not really what I want. Instead I would like to highlight all cells where the value is greater than or equal to 18. So I tried:
<DataGridTextColumn Header="Next Study" Binding="{Binding NextStudy}">
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Style.Triggers>
<DataTrigger Binding="{NextStudy Converter={StaticResource IsEqualOrGreaterThanConverter}, ConverterParameter=18}" Value="True">
<Setter Property="Background" Value="Red"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.ElementStyle>
<DataGridTextColumn.CellStyle>
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="ToolTip" Value="{Binding NextStudyDescription}" />
</Style>
</DataGridTextColumn.CellStyle>
</DataGridTextColumn>
It doesn't like: <DataTrigger Binding="{NextStudy
In addition, I would like to do this background test if the element comboActiveStudentAssignmentType selected index is 0, 1 or 2. Otherwise it does not need to do this highlighting.
Thanks.
You have a syntax error: Binding is the property name, you still have to declare it as a Binding
<DataTrigger Binding="{Binding NextStudy, Converter={StaticResource IsEqualOrGreaterThanConverter}, ConverterParameter=18}" Value="True">
As for the second part of the question, you can use a MultiDataTrigger. The conditions in the MultiDataTrigger have to ALL be true for the trigger to execute the setters. You will probably need to write another converter to transform your AssignmentType to True/False and you should be set.
Here's a quick example:
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding NextStudy, Converter={StaticResource IsEqualOrGreaterThanConverter}, ConverterParameter=18}" Value="True"/>
<Condition Binding="{Binding comboActiveStudentAssignmentType, Converter={StaticResource YourOtherConverter}" Value="True"/>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter Property="Background" Value="Red"/>
</MultiDataTrigger.Setters>
</MultiDataTrigger>
I'm trying to get up to speed on how to use DataTriggers on a DataGrid.
I have four columns in my datatable (Node, Name, Value, Flag). Flag is a hidden column in the datagrid.
I would the DataGridRow to have PaleGreen background when Flag = 2 but the Value column should be red. I know that I can create a style for the flag column as thats not vislible this isn't helpful.
Sorry if this is a newbie question. First foray into wpf from WinForms.
What I have so far:
<Style TargetType="{x:Type DataGridRow}">
<Style.Triggers>
<DataTrigger Binding="{Binding Flag}" Value="2">
<Setter Property="Background" Value="PaleGreen" />
<Setter Property="Foreground" Value="Black" />
</DataTrigger>
<DataTrigger Binding="{Binding Flag}" Value="3">
<Setter Property="Background" Value="CadetBlue" />
<Setter Property="Foreground" Value="White" />
</DataTrigger>
</Style.Triggers>
</Style>
Figured it out. Code for completeness
<UserControl.Resources>
<Style TargetType="{x:Type DataGridRow}">
<Style.Triggers>
<DataTrigger Binding="{Binding Flag}" Value="2">
<Setter Property="Background" Value="PaleGreen" />
<Setter Property="Foreground" Value="Black" />
</DataTrigger>
<DataTrigger Binding="{Binding Flag}" Value="3">
<Setter Property="Background" Value="CadetBlue" />
<Setter Property="Foreground" Value="White" />
</DataTrigger>
</Style.Triggers>
</Style>
<Style TargetType="DataGridCell" x:Key="ValueColumn">
<Style.Triggers>
<DataTrigger Binding="{Binding Flag}" Value="2">
<Setter Property="Background" Value="Red" />
<Setter Property="Foreground" Value="White" />
</DataTrigger>
</Style.Triggers>
</Style>
</UserControl.Resources>
<DataGrid>
<DataGrid.Columns>
<DataGridTextColumn Header="Node" Binding="{Binding Path=Node}"/>
<DataGridTextColumn Header="Name" Binding="{Binding Path=Name}"/>
<DataGridTextColumn MinWidth="300" Header="Value" Binding="{Binding Path=Value}" CellStyle="{StaticResource ValueColumn}"/>
<DataGridTextColumn Header="Flag" Binding="{Binding Path=Flag}" Visibility="Hidden" />
</DataGrid.Columns>
</DataGrid>
I have the following DataGrid
<DataGrid x:Name="cultureDataGrid"
Grid.Row="1"
CellStyle="{StaticResource DataGridCell}"
ItemsSource="{Binding Cultures,
NotifyOnSourceUpdated=True,
UpdateSourceTrigger=PropertyChanged,
Mode=TwoWay,
IsAsync=True}"
Style="{x:Null}" >
<DataGrid.Columns>
<DataGridTextColumn Header="Code" Binding="{Binding Code}" IsReadOnly="True"/>
<DataGridTextColumn Header="Language" Binding="{Binding Language}" IsReadOnly="True"/>
<DataGridTextColumn Header="LocalName" Binding="{Binding LocalName}" IsReadOnly="True"/>
</DataGrid.Columns>
</DataGrid>
I have the following cell style to change the selected Backcolor
<Style TargetType="DataGridCell" BasedOn="{StaticResource {x:Type DataGridCell}}">
<Setter Property="Background" Value="White"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="Red"/>
<Setter Property="Foreground" Value="White"/>
</Trigger>
</Style.Triggers>
</Style>
I have tried applying the CellStyle="{StaticResource DataGridCell}" as shown above, and using DynamicResource but the resource is failing to be resolved. I have imported the correct resource dictionary as other styles are working What am I doing wrong here?
Thanks for your time.
Since your Style has no Key you do not have to set CellStyle on the DataGrid, it will be applied to all DataGridCell by default.
If you dont want it applied to all DataGridCell by default give the style an x:Key and set the CellStyle on the DataGrid
Example:
<Style x:Key="MyDataGridCell" TargetType="DataGridCell" BasedOn="{StaticResource {x:Type DataGridCell}}">
<Setter Property="Background" Value="White"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="Red"/>
<Setter Property="Foreground" Value="White"/>
</Trigger>
</Style.Triggers>
</Style>
<DataGrid CellStyle="{StaticResource MyDataGridCell}" />
To apply the style to only some DataGridRow :
Create your DataGridCell style :
< !-- DataGridCell Style-->
< Style x:Key="MyDataGridCellStyle" TargetType="{x:Type DataGridCell}">
<Setter Property="Background" Value="White"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="Red"/>
<Setter Property="Foreground" Value="White"/>
</Trigger>
</Style.Triggers>
</Style>
Use it in the column you want
< !-- DataGrid -->
<DataGrid >
<DataGrid.Columns>
<DataGridComboBoxColumn CellStyle="{StaticResource MyDataGridCellStyle}" />
<DataGridTextColumn CellStyle="{StaticResource MyDataGridCellStyle}" />
</DataGrid.Columns>
</DataGrid>
I have a question on this WPF-xaml code. Haven't used xaml alot but manage to get quite what I wanted with this code. But I feel that it isn't good practise at all. First, I would like to change the row from red to green or gray depending on some values in a certain cell. Do I really have to keep one trigger for each cell, or is there anyway to do the same trigger on the whole row? I would also like to set a specific color when a row is selected, but the style doesn't seem to support "IsSelected"...
<DataGrid AutoGenerateColumns="False" IsReadOnly="True" HorizontalAlignment="Stretch" Margin="200,50,5,5" ItemsSource="{Binding}" Name="dataGrid1" VerticalAlignment="Stretch" EnableRowVirtualization="True" SelectionChanged="dataGrid1_SelectionChanged" MouseDoubleClick="dataGrid1_MouseDoubleClick">
<DataGrid.Columns>
<DataGridTextColumn Width="1*" Header="File name" Binding="{Binding Path=Filename}">
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Background" Value="#68FF0000" />
<Style.Triggers>
<DataTrigger Binding="{Binding Errorcode}" Value="0">
<Setter Property="Background" Value="LightGreen"/>
</DataTrigger>
<DataTrigger Binding="{Binding Filename}" Value="File not created">
<Setter Property="Background" Value="LightGray" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<DataGridTextColumn Width="1*" Header="Weight" Binding="{Binding Path=Info1}">
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Background" Value="#68FF0000" />
<Style.Triggers>
<DataTrigger Binding="{Binding Errorcode}" Value="0">
<Setter Property="Background" Value="LightGreen" />
</DataTrigger>
<DataTrigger Binding="{Binding Filename}" Value="File not created">
<Setter Property="Background" Value="LightGray" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<DataGridTextColumn Width="1*" Header="Rfid" Binding="{Binding Path=Info1}">
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Background" Value="#68FF0000" />
<Style.Triggers>
<DataTrigger Binding="{Binding Errorcode}" Value="0">
<Setter Property="Background" Value="LightGreen" />
</DataTrigger>
<DataTrigger Binding="{Binding Filename}" Value="File not created">
<Setter Property="Background" Value="LightGray" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<DataGridTextColumn Width="1*" Header="Date/Time" Binding="{Binding Datetime, StringFormat=\{0:yyyy.MM.dd HH:mm:ss\}}">
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Background" Value="#68FF0000" />
<Style.Triggers>
<DataTrigger Binding="{Binding Errorcode}" Value="0">
<Setter Property="Background" Value="LightGreen" />
</DataTrigger>
<DataTrigger Binding="{Binding Filename}" Value="File not created">
<Setter Property="Background" Value="LightGray" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<DataGridTextColumn Width="1*" Header="Error code" Binding="{Binding Path=Errorcode}">
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Background" Value="#68FF0000" />
<Style.Triggers>
<DataTrigger Binding="{Binding Errorcode}" Value="0">
<Setter Property="Background" Value="LightGreen" />
</DataTrigger>
<DataTrigger Binding="{Binding Filename}" Value="File not created">
<Setter Property="Background" Value="LightGray" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
I'm not very experienced with DataGrid, so this might not be the best option, but I think you can achieve what you're after by styling the Row, rather than the individual Columns:
<DataGrid <!-- Your settings here -->>
<!-- Your column definitions here -->
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Errorcode}" Value="0">
<Setter Property="Background" Value="LightGreen" />
<!-- Other Setters -->
</DataTrigger>
<DataTrigger Binding="{Binding Path=Filename}" Value="File not created">
<Setter Property="Background" Value="LightGray" />
</DataTrigger>
<!-- Other Triggers -->
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="Red" />
<!-- Other Setters -->
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
</DataGrid>
Good luck.