.Netデータテーブルは、データ駆動型の アプリケーションを作成するときに非常に便利です。しかし、テーブルには データローの任意のリストにグリッド(または他のコントロール)をバインドするための明白な方法はありません。 DataSourceをDataTable自体に設定することで、テーブル全体に直接バインドできます。また、フィルタ付きのDataViewを作成して、テーブルのサブセット にバインドできます。
一般に、IEnumerable(たとえば、LINQクエリ)にバインドすることはできません。 データバインディングインフラストラクチャは、IList(非汎用) またはIListSourceのみを処理できます。これは、あらゆる種類のデータソースに当てはまります。 したがって、任意のLINQクエリにバインドするには、.ToList()を呼び出す必要があります。 (または .ToArray())
ただし、DataTableにバインドする場合は、 リストも使用できません。試してみると、4つの列(RowError、 RowState、Table、およびHasErrors)があり、有用な情報は得られません。この は、リストがDataRowsの特別なプロパティについてデータバインディング インフラストラクチャに通知しないために発生します。 に問題を理解するには、背景が必要です
データバインディングはListBindingHelperおよびTypeDescriptor クラスによって制御されます。リストにバインドすると、 ListBindingHelper.GetListItemPropertiesメソッドが呼び出され、リスト内の 列が取得されます。リストがITypedListインターフェイスを実装している場合は、 GetItemPropertiesメソッドが呼び出されます。それ以外の場合は、 TypeDescriptorを使用して、リスト内の最初の項目のプロパティを取得します。 (これは、リフレクションを使用)(データテーブルも IListSourceを用いて、スルー結合)ITypedListを実装し、テーブルの列を露出 DataColumnPropertyDescriptorsを返し
データビュークラス。 これは、DataViewまたはDataTableにバインドして列を表示できる理由です。 ただし、Listにバインドすると、 がプロパティとして列を返すことができるITypedListはありません。したがって、それは 反射に戻り、DataRowクラスの物理的特性を示します。
この問題を解決するには、 のITypedList実装を利用できるように、DataViewでリストをラップする必要があります。 AsyncView()メソッドを使用して とすることができます。このメソッドは、DataTableクラスとEnumerableRowCollectionクラスの でのみ使用できます。任意のLINQクエリで を呼び出すことはできません。特別なバージョンのCast、 OrderBy、Where、およびSelectメソッドをDataTableから呼び出すことによって、 EnumerableRowCollectionのみを取得できます。
したがって、クエリで AsDataView()を呼び出すことによって、単純なLINQクエリにデータバインドすることができます。 AsEnumerable()の呼び出しは、型付きデータセットには必要ありません
List<DataRow> list = ...;
grid.DataSource = datatable.AsEnumerable()
.Where(list.Contains)
.AsDataView();
:リストに、以上の 複雑なクエリにバインドするには、醜いハックを使用することができます。
CopyToDataTable()を呼び出すこともできます。 IEnumerableでは[sic]が動作します。ただし、行のディープコピーを作成するので、 ユーザーにデータを更新させたい場合、または の場合、元のdatarowsに加えられた変更をユーザーに表示させたい場合は役に立ちません。