DataExport from DataGrid:用更通用的东西替换开关/大小写

本文关键字:替换 开关 大小写 DataGrid from DataExport | 更新日期: 2023-09-27 18:26:30

我有一个显示项目的数据网格。数据网格绑定到ObservableCollection类型的属性DataGridItems。在代码中,我动态实例化属性DataGridItems,如下所示:

this.DataGridItems = Db.Instance.RetrieveFoldingBoxes();

this.DataGridItems = Db.Instance.RetrieveLabels();

现在我想导出数据网格中显示的(以及过滤/排序的)数据。我可以这样做:

    private void ExportData(ControlDataGrid dataGrid)
    {
        if (dataGrid == null) return;
        //items is type of Telerik.Windows.Data.DataItemCollection
        var items = dataGrid.GetFilteredCollection();
        switch (this.GetSelectedViewComboBoxItemName)
        {
            case "Folding Box":
                var exportItems1 = items.Cast<View_DataExport_FoldingBox>();
                this.GenericExport(exportItems1);
                break;
            //30 cases more...
            case "Label":
                var exportItems2 = items.Cast<View_DataExport_Label>();
                this.GenericExport(exportItems2);
                break;
        }
    }
    private void GenericExport<T>(IEnumerable<T> list) { ... }

但我真的不喜欢这样,因为冗余度太高了。如果我能做这样的事情,那会更优雅:

    private void ExportData(ControlDataGrid dataGrid)
    {
        if (dataGrid == null) return;
        //items == Telerik.Windows.Data.DataItemCollection
        var items = dataGrid.GetFilteredCollection();
        //Getting the generic type in pseudo code
        //Also far from a good solution because I think CurrentItem could be null
        if(items.CurrentItem == null) return;
        var type = Type.GetType(items.CurrentItem);
        var exportItems = items.Cast<type>();
        this.GenericExport<type>(exportItems);
    }

我相信这是可能的,但目前我不知道怎么做。


编辑:这是GenericExport方法的代码:

    private void GenericExport<T>(IEnumerable<T> list)
    {
        using (var excelPackage = new ExcelPackage())
        {
            var name = this.GetSelectedViewComboBoxItemName;
            excelPackage.Workbook.Properties.Company = "COMPANYNAME";
            excelPackage.Workbook.Properties.Author = Configuration.UserName;
            excelPackage.Workbook.Properties.Title = string.Concat("Export for ", name);
            excelPackage.Workbook.Properties.Category = "CATEGORY";
            var worksheet = excelPackage.Workbook.Worksheets.Add(name);
            worksheet.Cells["A1"].LoadFromCollection(list, true, TableStyles.Medium2);
            ExcelSheetFormatter.FormatWorksheet(worksheet, list);
            var fileName = this.GetSelectedViewComboBoxItemName;
            var fileDestination = DataExportHelper.ShowSaveFileDialog(fileName, false);
            if (fileDestination == null) return;
            try
            {
                excelPackage.SaveAs(fileDestination);
            }
            catch (InvalidOperationException)
            {
                throw new PulseException(ExceptionMessage.FileInUse, false);
            }
            DataExportHelper.OpenExportedFileDialog(fileDestination.FullName);
        }
    }

我使用EPPlus 4.0 Beta 2(eppls.codeplex.com/releases/view/118053)将数据导出到excel。

因此,我绑定到了EPPlus的API,它是:

    public ExcelRangeBase LoadFromCollection<T>(IEnumerable<T> Collection, ...);

DataExport from DataGrid:用更通用的东西替换开关/大小写

如果你不能更改GenericExport签名,那么,恐怕反射是你唯一的朋友。假设items实现IList,包含相同类型的项,并且它不是空的:

// make IEnumerable<YourType>
var itemType = items[0].GetType();
var castDef = typeof(Enumerable).GetMethod("Cast");
var cast = castDef.MakeGenericMethod(itemType);
var enumerable = cast.Invoke(null, new[] { items });
// call GenericExport<YourType>
var methodDef = typeof(Program).GetMethod("GenericExport", BindingFlags.Instance | BindingFlags.NonPublic);
var method = methodDef.MakeGenericMethod(itemType);
method.Invoke(this, new[] { enumerable });