访问 WPF 中 DataGrid 的单元格值?
我们有这样一个场景,我们有一个包含DataGrid的页面,现在我们想从这个DataGrid中获取所有数据,但不访问它的底层项目源,即我们想直接从DataGrid访问数据。这似乎很棘手,但并非不可能。我找到了很多文章,例如:DataGridHelper ,以及这个: 获取 WPF DataGrid 行和单元格,以及许多其他内容。它们基本上是相同的:在另一个 GetVisualChild 函数的帮助下定义 DataGrid 上的扩展方法来查找目标 DataGridCell 对象。然而,当我使用它时,我找不到目标细胞。具体来说,DataGrid 中的每一行对应于 DataContext 集合中的一项,比方说,它是一个“Employee”类型的集合,DataGrid 中的每一列对应于 Employee 类的一个属性,例如姓名、性别, 年龄。现在我的问题是,上述 GetCell() 函数总是找到一个以一个 Employee 对象作为其内容(DataGridCell 中 Content 的属性)的 DataGridCell,并且无法进一步深入每个属性,无论我给出什么列索引它。 例如,在GetCell函数中,有一行: 将单元格调暗为 DataGridCell = DirectCast(presenter.ItemContainerGenerator.ContainerFromIndex(colum), DataGridCell)
, 其中演示者是我得到的 DataGridCellsPresenter,它代表我选择的行,一旦我给出列索引,我自然希望它返回我指定的位置处所选属性的控件。但它只是没有按预期工作。任何帮助将不胜感激!
We have such a scenario that we have a page including a DataGrid, and now we want to get all data from this DataGrid, but without accessing to the underlying item source of it, i.e., we want to access to the data directly from the DataGrid. It seems to be tricky but not impossible. I found many articles, like this: DataGridHelper, and this: Get WPF DataGrid row and cell, and many other ones. They are basically the same thing: to define the extension methods on DataGrid with help of another GetVisualChild function to find the target DataGridCell object. However, when I am using it, I can't find the target cell. Specifically, Each row in the DataGrid corresponds to one item from a collection of the DataContext, let's say, it is a collection of type "Employee", and each column of the DataGrid corresponds one property of class Employee, e.g, the Name, Gender, Age. Now my problem is, the above-mentioned GetCell() function always finds a DataGridCell with one Employee object as its content (the property of Content in DataGridCell), and can't go further into each property, no matter what column index I give it.
For example, in the GetCell function, there is one line:Dim cell As DataGridCell = DirectCast(presenter.ItemContainerGenerator.ContainerFromIndex(column), DataGridCell)
,
where the presenter is a DataGridCellsPresenter I got which representing the row I choose, and as soon as I give the column index, naturally I am expecting it to return the control for selected property at position I specified. But it just doesn't work as expected. Any help would be appreciated!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
当您使用 Presenter.ItemContainerGenerator.ContainerFromIndex 时,您就会陷入限制,因为它仅适用于非虚拟化项目,即滚动视图中显示的行(加上上方和下方的一些行偏移量)数据网格的滚动视图限制)。
为了访问所有单元格的值,您必须为每行执行列级绑定。
访问
DataGrid.Items
集合。这是项目的视图,因此任何被过滤条件或自定义分页等隐藏的项目都将被排除。如果您不希望这样做,请执行DataGrid.ItemsSource.Cast
现在访问数据网格的所有列,即
DataGrid.Columns
。假设它们是除DataGridTemplateColumn
之外的任何类型,下面的步骤 3 将提取单元格级别值。对于模板列,您必须指定一些代表单元格整个模板的属性值。我发现DataGridTemplateColumn.SortMemberPath
是一个很好的选择。提取
DataGridTextColumn.Binding
、DataGridCheckBoxColumn.Binding
、DataGridComboBoxColumn.SelectedValueBinding
或DataGridComboBoxColumn.SelectedItemBinding
。然后,对于步骤 1 中的每个项目,执行绑定以提取值。代码
The moment you use
presenter.ItemContainerGenerator.ContainerFromIndex
you fall into a limitation for it to work ONLY for non-virtualized items i.e. rows that are shown in the scroll view (plus some offset number of rows above and below the scroll view limits) of the datagrid.For you to access values of all cells you will have to execute column level bindings for each row.
Access the
DataGrid.Items
collection. This is a view of items so any items hidden by filter criteria or custom paging etc will be excluded. If you dont want that then doDataGrid.ItemsSource.Cast<object>().ToList()
call.Now access all columns of the datagrid i.e.
DataGrid.Columns
. Assuming that they are of any type butDataGridTemplateColumn
, step 3 below will extract the cell level value. For template columns you will have to specify some property value that represents the entire template of the cell. I findDataGridTemplateColumn.SortMemberPath
a good candidate for this.Extract the
DataGridTextColumn.Binding
,DataGridCheckBoxColumn.Binding
,DataGridComboBoxColumn.SelectedValueBinding
orDataGridComboBoxColumn.SelectedItemBinding
. Then for each item from step 1, execute the binding to extract the value.Code
我意识到这是一个老话题,但我寻找了一个简单的解决方案并终于找到了它。认为其他人可能喜欢简单。以下示例按指定列在数据网格中搜索所需值,如果找到,将选择该行。
I realize this is old topic, but I searched for a simple solution and finally found it. Thought others might like simple. The following example searches the datagrid by specified column for the desired value, if found will select the row.