WPF DataGridRow在列排序后不更新单元格顺序

时间:2013-10-11 13:14:34

标签: c# wpf sorting datagrid

我有一个DataGrid,填充后我想将其导出为Excel格式。到目前为止,我能够做到这一点。当我尝试对列顺序进行排序时,我的问题出现了。标头是按照正确的顺序构建的,但DataGridRows不是。

图像显示最终结果:

Column Sort

在这个例子中,我将'ID Equipa'列与'Tipo Entidade'交换,但是在excel文件(右侧)中,行值继续,好像在标题更新时没有发生任何变化。

不知道这是否有帮助,但我的'ExportToExcel'类基于此项目ExportToExcel Project,而不是使用它的类标识符

public class ExportToExcel<T, U>
where T : class
where U : List<T>
{
    // ...
}

我创建了这个

public class ExportToExcel
}
    public ExportToExcel(List<DataGridColumn> columns, List<DataGridRow> dataToFill)
        {
            // ...
        }
}

我认为问题出在我的'dataToFill'参数中,因为它保留了默认的单元格顺序,并且在列排序事件后不会更新。

我不明白为什么会这样。如果有人能对这个问题有所了解,我真的很感激。

由于

编辑:

根据Sheridan的建议,我发布了一些额外的代码。

这就是我提取DataGrid行的方法

public IEnumerable<DataGridRow> GetDataGridRows()
    {
        var itemsSource = dgEntities.ItemsSource as IEnumerable;
        if (null == itemsSource) yield return null;
        foreach (var item in itemsSource)
        {
            var row = dgEntities.ItemContainerGenerator.ContainerFromItem(item) as DataGridRow;
            if (null != row) 
            {
                if (dgEntities.SelectedItems.Count == 0) yield return row;
                else if (row.IsSelected) yield return row;
            }
        }
    }

以下是我如何设置ExportToExcel类

public void ExportToExcel() 
    {
        if (dgEntities.ItemsSource != null)
        {
            try
            {
                BLL.ExportToExcel export = new ExportToExcel(dgEntities.Columns.ToList(), GetDataGridRows().ToList());
                export.GenerateReport();
            }
            catch (Exception e)
            {
                MessageBox.Show(e.ToString());
            }
        }
    }

下一步是我对前面提到的CodeProject项目的原始代码的覆盖

private object[] CreateHeader()
    {
        // Create an array for the headers and add it to the
        // worksheet starting at cell A1.
        List<object> objHeaders = new List<object>();
        foreach (DataGridColumn dgc in Columns)
        {
            if (dgc.Visibility == System.Windows.Visibility.Visible) objHeaders.Add(dgc.Header);
            else deletedColumns.Add(dgc.DisplayIndex);
        }

        var headerToAdd = objHeaders.ToArray();
        AddExcelRows("A1", 1, headerToAdd.Length, headerToAdd);
        SetHeaderStyle();

        return headerToAdd;
    }

    private void WriteData(object[] header)
    {
        object[,] objData = new object[DataToFill.Count, header.Length];

        for (int j = 0; j < DataToFill.Count; j++)
        {
            DataGridRow row = DataToFill[j];
            int i = 0;
            for (int x = 0; x < Columns.Count; x++)
            {
                if (!deletedColumns.Contains(x))
                {
                    DataGridCell cell = GetCell(row, j, x);
                    if (cell != null && cell.Content is TextBlock)
                    {
                        objData[j, i] = ((TextBlock)cell.Content).Text;
                        i++;
                    }
                }
            }
        }
        AddExcelRows("A2", DataToFill.Count, header.Length, objData);
        AutoFitColumns("A1", DataToFill.Count + 1, header.Length);
    }

1 个答案:

答案 0 :(得分:0)

你真的不应该使用你不了解的代码......这是使用你在互联网上找到的代码的问题。

如果您查看CreateHeader方法,您会看到标题标题来自该行:

PropertyInfo[] headerInfo = typeof(T).GetProperties();

这只是遍历您的类中定义的属性,与您的排序数据无关。要以简单的方式解决您的问题,只需重新排序headerInfo变量以匹配您的排序数据。

但是,我建议您解决问题是学习代码正在做什么然后根据您的要求进行调整的更困难的方法。

更新&gt;&gt;&gt;

在看到您正在迭代DataGrid.ItemsSource集合之后,我猜测这是您的问题,因为该集合在UI中排序后将保持不变。您有几个选择...一种方法是更新绑定到ItemsSource属性的实际集合以响应用户&#39;点击网格中的各种标题 - 这样,您当前的数据提取方法就可以了。

使用更常用的方法可能是在集合与CollectionViewSource之间使用DataGrid.ItemsSource对象 ...请参阅CollectionViewSource Class页面MSDN对此有所帮助,包括XAML示例。基本上,使用此方法时,您可以从CollectionViewSource对象获取其排序(和过滤)状态集合的副本。