首页 文章

在WPF中访问DataGrid的单元格值?

提问于
浏览
0

我们有这样一个场景,我们有一个包含DataGrid的页面,现在我们想从这个DataGrid获取所有数据,但是没有访问它的底层项源,即我们想直接从DataGrid访问数据 . 这似乎很棘手,但并非不可能 . 我找到了很多文章,比如:DataGridHelper,这个:Get WPF DataGrid row and cell,还有很多其他文章 . 它们基本相同:在DataGrid上使用另一个GetVisualChild函数定义扩展方法来查找目标DataGridCell对象 . 但是,当我使用它时,我可以说't find the target cell. Specifically, Each row in the DataGrid corresponds to one item from a collection of the DataContext, let',它是"Employee"类型的集合,DataGrid的每一列对应一个Employee类的一个属性,例如Name,Gender,Age . 现在我的问题是,上面提到的GetCell()函数总是找到一个DataGridCell,其中一个Employee对象作为其内容(DataGridCell中Content的属性),无论我给出什么列索引,都无法进一步进入每个属性它 . 例如,在GetCell函数中,有一行: Dim cell As DataGridCell = DirectCast(presenter.ItemContainerGenerator.ContainerFromIndex(column), DataGridCell) ,其中演示者是我得到的DataGridCellsPresenter,表示我选择的行,一旦我给列索引,我自然希望它返回控件在我指定的位置选择的属性 . 但它只是没有按预期工作 . 任何帮助,将不胜感激!

2 回答

  • 0

    当您使用 presenter.ItemContainerGenerator.ContainerFromIndex 时,您将陷入限制,它仅适用于非虚拟化项目,即滚动视图中显示的行(加上滚动视图限制上下的一些偏移行数) .

    要访问所有单元格的值,您必须为每行执行列级绑定 .

    • 访问 DataGrid.Items 集合 . 这是项目的视图,因此将排除由筛选条件或自定义分页等隐藏的任何项目 . 如果你不想要那么做 DataGrid.ItemsSource.Cast<object>().ToList() 电话 .

    • 现在访问数据网格的所有列,即 DataGrid.Columns . 假设它们是任何类型但是 DataGridTemplateColumn ,下面的步骤3将提取单元格级别的值 . 对于模板列,您必须指定一些属性值,该值表示单元格的整个模板 . 我发现 DataGridTemplateColumn.SortMemberPath 是一个很好的候选人 .

    • 提取 DataGridTextColumn.BindingDataGridCheckBoxColumn.BindingDataGridComboBoxColumn.SelectedValueBindingDataGridComboBoxColumn.SelectedItemBinding . 然后对于步骤1中的每个项目,执行绑定以提取值 .

    Code

    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);
        }
    }
    
  • 0

    我意识到这是一个古老的话题,但我搜索了一个简单的解决方案,并最终找到了它 . 认为其他人可能会喜欢简单以下示例按指定列搜索数据网格以获取所需值,如果找到则将选择该行 .

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

相关问题