0

我使用通过反射填充 itemsSource 的数据网格(methodDefinition.Invoke(..)),目标方法返回 IQueryable<T>,其中 T 是运行时已知的 EntityType。

由于返回类型是 IQueryable<T>,而当我这样做时,IQueryable<T> 实现了 IEnumerable:

dataGrid1.ItemsSource = methodQuery.Invoke(instance, parameters) as IEnumerable<object>;

我能够看到行和列(加上引发了 AutoGeneratingColumns 事件,因此我可以管理列)但我无法通过单击其标题对行进行排序。

然后我尝试这样做:

dataGrid1.ItemsSource = methodQuery.Invoke(instance, parameters) as List<object>;

但正如我所料,抛出了一个异常,说我不能直接将泛型类型从“Model.Tab_001”转换为“object”。

此外,我尝试在运行时将结果转换为 List<T>(通过 IEnumerable.ToList() 的扩展,创建一个实现将源转换为 List<T> 的函数的委托),但由于 T 仅在运行时和对象(从 methodDefinition.invoke 返回)不能使用扩展 .ToList() ,而在使用此方法之前没有 T 类型的显式声明。

@edit:当我将此方法与相同的 IEnumerable< object > (在数据网格上工作)和 ToList() 扩展方法一起使用时,数据网格被空白行填充,而且它没有触发 AutoGeneratingColumns。所以我看不到结果,只是一个充满空行的dataGrid。

还尝试将结果转换为 ObservableCollection,与 List 相同的问题。

是否有一种不同的方法可以通过单击列标题旁边的列标题来对数据网格的行进行排序,并将列表用作数据网格的 ItemsSoure?

4

2 回答 2

0

为什么不先投射,然后转换?

var ienum = (IEnumerable<object>)methodQuery.Invoke(instance, parameters);
dataGrid1.ItemsSource = ienum.ToList();

(也仅as在您null事后检查时使用)

于 2013-08-16T18:23:54.770 回答
0

我找到了一种更简单的方法。

我没有将 dataGrid 设置为 AutoGenerateColumns,而是将属性通知器设置为 dataGrid 的 ItemsSource,然后使用直接强制转换为 IEnumerable< object> 填充它,然后使用 ToList() 扩展。

每当我的数据源发生更改时,我都会手动添加列,并使用其正确的标题和绑定。

现在我可以通过单击列标题对行进行排序。

代码:

...
dataGrid1.ItemsSource = (IEnumerable<object>)methodQuery.Invoke(instance, parameters).ToList();
...

...

private void DataGridItemsSourceChanged(object sender, EventArgs e)
{
        var currentDataGrid =  (DataGrid)sender;

        foreach (TSpe_Reg reg in tabItemSourceChange.TSpe_Reg) // tabItemSourceChange is used to check the table and field names, since im using reflection.
        {
            string headerName = "";
            if (reg.a_short_name != "")
                headerName = reg.a_short_name;
            else
                headerName = reg.a_full_name;
            string boundColumn = "a_" + reg.a_field_name + "_" + tabItemSourceChange.a_table_name;
            DataGridTextColumn ColumnDataGrid = new DataGridTextColumn { Header = headerName, Binding = new Binding(boundColumn) };

        }
}


// Calls the DataGridItemsSourceChanged whenever the DependencyProperty ItemsSource is changed.
private void CallItemSourcePropertyDescriptor(DataGrid currentDataGrid)
    {
        var dpd = DependencyPropertyDescriptor.FromProperty(ItemsControl.ItemsSourceProperty, typeof(DataGrid));
        if (dpd != null)
        {
            dpd.AddValueChanged(currentDataGrid, DataGridItemsSourceChanged);
        }
    }
于 2013-08-20T13:44:02.247 回答