13

I have a DataGrid WPF control and I want to get a specific DataGridCell. I know the row and column indices. How can I do this?

I need the DataGridCell because I have to have access to its Content. So if I have (for example) a column of DataGridTextColum, my Content will be a TextBlock object.

danielbeard
  • 9,120
  • 3
  • 44
  • 58
gliderkite
  • 8,828
  • 6
  • 44
  • 80

3 Answers3

5

You can use code similar to this to select a cell:

var dataGridCellInfo = new DataGridCellInfo(
    dataGrid.Items[rowNo], dataGrid.Columns[colNo]);

dataGrid.SelectedCells.Clear();
dataGrid.SelectedCells.Add(dataGridCellInfo);
dataGrid.CurrentCell = dataGridCellInfo;

I can't see a way to update the contents of a specific cell directly, so in order to update the content of a specific cell I would do the following

// gets the data item bound to the row that contains the current cell
// and casts to your data type.
var item = dataGrid.CurrentItem as MyDataItem;

if(item != null){
    // update the property on your item associated with column 'n'
    item.MyProperty = "new value";
}
// assuming your data item implements INotifyPropertyChanged the cell will be updated.
Phil
  • 42,255
  • 9
  • 100
  • 100
  • 1
    But Rows is not a member of [DataGrid](http://msdn.microsoft.com/en-us/library/system.windows.controls.datagrid.aspx) – gliderkite Apr 03 '12 at 16:14
  • You're not wrong. Changed the answer, must have been too tired last night :-) – Phil Apr 03 '12 at 16:51
  • 1
    Ok, in this way works (if the SelectionUnit is not Row), but I need the [DataGridCell](http://msdn.microsoft.com/en-us/library/system.windows.controls.datagridcell.aspx) and not the DataGridCellInfo, because I need access to the DataGridCell Content. I tried [this](http://stackoverflow.com/questions/1764498/wpf-datagrid-programmatically-editing-a-cell), but the method GetVisualChild returns a null child, therefore will not work. – gliderkite Apr 03 '12 at 22:21
  • 1
    @Phil , have a look at this please , http://stackoverflow.com/questions/19889780/wpf-datagrid-unable-to-select-cells-programmatically – eran otzap Nov 10 '13 at 12:51
2

You can simply use this extension method-

public static DataGridRow GetSelectedRow(this DataGrid grid)
{
    return (DataGridRow)grid.ItemContainerGenerator.ContainerFromItem(grid.SelectedItem);
}

and you can get a cell of a DataGrid by an existing row and column id:

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;
}

grid.ScrollIntoView is the key to make this work in case DataGrid is virtualized and required cell is not in view currently.

Check this link for details - Get WPF DataGrid row and cell

akjoshi
  • 15,374
  • 13
  • 103
  • 121
1

Here is the code I used:

    /// <summary>
    /// Get the cell of the datagrid.
    /// </summary>
    /// <param name="dataGrid">The data grid in question</param>
    /// <param name="cellInfo">The cell information for a row of that datagrid</param>
    /// <param name="cellIndex">The row index of the cell to find. </param>
    /// <returns>The cell or null</returns>
    private DataGridCell TryToFindGridCell(DataGrid dataGrid, DataGridCellInfo cellInfo, int cellIndex = -1)
    {
        DataGridRow row;
        DataGridCell result = null;

        if (dataGrid != null && cellInfo != null)
        {
            if (cellIndex < 0)
            {
                row = (DataGridRow)dataGrid.ItemContainerGenerator.ContainerFromItem(cellInfo.Item);
            }
            else
            {
                row = (DataGridRow)dataGrid.ItemContainerGenerator.ContainerFromIndex(cellIndex);
            }

            if (row != null)
            {
                int columnIndex = dataGrid.Columns.IndexOf(cellInfo.Column);

                if (columnIndex > -1)
                {
                    DataGridCellsPresenter presenter = this.FindVisualChild<DataGridCellsPresenter>(row);

                    if (presenter != null)
                    {
                        result = presenter.ItemContainerGenerator.ContainerFromIndex(columnIndex) as DataGridCell;
                    }
                    else
                    {
                        result = null;
                    }
                }
            }
        }

        return result;
    }`

This assumes that the DataGrid has already been loaded (executed its own Loaded handler).

ouflak
  • 2,458
  • 10
  • 44
  • 49
  • 1
    that helped me , the common way as described in Phil answer above didn't work for an odd reason i described in this post : http://stackoverflow.com/questions/19889780/wpf-datagrid-unable-to-select-cells-programmatically – eran otzap Nov 10 '13 at 12:58
  • 1
    Where is the `FindVisualChild` method implementation? – NathanAldenSr Jun 24 '16 at 13:08