I've written some code to try and change the color of a DataGrid cell based on the length of the value inside the cell. However it appears to work correctly when it loads in the first few rows however when i scroll down past the rows in view it seems to randomly change colour.

My XML behind this is:

  <DataGrid  Grid.Row="2" Name="DataGridView1" CanUserSortColumns="False" CanUserReorderColumns="False" IsReadOnly="True" ItemsSource="{Binding}" Background="LightGray" RowBackground="#BDBDBF" AlternatingRowBackground="#E3E3E5" CellStyle="{StaticResource CellStyle}">

My 'CellStyle' Resource is

 <local:ValueToBrushConverter x:Key="ValueToBrushConverter"/>
    <Style x:Key="CellStyle" TargetType="DataGridCell">
        <Setter Property="Background" Value="{Binding RelativeSource={RelativeSource Self}, Converter={StaticResource ValueToBrushConverter}}" />
    </Style>

And finally my ValueToBrushConverter is:

 public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        DataGridCell dgc = (DataGridCell)value;
        System.Data.DataRowView rowView = (System.Data.DataRowView)dgc.DataContext;
        var input = rowView.Row.ItemArray[dgc.Column.DisplayIndex];
        StreamWriter sw = new StreamWriter(@"C:\DM Data\Inputs.txt",true);
        sw.WriteLine(input + "      " + input.ToString().Length);
        sw.Close();
        sw.Dispose();
        if (input.ToString().Length < 32)
            return new SolidColorBrush(Colors.LimeGreen);
        else if (input.ToString().Length >= 32)
            return (SolidColorBrush)(new BrushConverter().ConvertFrom("#FF1616"));
        else
            return new SolidColorBrush(Colors.Black);

    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotSupportedException();
    }

Note the streamwriter is merely for my testing to see what the values are returning.

As said the code works initially but after stops working, this gif shows what i mean

https://gyazo.com/099873b8738887bddaf418c3b45129e3

You can see some values that should not be highlighted become highlighted and visa versa

This is because of the UI virtualization, i.e. the item containers are reused as you scroll through the items.

You can disable this by setting VirtualizingStackPanel.VirtualizationMode attached property to Standard, at the potential cost of some scrolling performance:

<DataGrid ... VirtualizingStackPanel.VirtualizationMode="Standard">

what is the actual difference between Recycling/Standard of VirtualizationMode property in VirtualizingStackPanel?

A better option would be to use a specific CellStyle for each column that binds to the actual source property of the item, e.g.:

<DataGridTextColumn Binding="{Binding Name}">
    <DataGridTextColumn.CellStyle>
        <Style TargetType="DataGridCell">
            <Setter Property="Background" Value="{Binding Name, 
                                    Converter={StaticResource ValueToBrushConverter}}" />
        </Style>
    </DataGridTextColumn.CellStyle>
</DataGridTextColumn>

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.