Доступ к значениям ячейки DataGrid в WPF?

Вопрос: У нас есть такой сценарий, что у нас есть страница, включая DataGrid, и теперь мы хотим получить все данные из этого DataGrid, но без доступа к исходному ее источнику, т.е. Мы хотим получить доступ к данным непосредственно из DataGrid, Это кажется сложным, но не невозможным. Я нашел много статей, таких как: DataGridHelper, и это:

Вопрос:

У нас есть такой сценарий, что у нас есть страница, включая DataGrid, и теперь мы хотим получить все данные из этого DataGrid, но без доступа к исходному ее источнику, т.е. Мы хотим получить доступ к данным непосредственно из DataGrid, Это кажется сложным, но не невозможным. Я нашел много статей, таких как: DataGridHelper, и это: Получить строку и ячейку WPF DataGrid и многие другие. Они в основном одно и то же: определить методы расширения в DataGrid с помощью другой функции GetVisualChild для поиска целевого объекта DataGridCell. Однако, когда я его использую, я не могу найти целевую ячейку. В частности, каждая строка в DataGrid соответствует одному элементу из коллекции DataContext, скажем, это коллекция типа “Сотрудник”, и каждый столбец DataGrid соответствует одному свойству класса Employee, например, Name, Gender, Возраст. Теперь моя проблема заключается в том, что вышеупомянутая функция GetCell() всегда находит DataGridCell с одним объектом Employee как свой контент (свойство Content in DataGridCell) и не может идти дальше в каждое свойство, независимо от того, какой индекс столбца я даю Это. Например, в функции GetCell есть одна строка: Dim cell As DataGridCell = DirectCast(presenter.ItemContainerGenerator.ContainerFromIndex(column), DataGridCell), где ведущий – это DataGridCellsPresenter, который я представляю, какую строку я выбираю, и как только поскольку я даю индекс столбца, естественно, я ожидаю, что он вернет элемент управления для выбранного свойства в заданном положении. Но он работает не так, как ожидалось. Любая помощь будет оценена!

Лучший ответ:

В тот момент, когда вы используете presenter.ItemContainerGenerator.ContainerFromIndex вы попадаете в ограничение для работы ТОЛЬКО для не виртуализированных элементов, то есть строк, которые отображаются в представлении прокрутки (плюс некоторое количество смещений строк выше и ниже пределов прокрутки) DataGrid.

Для доступа к значениям всех ячеек вам потребуется выполнить привязки уровня столбца для каждой строки.

  1. Войдите в коллекцию DataGrid.Items. Это представление элементов, поэтому любые элементы, скрытые критериями фильтрации или пользовательскими подкачками и т.д., Будут исключены. Если вы этого не хотите, выполните DataGrid.ItemsSource.Cast<object>().ToList().

  2. Теперь обращайтесь ко всем столбцам данных, то есть к DataGrid.Columns. Предполагая, что они имеют какой-либо тип, но DataGridTemplateColumn, шаг 3 ниже будет извлекать значение уровня ячейки. Для столбцов шаблона вам необходимо указать некоторое значение свойства, которое представляет весь шаблон ячейки. Я считаю DataGridTemplateColumn.SortMemberPath хорошим кандидатом для этого.

  3. Извлеките DataGridTextColumn.Binding, DataGridCheckBoxColumn.Binding, DataGridComboBoxColumn.SelectedValueBinding или DataGridComboBoxColumn.SelectedItemBinding. Затем для каждого элемента с шага 1 выполните привязку для извлечения значения.

Код

private void Button_Click_1(object sender, RoutedEventArgs e) { string gridContent = string.Empty; foreach(var item in MyDataGrid.Items) { foreach (var column in MyDataGrid.Columns) { var textCol = column as DataGridTextColumn; var checkCol = column as DataGridCheckBoxColumn; var comboCol = column as DataGridComboBoxColumn; var templateCol = column as DataGridTemplateColumn; if (textCol != null) { var propertyName = ((Binding)textCol.Binding).Path.Path; var value = item.GetType().GetProperty( propertyName).GetValue( item, new object[] {}); if (((Binding)textCol.Binding).Converter != null) { value = ((Binding)checkCol.Binding).Converter.Convert( value, typeof(object), ((Binding)checkCol.Binding).ConverterParameter, ((Binding)checkCol.Binding).ConverterCulture); } gridContent = gridContent + «t» + value.ToString(); } if (checkCol != null) { var propertyName = ((Binding)checkCol.Binding).Path.Path; object value = item.GetType().GetProperty( propertyName).GetValue( item, new object[] { }); if (((Binding)checkCol.Binding).Converter != null) { value = ((Binding)checkCol.Binding).Converter.Convert( value, typeof(object), ((Binding)checkCol.Binding).ConverterParameter, ((Binding)checkCol.Binding).ConverterCulture); } gridContent = gridContent + «t» + value.ToString(); } if (comboCol != null) { var propertyName = string.Empty; if (comboCol.SelectedValueBinding != null) { propertyName = ((Binding)comboCol.SelectedValueBinding).Path.Path; } else if (!string.IsNullOrEmpty(comboCol.SelectedValuePath)) { propertyName = comboCol.SelectedValuePath; } else if (!string.IsNullOrEmpty(comboCol.DisplayMemberPath)) { propertyName = comboCol.DisplayMemberPath; } var value = item.GetType().GetProperty( propertyName).GetValue( item, new object[] { }); if (comboCol.SelectedValueBinding != null && ((Binding)comboCol.SelectedValueBinding).Converter != null) { var bnd = (Binding)comboCol.SelectedValueBinding; value = bnd.Converter.Convert( value, typeof(object), bnd.ConverterParameter, bnd.ConverterCulture); } gridContent = gridContent + «t» + value.ToString(); } if (templateCol != null) { var propertyName = templateCol.SortMemberPath; var value = item.GetType().GetProperty( propertyName).GetValue( item, new object[] { }); gridContent = gridContent + «t» + value.ToString(); } } gridContent = gridContent + «n»; } MessageBox.Show(gridContent); } } Ответ №1

Я понимаю, что это старая тема, но я искал простое решение и, наконец, нашел его. Мысль других могла бы быть простой. В следующем примере выполняется поиск по datagrid по указанному столбцу для требуемого значения, если найденный будет выбирать строку.

private void dgSetRow(DataGrid dg, string sColHeader, int iFindValue) { foreach (DataRowView drv in dg.Items ) { // compare value in datarow of view if (iFindValue == (int)drv.Row[sColHeader]) { // select item dg.SelectedItem = drv; dg.ScrollIntoView(drv); } } }

Оцените статью
Добавить комментарий