Search code examples
c#wpfdatagrid

Retrieve container from DataGrid wpf by DataRow


I'm using DataGrid in Wpf and bind data as following:

datagridEx.ItemsSource = tblEx.AsDataView();

Now i have a function which handling some logic then return a List of DataRow. I want to set background for these rows


public void HighlightRows(IEnumerable<DataRow> rows, DataGrid grid)
{
    foreach(var row in rows)
    {
        DataGridRow dgr = grid.ItemContainerGenerator.ContainerFromItem(row) as DataGridRow;
        if (dgr != null)
        {
            dgr.Background = Brushes.LightBlue; 
        }
    }
}
   

but i always recieve a null reference pointer of dgr. I realized that DataRow is converted to DataRowView therefore DataGrid could not found the container represent to DataRow item.

Which is good solution can help me?


Solution

  • Instead of grid.ItemContainerGenerator.ContainerFromItem(), use grid.ItemContainerGenerator.ContainerFromIndex() function, because DataGrid uses virtualization so Item has not been generated at that time.

    From the ContainerFromIndex function you can fetch DataGridRow and then you can use DataGridRow.Item to compare data rows.

    Updated function is as below:

    public void HighlightRows(IEnumerable<DataRow> rows, DataGrid grid)
    {           
        for (int index = 0; index < grid.Items.Count; index++)
        {
            DataGridRow dgr = grid.ItemContainerGenerator.ContainerFromIndex(index) as DataGridRow;
    
            if (dgr.Item.GetType() == typeof(DataRowView))
            {
                foreach (DataRow row in rows)
                {
                    var array1 = row.ItemArray;
                    var array2 = (((DataRowView)dgr.Item).Row).ItemArray;
    
                    if (array1.SequenceEqual(array2))
                    {
                        dgr.Background = Brushes.LightBlue;
                    }
                }
            }
        }
    }