rbasniak
rbasniak

Reputation: 4964

Changing color of a single cell in WPF Datagrid

I have a WPF Datagrid with variable number of columns and populated at runtime with a 2D array of String[][].

String[] data = .....;

datagrid.ItemsSource = data;

I need to chance cell colors based on its values. But these values are defined by the user during execution. Most examples I found about changing cell colors use Triggers on the XAML and the value is known in design time.

So I'm changing the background of the cell like this:

DataGridCell cell = DataGridUtils.GetCell(datagrid, i, j);

cell.Background = new SolidColorBrush(Colors.DarkGreen);

And the GetCell function:

private DataGridCell GetCell(int rowIndex, int colIndex, DataGrid dg)
{
    DataGridRow row = dg.ItemContainerGenerator.ContainerFromIndex(rowIndex) as DataGridRow;
    DataGridCellsPresenter p = GetVisualChild<DataGridCellsPresenter>(row);
    DataGridCell cell = p.ItemContainerGenerator.ContainerFromIndex(colIndex) as DataGridCell;

    return cell;
}

At first glance it seems to be doing ok, I can see the cell with that value in green. But if I scroll the datagrid all the way down and then go back up the cell in green changes do another random cell nad more cells are turning green. If I keep going up and down the cells in green keep changing randomly.

I know this sounds very weird, but there's only one place in code that changes cell colors, and it's in a button click. I don't know how this could be happening when scrolling the datagrid.

I read somewhere that ItemContainerGenerator it's not an elegant solution and should be avoided. But it's the only way I managed to make this work.

Is there better way to change background color of a cell? Can I do this with Triggers without knowing the values at design time? If so, how?

Upvotes: 0

Views: 2031

Answers (1)

123 456 789 0
123 456 789 0

Reputation: 10865

DataGrid has VirtualizationMode default to Recycling which means it'll reuse the DataCell that it generated to improve performance. It won't have to create n times of controls.

Add this to your DataGrid

VirtualizingStackPanel.VirtualizationMode="Standard"

Be aware that it'll affect your performance and WPF will create n times of control.

Upvotes: 1

Related Questions