2012-04-02 3 views
10

У меня есть DataGrid WPF-контроль, и я хочу получить конкретное DataGridCell. Я знаю индексы строк и столбцов. Как я могу это сделать?Выберите DataGridCell от DataGrid

Мне нужен DataGridCell, потому что я должен иметь доступ к его контенту. Поэтому, если у меня есть (например) столбец DataGridTextColum, мой контент будет TextBlock.

+0

Здравствуйте, я внедрил метод, к которому вы можете получить доступ ко всем свойствам ячейки. –

ответ

4

Вы можете использовать код, подобный этому, чтобы выбрать ячейку:

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

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

Я не могу видеть способ обновить содержимое конкретной ячейки непосредственно, поэтому для того, чтобы обновить содержание конкретного клетка я хотел бы сделать следующее

// 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. 
+1

Но строки не являются членами [DataGrid] (http://msdn.microsoft.com/en-us/library/system.windows.controls.datagrid.aspx) – gliderkite

+0

Вы не ошибаетесь. Изменил ответ, должно быть, слишком устал прошлой ночью :-) – Phil

+1

Хорошо, таким образом работает (если SelectionUnit не Row), но мне нужен [DataGridCell] (http://msdn.microsoft.com/en- us/library/system.windows.controls.datagridcell.aspx), а не DataGridCellInfo, потому что мне нужен доступ к контенту DataGridCell. Я попробовал [this] (http://stackoverflow.com/questions/1764498/wpf-datagrid-programmatically-editing-a-cell), но метод GetVisualChild возвращает нулевой ребенок, поэтому не будет работать. – gliderkite

2

Вы можете просто использовать это расширение

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

, и вы можете получить ячейку в DataGrid с помощью существующей строки и столбца 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 является ключом, чтобы сделать эту работу в случае, если DataGrid виртуализируется и требуется ячейка не с точки зрения в настоящее время.

Проверить эту ссылку для деталей - Get WPF DataGrid row and cell

1

Вот код, который я использовал:

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

Это предполагает, что DataGrid уже загружен (выполняется свой собственный обработчик Loaded).

+1

, который помог мне, общий способ, описанный в Phil ответ выше не работал по нечетной причине, описанной в этой статье: http://stackoverflow.com/questions/19889780/wpf-datagrid-unable-to-select-cells-programmatically –

+0

Где находится 'FindVisualChild' метод реализации? – NathanAldenSr