读取 DataGrid 时如何保存重新排列的列位置?

How can I save rearranged column positions when reading out a DataGrid?

我在 VSTO-AddIn 中的 WPF-window 中实现了 DataGrid,它应该在将数据粘贴到现有 Excel 之前向用户预览数据-sheet。 CanUserSortColumns-Property 设置为 true,因此用户可以在列被读出并粘贴到 sheet 之前重新排列列。但是,当我从 DataGrid 中读出 DataRows 时,如下所示,列又回到了原来的位置。

 object[,] dataArray = new object[allRows, allCols];

        for (int r = 0; r < allRows; r++)
        {
            DataRow row = ClientGrid.Rows[r];
            for (int c = 0; c < allCols; c++)
            {
                dataArray[r, c] = row[c];
            }
        }

这是我的问题:有什么方法可以快速解决这个问题,或者至少跟踪列显示索引的变化,以便在每次更改列显示顺序时重新排列代码中的列顺序?

我已经尝试用 DisplayIndex-属性 解决一些问题,但我不太了解它吐出的数字。

您可以按 DisplayIndex 属性 对列进行排序,并使用反射导出值,例如:

public static void ExportUsingRefection(this DataGrid grid)
{
    if (grid.ItemsSource == null || grid.Items.Count.Equals(0))
        throw new InvalidOperationException("You cannot export any data from an empty DataGrid.");

    IEnumerable<DataGridColumn> columns = grid.Columns.OrderBy(c => c.DisplayIndex);
    ICollectionView collectionView = CollectionViewSource.GetDefaultView(grid.ItemsSource);
    foreach (object o in collectionView)
    {
        if (o.Equals(CollectionView.NewItemPlaceholder))
            continue;

        foreach (DataGridColumn column in columns)
        {
            if (column is DataGridBoundColumn)
            {
                string propertyValue = string.Empty;

                /* Get the property name from the column's binding */
                BindingBase bb = (column as DataGridBoundColumn).Binding;
                if (bb != null)
                {
                    Binding binding = bb as Binding;
                    if (binding != null)
                    {
                        string boundProperty = binding.Path.Path;

                        /* Get the property value using reflection */
                        PropertyInfo pi = o.GetType().GetProperty(boundProperty);
                        if (pi != null)
                        {
                            object value = pi.GetValue(o);
                            if (value != null)
                                propertyValue = value.ToString();
                        }
                    }
                }
                //...
            }
        }
    }
}

更多信息请参考以下博客post。

如何从 WPF 中的 DataGrid 导出数据: https://blog.magnusmontin.net/2013/09/29/export-data-from-a-datagrid/

我最后做了以下事情:

  1. 读出DisplayIndex-Property和每列的初始位置,然后按DisplayIndex-Property排序元组

    var columnIndices = new List<Tuple<int,int>>();
    var colCounter = 0;
    
    foreach (var col in myDataGrid.Columns)
    {
        columnIndices.Add(Tuple.Create(col.DisplayIndex, colCounter));
        colCounter += 1;
    }
    
    var sortedColumns = columnIndices.OrderBy(x => x.Item1).ToList();        
    
  2. 正在创建一个空的 DataTable 并向其中添加原始的 DataGrid's 列。然后我将新的 DataTable's DataRow's 单元格设置为等于原始 DataGrid.

    DataRows 的单元格
    var myDataTable = new DataTable();
    
    foreach (var index1 in sortedColumns)
    {
        var columnName = myDataGrid.Columns[index1.Item2].ColumnName;
        myDataTable.Columns.Add(columnName, myDataGrid.Columns[index1.Item2].DataType);
    }
    
    foreach (DataRow dr in myDataGrid.Rows)
    {
        var itemArray = new object[allCols];
        var indexer = 0;
    
        foreach (var index2 in sortedColumns)
        {
            itemArray[indexer] = dr[index2.Item2];
            indexer += 1;
        }
    
        myDataTable.Rows.Add(itemArray);
    }