DataExport от DataGrid: заменить переключатель / регистр чем-то более общим

1

У меня есть datagrid, который отображает элементы. Datagrid привязан к свойству DataGridItems типа ObservableCollection. В коде я динамически создаю свойства DataGridItems следующим образом:

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

или

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

Теперь я хочу экспортировать отображаемые данные (и фильтровать/отсортировать) в datagrid. Я мог бы сделать это так:

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

Я уверен, что это возможно, но в настоящее время я понятия не имею, как это сделать.


EDIT: вот код для метода 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 (epplus.codeplex.com/releases/view/118053), чтобы экспортировать данные в excel.

Поэтому я связан с API EPPlus, который:

    public ExcelRangeBase LoadFromCollection<T>(IEnumerable<T> Collection, ...);
  • 1
    Можете ли вы сделать GenericExport не общим? private void Export(IEnumerable items)
  • 0
    Отличается ли код в GenericExport<T> от типа к типу?
Показать ещё 2 комментария
Теги:
generics
wpf
radgridview

1 ответ

1
Лучший ответ

Если вы не можете изменить подпись 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 });
  • 0
    Думаю, я вас неправильно понял. Я могу изменить метод GenericExport, но не могу изменить коллекцию LoadFromCollection, используемую в методе GenericExport. Методы LoadFromCollection принимают IEnumerable <T> в качестве параметра.
  • 0
    @Joel: «но я не могу изменить LoadFromCollection» - следовательно, вы не можете изменить GenericExport , потому что, в конце концов, вам придется вызывать любой универсальный метод, либо ваш, либо сторонний.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню