1
votes

I have a datagrid that is populated by binding it to a datatable.

There are 100 rows.

Using c# how do I change the background colour of a specific cell?

Lets say for example the 15th row and the background colour I want is green.

Datagrid

<DataGrid Name="grid" ItemsSource="{Binding}" Height="300" Width="900"
          AutoGenerateColumns="True"
          VerticalScrollBarVisibility="Disabled" HorizontalAlignment="Center" VerticalAlignment="Top" RowHeight="40">
            <DataGrid.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel Orientation="Vertical" />
                </ItemsPanelTemplate>
            </DataGrid.ItemsPanel>
        </DataGrid>
2
remove that horrible untyped, magic-string based DataTable stuff and create a proper, strongly-typed ViewModel for this. Then simply use Style.Triggers or the like to change the cell background based on values from the underlying data. Don't manipulate UI elements in procedural code in WPF. That's what XAML is for.Federico Berasategui

2 Answers

1
votes

Actually there are no methods for accessing individual row in a WPF Datagrid and u shouldn't do it! The better way is to use style setter

<Style TargetType="{x:Type DataGridCell}" x:Key="NumberCell">      
<Style.Setters>
    <Setter Property="Background" Value="{Binding backgroundColor></Setter>
</Style.Setters>

Unless you can't do it this way there is an other option: I found this solution on the web some time ago, but can't remember where.

At first we need some helper functions. Simply add this class

namespace YOURNAMESPACE.DataGridHelpers
/// <summary>
/// Extension methods for DataGrid
/// </summary>
public static class DataGridHelper
{
    /// <summary>
    /// Gets the visual child of an element
    /// </summary>
    /// <typeparam name="T">Expected type</typeparam>
    /// <param name="parent">The parent of the expected element</param>
    /// <returns>A visual child</returns>
    public static T GetVisualChild<T>(Visual parent) where T : Visual
    {
        T child = default(T);
        int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
        for (int i = 0; i < numVisuals; i++)
        {
            Visual v = (Visual)VisualTreeHelper.GetChild(parent, i);
            child = v as T;
            if (child == null)
            {
                child = GetVisualChild<T>(v);
            }
            if (child != null)
            {
                break;
            }
        }
        return child;
    }



    /// <summary>
    /// Gets the specified cell of the DataGrid
    /// </summary>
    /// <param name="grid">The DataGrid instance</param>
    /// <param name="row">The row of the cell</param>
    /// <param name="column">The column index of the cell</param>
    /// <returns>A cell of the DataGrid</returns>
    public static DataGridCell GetCell(this DataGrid grid, DataGridRow row, int column)
    {
        if (row != null)
        {
            DataGridCellsPresenter presenter = GetVisualChild<DataGridCellsPresenter>(row);

            if (presenter == null)
            {
                grid.ScrollIntoView(row, grid.Columns[column]);
                presenter = GetVisualChild<DataGridCellsPresenter>(row);
            }

            DataGridCell cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column);

            return cell;
        }
        return null;
    }

    /// <summary>
    /// Gets the specified cell of the DataGrid
    /// </summary>
    /// <param name="grid">The DataGrid instance</param>
    /// <param name="row">The row index of the cell</param>
    /// <param name="column">The column index of the cell</param>
    /// <returns>A cell of the DataGrid</returns>
    public static DataGridCell GetCell(this DataGrid grid, int row, int column)
    {
        DataGridRow rowContainer = grid.GetRow(row);
        return grid.GetCell(rowContainer, column);
    }

    /// <summary>
    /// Gets the specified row of the DataGrid
    /// </summary>
    /// <param name="grid">The DataGrid instance</param>
    /// <param name="index">The index of the row</param>
    /// <returns>A row of the DataGrid</returns>
    public static DataGridRow GetRow(this DataGrid grid, int index)
    {
        DataGridRow row = (DataGridRow)grid.ItemContainerGenerator.ContainerFromIndex(index);
        if (row == null)
        {
            // May be virtualized, bring into view and try again.
            grid.UpdateLayout();
            grid.ScrollIntoView(grid.Items[index]);
            row = (DataGridRow)grid.ItemContainerGenerator.ContainerFromIndex(index);
        }
        return row;
    }

    /// <summary>
    /// Gets the selected row of the DataGrid
    /// </summary>
    /// <param name="grid">The DataGrid instance</param>
    /// <returns></returns>
    public static DataGridRow GetSelectedRow(this DataGrid grid)
    {
        return (DataGridRow)grid.ItemContainerGenerator.ContainerFromItem(grid.SelectedItem);
    }
}

}

Now u can get DataGrid Column 0 row 15 with:

var cell = dataGrid.GetCell( 15, 0);

and set the color to green

cell.Background = Brushes.Green;
0
votes

Add a handler to the LoadingRow event of the DataGrid like this:

    <DataGrid Name="grid" ItemsSource="{Binding}" Height="300" Width="900"
            AutoGenerateColumns="True" VerticalAlignment="Top" RowHeight="40"
            VerticalScrollBarVisibility="Disabled" HorizontalAlignment="Center"  
            LoadingRow="DataGrid_LoadingRow" >
        <DataGrid.ItemsPanel>
            <ItemsPanelTemplate>
                <WrapPanel Orientation="Vertical" />
            </ItemsPanelTemplate>
        </DataGrid.ItemsPanel>
    </DataGrid>

Then in the code behind:

     int index = 0;
     public void DataGrid_LoadingRow(object sender, DataGridRowEventArgs e)
     {
        var row = (DataRowView)e.Row.Item;
        //If you want the content of a specific column of the current row
        //var content = row.Row[0].ToString(); 
        if (index == 15)
        {
            e.Row.Background = new SolidColorBrush(Colors.DeepSkyBlue);
            e.Row.Foreground = new SolidColorBrush(Colors.Black);
        }
        index ++ ; //don't forget to increase the index
     }