I cannot say that I am new to WPF, because it would be too much. I just was given with WPF app to maintain...
I need to change particular cell color in DataGrid
based on a value. I thought it would be easy, found that SO post: Change DataGrid cell colour based on values
.
Pasted where it belongs, which gave me the following:
<DataGrid x:Name="DgDevices" ItemsSource="{Binding}" BorderThickness="2,0,2,2" Cursor="Cross">
<DataGrid.ContextMenu>
<ContextMenu >
<MenuItem Header="Załóż Deblokadę" Click="InsertDBL" />
<MenuItem Header="Usuń Deblokadę" Click="RemoveDBL"/>
</ContextMenu>
</DataGrid.ContextMenu>
<DataGridTextColumn Binding="{Binding Name}">
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Style.Triggers>
<Trigger Property="Text" Value="1">
<Setter Property="Background" Value="Black"/>
<Setter Property="Foreground" Value="White"/>
</Trigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
</DataGrid>
Now, when invoking Show
method on this form, it gives me InvalidOperationException
. I searched for explanation why this happens, but haven't found clear explanation.
Also, I know that Binding Name
is placeholder for my binding (in <DataGridTextColumn Binding="{Binding Name}">
), so I tired putting just Binding
there (inspired by ItemsSource="{Binding}"
in DataGrid
node), but didn't solve the issue.
You are now adding DataGridTextColumn
right into DataGrid
itself, not to its columns list. Adding items directly and using ItemsSource
are mutually exclusive, so InvalidOperationException
is thrown (and you didn't intend to add column as item anyway). Instead, do it like this:
<DataGrid x:Name="DgDevices"
ItemsSource="{Binding}"
BorderThickness="2,0,2,2"
AutoGenerateColumns="False"
Cursor="Cross">
<DataGrid.ContextMenu>
<ContextMenu >
<MenuItem Header="Załóż Deblokadę" Click="InsertDBL" />
<MenuItem Header="Usuń Deblokadę" Click="RemoveDBL"/>
</ContextMenu>
</DataGrid.ContextMenu>
<DataGrid.Columns> <!-- add to columns -->
<DataGridTextColumn Binding="{Binding Name}">
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Style.Triggers>
<Trigger Property="Text"
Value="1">
<Setter Property="Background"
Value="Black" />
<Setter Property="Foreground"
Value="White" />
</Trigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
Also, because you need to set AutoGenerateColumns
to False
, because otherwise DataGrid
will automatically generate columns from your data source, in addition to columns you define manually, and you rarely need that.