HCL
HCL

Reputation: 36765

DataGrid how to get the value of the CurrentCell

I have to access the value that underlies the active cell of a DataGrid (The cell with the black border around it).

Luckily DataGrid has a lot of properties such as CurrentCell, CurrentItem SelectedCells SelectedItem and SelectedItems seeming to provide me with the data I want.

However I have not figured out how to access the cell in an easy way. I also have changed the …

SelectionMode="Single" SelectionUnit="Cell"

...properties but in the end I had to do something like this:

DataGridCellInfo cellInfo = dataGrid.CurrentCell;

if(null != cellInfo && cellInfo.IsValid)
{
    object[] array = cellInfo.Item as object[];
    if (null != array && cellInfo.Column.DisplayIndex >= 0 && cellInfo.Column.DisplayIndex < array.Length) 
    {
        object cellValue = array[cellInfo.Column.DisplayIndex];
        if (null != cellValue) 
        {
            // Here we are
        }
    }
}

In my example, the row is built through an object-array containing various object-types. I'm aware that I could execute the binding on the cellInfo.Column (after a cast), however that is not the point. My question is, if I make something really wrong, because I cannot imaging that such a powerful piece of software as DataGrid is, can not provide me the desired value without doing such a lot of coding.

What have I missed or is it really such complicated to get the current cells value.

UPDATE

As Quartermeister explained in his very good answer, there is not a single property to access the cells value and this is has a meaningfull cause. besides, beware of using the DisplayIndex as I do in my example if you let the user rearrange the columns.

Upvotes: 4

Views: 7930

Answers (1)

Quartermeister
Quartermeister

Reputation: 59129

It really is that complicated. The problem is that a DataGridColumn isn't necessarily bound to a single value. A DataGridTemplateColumn, for example, just has a DataTemplate. The template may use multiple values from the row object or even no values at all, so there is no way to usefully return a single value for that cell.

You can be guaranteed to have a single value if the column is a DataGridBoundColumn (such as a DataGridTextColumn). As you said, you can get the value by executing the Binding. For example, you could do something like this (note that this won't work for a binding that uses ElementName or RelativeSource, but you probably won't use those in a DataGridBoundColumn):

var cellInfo = dataGrid.CurrentCell;
if (cellInfo != null)
{
    var column = cellInfo.Column as DataGridBoundColumn;
    if (column != null)
    {
        var element = new FrameworkElement() { DataContext = cellInfo.Item };
        BindingOperations.SetBinding(element, FrameworkElement.TagProperty, column.Binding);
        var cellValue = element.Tag;
    }
}

Note that you probably don't want to use the DisplayIndex property, since that can be changed if the user manually drags the columns to reorder them.

Upvotes: 6

Related Questions