0

リフレクション (methodDefinition.Invoke(..)) によって itemsSource を満たすデータグリッドを使用しています。ターゲット メソッドは 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 > に変換する関数を実装するデリゲートを作成します)。ランタイムとオブジェクト (methodDefinition.invoke から返される) は、このメソッドを使用する前に型 T を明示的に宣言しないと、拡張子 .ToList() を使用できません。

@edit: このメソッドを同じ IEnumerable< object > (datagrid で動作する) および ToList() 拡張メソッドで使用すると、datagrid が空白行でいっぱいになり、AutoGeneratingColumns が起動されません。したがって、空白行でいっぱいの dataGrid だけで、結果を見ることができません。

また、結果を ObservableCollection に変換しようとしたところ、リストで同じ問題が発生しました。

リストをデータグリッドの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 に答える