[c#] WPF Datagrid Get Selected Cell Value

I want to get value for selected cell in datagrid , please anyone tell how to do this. i used SelectedCell changed event , how can i do that?

dataGrid1.CurrentCell

This question is related to c# wpf datagrid

The answer is


I was to dumb to find the Solution...

For me (VB):

 Dim string= Datagrid.SelectedCells(0).Item(0).ToString

I was in such situation .. and found This:

int ColumnIndex = DataGrid.CurrentColumn.DisplayIndex;
TextBlock CellContent = DataGrid.SelectedCells[ColumnIndex].Column.GetCellContent(DataGrid.SelectedItem);

And make sure to treat custom columns' templates


you can also use this function.

 public static void GetGridSelectedView(out string tuid, ref DataGrid dataGrid,string Column)
    {
        try
        {
            // grid selected row values
            var item = dataGrid.SelectedItem as DataRowView;
            if (null == item) tuid = null;
            if (item.DataView.Count > 0)
            {
                tuid =  item.DataView[dataGrid.SelectedIndex][Column].ToString().Trim();
            }
            else { tuid = null; }
        }
        catch (Exception exc) { System.Windows.MessageBox.Show(exc.Message); tuid = null; }
    }

I'm extending the solution by Rushi to following (which solved the puzzle for me)

var cellInfo = Grid1.SelectedCells[0];
var content = (cellInfo.Column.GetCellContent(cellInfo.Item) as TextBlock).Text;

Ok after doing reverse engineering and a little pixie dust of reflection, one can do this operation on SelectedCells (at any point) to get all (regardless of selected on one row or many rows) the data from one to many selected cells:

MessageBox.Show(

string.Join(", ", myGrid.SelectedCells
                        .Select(cl => cl.Item.GetType()
                                             .GetProperty(cl.Column.SortMemberPath)
                                             .GetValue(cl.Item, null)))

               );

I tried this on text (string) fields only though a DateTime field should return a value the initiate ToString(). Also note that SortMemberPath is not the same as Header so that should always provide the proper property to reflect off of.

<DataGrid ItemsSource="{Binding MyData}"                      
          AutoGenerateColumns="True"
          Name="myGrid"
          IsReadOnly="True"
          SelectionUnit="Cell"
          SelectionMode="Extended">

If SelectionUnit="Cell" try this:

    string cellValue = GetSelectedCellValue();

Where:

    public string GetSelectedCellValue()
    {
        DataGridCellInfo cellInfo = MyDataGrid.SelectedCells[0];
        if (cellInfo == null) return null;

        DataGridBoundColumn column = cellInfo.Column as DataGridBoundColumn;
        if (column == null) return null;

        FrameworkElement element = new FrameworkElement() { DataContext = cellInfo.Item };
        BindingOperations.SetBinding(element, TagProperty, column.Binding);

        return element.Tag.ToString();
    }

Seems like it shouldn't be that complicated, I know...

Edit: This doesn't seem to work on DataGridTemplateColumn type columns. You could also try this if your rows are made up of a custom class and you've assigned a sort member path:

    public string GetSelectedCellValue()
    {
        DataGridCellInfo cells = MyDataGrid.SelectedCells[0];

        YourRowClass item = cells.Item as YourRowClass;
        string columnName = cells.Column.SortMemberPath;

        if (item == null || columnName == null) return null;

        object result = item.GetType().GetProperty(columnName).GetValue(item, null);

        if (result == null) return null;

        return result.ToString();
    }

When I faced this problem, I approached it like this: I created a DataRowView, grabbed the column index, and then used that in the row's ItemArray

DataRowView dataRow = (DataRowView)dataGrid1.SelectedItem;
int index = dataGrid1.CurrentCell.Column.DisplayIndex;
string cellValue = dataRow.Row.ItemArray[index].ToString();

I struggled with this one for a long time! (Using VB.NET) Basically you get the row index and column index of the selected cell, and then use that to access the value.

Private Sub LineListDataGrid_SelectedCellsChanged(sender As Object, e As SelectedCellsChangedEventArgs) Handles LineListDataGrid.SelectedCellsChanged

    Dim colInd As Integer = LineListDataGrid.CurrentCell.Column.DisplayIndex

    Dim rowInd As Integer = LineListDataGrid.Items.IndexOf(LineListDataGrid.CurrentItem)

    Dim item As String

    Try
        item = LLDB.LineList.Rows(rowInd)(colInd)
    Catch
        Exit Sub
    End Try

End Sub

End Class


Worked For me

object item = dgwLoadItems.SelectedItem;
string ID = (dgwLoadItems.SelectedCells[0].Column.GetCellContent(item) as TextBlock).Text;
MessageBox.Show(ID);

These are 2 methods that can be used to take a value from the selected row

    /// <summary>
    /// Take a value from a the selected row of a DataGrid
    /// ATTENTION : The column's index is absolute : if the DataGrid is reorganized by the user,
    /// the index must change
    /// </summary>
    /// <param name="dGrid">The DataGrid where we take the value</param>
    /// <param name="columnIndex">The value's line index</param>
    /// <returns>The value contained in the selected line or an empty string if nothing is selected</returns>
    public static string getDataGridValueAt(DataGrid dGrid, int columnIndex)
    {
        if (dGrid.SelectedItem == null)
            return "";
        string str = dGrid.SelectedItem.ToString(); // Take the selected line
        str = str.Replace("}", "").Trim().Replace("{", "").Trim(); // Delete useless characters
        if (columnIndex < 0 || columnIndex >= str.Split(',').Length) // case where the index can't be used 
            return "";
        str = str.Split(',')[columnIndex].Trim();
        str = str.Split('=')[1].Trim();
        return str;
    }

    /// <summary>
    /// Take a value from a the selected row of a DataGrid
    /// </summary>
    /// <param name="dGrid">The DataGrid where we take the value.</param>
    /// <param name="columnName">The column's name of the searched value. Be careful, the parameter must be the same as the shown on the dataGrid</param>
    /// <returns>The value contained in the selected line or an empty string if nothing is selected or if the column doesn't exist</returns>
    public static string getDataGridValueAt(DataGrid dGrid, string columnName)
    {
        if (dGrid.SelectedItem == null)
            return "";
        for (int i = 0; i < columnName.Length; i++)
            if (columnName.ElementAt(i) == '_')
            {
                columnName = columnName.Insert(i, "_");
                i++;
            }
        string str = dGrid.SelectedItem.ToString(); // Get the selected Line
        str = str.Replace("}", "").Trim().Replace("{", "").Trim(); // Remove useless characters
        for (int i = 0; i < str.Split(',').Length; i++)
            if (str.Split(',')[i].Trim().Split('=')[0].Trim() == columnName) // Check if the searched column exists in the dataGrid.
                return str.Split(',')[i].Trim().Split('=')[1].Trim();
        return str;
    }

If you are selecting only one cell then get selected cell content like this

var cellInfo = dataGrid1.SelectedCells[0];

var content = cellInfo.Column.GetCellContent(cellInfo.Item);

Here content will be your selected cells value

And if you are selecting multiple cells then you can do it like this

var cellInfos = dataGrid1.SelectedCells;

var list1 = new List<string>();

foreach (DataGridCellInfo cellInfo in cellInfos)
{
    if (cellInfo.IsValid)
    {
        //GetCellContent returns FrameworkElement
        var content= cellInfo.Column.GetCellContent(cellInfo.Item); 

        //Need to add the extra lines of code below to get desired output

        //get the datacontext from FrameworkElement and typecast to DataRowView
        var row = (DataRowView)content.DataContext;

        //ItemArray returns an object array with single element
        object[] obj = row.Row.ItemArray;

        //store the obj array in a list or Arraylist for later use
        list1.Add(obj[0].ToString());
    }
}

//Xaml Code
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Path=Date, Converter={StaticResource    dateconverter}, Mode=OneWay}" Header="Date" Width="100"/>
<DataGridTextColumn Binding="{Binding Path=Prescription}" Header="Prescription" Width="900"/>
</DataGrid.Columns>

//C# Code
 DataRowView row = (DataRowView)grid1.SelectedItem;
 MessageBox.Show(row["Prescription"].toString() + " " + row["Date"].toString());

As WPF provides binding in DataGrids, this should be rather transparent. However, the following method only works, if you have used SQLDataAdapter and provided a binding path to your DataGridColoumns. For eg. Let's say the above datagrid is named grid1, which has auto generate columns set to false, and is using binding to bind column names to Headers. In this case, we use the 'row' variable of type 'DataRowView' and store the selected row in it. Now, use your Binding Paths, and reference individual columns of the selected row. Hope this helps! Cheers!

PS: Works if SelectionUnit = 'Row'