WPF Datagrid получить выбранное значение ячейки

Я хочу получить значение для выбранной ячейки в datagrid, пожалуйста, кто-нибудь скажет, как это сделать. я использовал событие SelectedCell changed, как я могу это сделать?

dataGrid1.CurrentCell

10 ответов


пожалуйста, обратитесь к Класс DataGrid страница на MSDN. С этой страницы:

выбор

по умолчанию вся строка выбирается, когда пользователь щелкает ячейку в DataGrid, и пользователь может выбрать несколько строк. Вы можете установить SelectionMode свойство, чтобы указать, может ли пользователь выбрать ячейки, полные строки или оба. Задайте свойство SelectionUnit, чтобы указать, можно ли выбрать несколько строк или ячеек, или только отдельные строки или ячейки.

вы можете получить информацию о ячейках, которые выбраны из SelectedCells собственность. Вы можете получить информацию о ячейках, для которых выбор изменился в SelectedCellsChangedEventArgs события SelectedCellsChanged. Вызовите методы SelectAllCells или UnselectAllCells для программного выбора или отмены выбора всех ячеек. Дополнительные сведения см. В разделе Поведение клавиатуры и мыши по умолчанию в DataGrid Управление.

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


когда я столкнулся с этой проблемой, я подошел к ней так: Я создал DataRowView, схватил индекс столбца, а затем использовал это в строке ItemArray

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

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

var cellInfo = dataGrid1.SelectedCells[0];

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

здесь содержимое будет вашим выбранным значением ячейки

и если вы выбрали несколько ячеек, то вы можете сделать это

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

если SelectionUnit="Cell" попробуйте это:

    string cellValue = GetSelectedCellValue();

где:

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

кажется, это не должно быть так сложно, я знаю...

Edit: это, кажется, не работает на DataGridTemplateColumn столбцы типа. Вы также можете попробовать это, если ваши строки состоят из пользовательского класса, и вы назначили путь члена сортировки:

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

//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());

поскольку WPF обеспечивает привязку в DataGrids, это должно быть довольно прозрачным. Однако следующий метод работает только в том случае, если вы использовали SQLDataAdapter и предоставили путь привязки к DataGridColoumns. Для EG. Предположим, вышеупомянутый datagrid называется grid1, который имеет автоматическое создание столбцов, установленных в false, и использует привязку для привязки имен столбцов к заголовкам. В этом случае мы используем переменную 'row' типа 'DataRowView' и сохраняем в ней выбранную строку. Теперь используйте пути привязки, и ссылаться на отдельные столбцы выбранной строки. Надеюсь, это поможет! Ура!

PS: работает, если SelectionUnit = 'Row'


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

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

Я долго боролся с этим! (Использование VB.NET) в основном вы получаете индекс строки и индекс столбца выбранной ячейки, а затем используете его для доступа к значению.

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

Класс


Ok после выполнения обратного проектирования и немного пыли отражения pixie, можно сделать эту операцию на SelectedCells (в любой момент), чтобы получить все (независимо от выбранного в одной строке или во многих строках) данные от одной до многих выбранных ячеек:

MessageBox.Show(

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

               );

Я пробовал это на текстовых (строковых) полях, только если поле DateTime должно возвращать значение initiate ToString(). Также обратите внимание, что SortMemberPath - это не то же самое как Header так что всегда следует предоставлять надлежащее свойство отразить.

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

я расширяю решение Руши до следующего (который решил головоломку для меня)

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

вы также можете использовать эту функцию.

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