データソースとそれにバインドするコンポーネントの媒介とすることで、データの操作が容易になります。
DataTable table = new DataTable(); BindingSource bindingSource = new BindingSource(); bindingSource.DataSource = table; bindingSource.Filter = "col1 > 10"; // フィルタ bindingSource.Sort = "col1 ASC"; // ソート dataGridView.AutoGenerateColumns = true; dataGridView.DataSource = bindingSource; // BindingNavigatorと提携するならば、そのBindingSourceに設定する bindingNavigator.BindingSource = bindingSource;媒介手段としての BindingSource コンポーネント - BindingSource コンポーネントの概要 | Microsoft Learn
public BindingSource ( object dataSource, // DataSourceプロパティに設定する値 string dataMember // DataMemberプロパティに設定する値 );BindingSource(Object, String) - BindingSource Constructor (System.Windows.Forms) | Microsoft Learn
引数のないコンストラクタBindingSource()
の呼び出しは、BindingSource(null, String.Empty)
とすることと同じです。BindingSource - Source Browser
型 | プロパティ | 内容 |
---|---|---|
object | DataSource | バインドするデータソース。データソースの型に応じて、Listプロパティで公開されるRemarks - BindingSource.DataSource Property (System.Windows.Forms) | Microsoft Learn |
string | DataMember | バインドするデータソース内の特定の列またはリストの名前 |
IList | List | バインドしているリスト |
object | Item[Int32] | 指定のインデックスにある、リストの要素 |
object | Current | リスト内の、現在の項目 |
CurrencyManager | CurrencyManager | このBindingSourceに関連付けられているcurrency manager |
string | Filter | 表示する行を決定するフィルタの式。式の構文はデータソースに依存する。既定はnull。 |
string | Sort | 並べ替えに使用する列の名前。既定はnull。記述方法はDataView.Sortと同じ |
int | Count | フィルタが適用された状態での、項目の総数 |
bool | RaiseListChangedEvents | trueならば、ListChangedイベントが発生する
このListChangedイベントは、バインドしている項目が追加、削除、挿入や修正などによって変更されたときに発生する このプロパティをfalseとしていた間に発生した変更は、ResetBindings()を呼ぶことで反映できる |
データソースには配列やリスト、それにIListSourceやITypedListを実装する型を設定できます。Remarks - BindingSource.DataSource Property (System.Windows.Forms) | Microsoft Learn
nullを指定したときは、同一の型の項目をリストとして管理できます。
BindingSource b1 = new BindingSource();
b1.DataSource = new[] { 1, 2 };
BindingSource b2 = new BindingSource();
b2.DataSource = new DataTable(); // IListSourceを実装している
BindingSource b3 = new BindingSource();
b3.DataSource = null;
b3.Add(1);
b3.Add(2);
バインドしているリストを得られます。
DataTable table = new DataTable(); table.Columns.Add(); table.Rows.Add(0); table.Rows.Add(1); table.Rows.Add(2); dataGridView.DataSource = table; BindingSource bindingSource = new BindingSource(); bindingSource.DataSource = table; IList list = bindingSource.List; int count = list.Count; // 3 DataRowView rowView = (DataRowView)list[0]; object.ReferenceEquals(rowView.Row, table.Rows[0]); // true
DataTable table = new DataTable(); BindingSource bindingSource = new BindingSource(table, string.Empty); int c1 = bindingSource.Count; // 0 table.Columns.Add("col1", typeof(int)); DataRowCollection rows = table.Rows; rows.Add(1); rows.Add(2); rows.Add(3); table.AcceptChanges(); int c2 = bindingSource.Count; // 3 bindingSource.Filter = "col1 < 3"; int c3 = bindingSource.Count; // 2 rows[0].Delete(); // Deleted int c4 = bindingSource.Count; // 1 rows[0].AcceptChanges(); int c5 = bindingSource.Count; // 1
メソッド | 機能 |
---|---|
SuspendBinding() | データソースの更新からの変更を防止するため、データバインドを一時停止する
これを呼び出してもイベントの発生は抑制できない。これはTextBoxなどの単純なコントロールへのバインドを想定したもので、DataGridViewなどに対してはRaiseListChangedEventsをfalseとすることで対処するRemarks - BindingSource.SuspendBinding Method (System.Windows.Forms) | Microsoft Learn SelectionChangedなどの、一部のイベントは抑制できる。 SuspendBinding() - BindingSource.cs |
ResumeBinding() | SuspendBinding()により停止していた、データバインドを再開する
一時停止していた間に発生した変更は、ResetBindings()を呼ぶことで反映できる |
ResetBindings(Boolean) | データバインドされているすべての項目を再読み込みし、表示している値を更新する |
ResetItem(Int32) | 指定位置の項目を再読み込みし、表示している値を更新する |
RemoveFilter() | フィルタを削除する。既定では、Filterプロパティにnullを設定するのと同じ |
RemoveSort() | 並べ替えを削除する。既定では、Sortプロパティにnullを設定するのと同じ |
Add(Object) | 内部リストに、指定の項目を追加できる |
Remove(Object) | 内部リストから、指定の項目を削除できる |
IndexOf(Object) | 指定の項目のインデックスを取得できる |
Find(String, Object) | 指定のプロパティが指定の値に一致する項目の、最初のインデックスを取得できる |
UIスレッド以外からアクセスすると「BindingSource がそれ自体のデータ ソースであることはできません。DataSource および DataMember プロパティを、BindingSource に参照に帰る値に設定しないでください。(BindingSource cannot be its own data source. Do not set the DataSource and DataMember properties to values that refer back to BindingSource.)」としてInvalidOperationExceptionが投げられます。winforms - "BindingSource cannot be its own data source" - error when trying to reset the binding source from a method in another class - Stack Overflow
public void ResetBindings (bool metadataChanged);BindingSource.ResetBindings(Boolean) Method (System.Windows.Forms) | Microsoft Learn
metadataChangedは、BindingSourceのデータ スキーマが変更されたならばtrue、項目の値だけが変更されたならばfalseとします。
bindingSource.RaiseListChangedEvents = false;
// DataSource の更新
bindingSource.RaiseListChangedEvents = true;
bindingSource.ResetBindings(false);
public int Find ( string propertyName, object key );Find(String, Object) - BindingSource.Find Method (System.Windows.Forms) | Microsoft Learn
propertyNameで指定するオーバーロードでは、その名前からPropertyDescriptorが取得されて、もう一方のオーバーロードが呼び出されます。Find - BindingSource.cs
このメソッドはリストのIBindingList.Find()を呼び出すだけであり、一致する項目がなかったときの動作は、その実装に依存します。複数の項目が一致したときには、最初のインデックスが返されます。
DataTable table = new DataTable(); table.Columns.Add("c1"); table.Columns.Add("c2"); table.Rows.Add(1, 2); table.Rows.Add(3, 4); table.Rows.Add(5, 6); table.Rows.Add(5, 6); dataGridView.DataSource = table; BindingSource bindingSource = new BindingSource(); bindingSource.DataSource = table; dataGridView.DataSource = bindingSource; int index1 = bindingSource.Find("c1", 3); // 1 int index2 = bindingSource.Find("c2", 6); // 2
データソースのフィルタで検索したときには、Listから一致する項目を見つけることで、そのインデックスを得られます。
DataRow[] rows = table.Select("c1 = 3"); DataRow target = rows[0]; int index = 0; for (; index < bindingSource.List.Count; index++) { DataRowView rowView = (DataRowView)bindingSource.List[index]; if (object.ReferenceEquals(target, rowView.Row)) break; } // indexは、1
そのときフィルタも並べ替えも適用されていないならば、データソース内でのインデックスから得られます。
int rowIndex = table.Rows.IndexOf(target); // データソース内での、インデックス DataRowView rowView = table.DefaultView[rowIndex]; // そのインデックス位置にある、バインドされている項目 int index = bindingSource.IndexOf(rowView); // バインドされている項目の、BindingSource内でのインデックス // rowIndexとindexは一致する
DataGridViewにバインドされているとき、一致した項目が含まれる行は、その行にバインドされているオブジェクトと比較することで見つけられます。
foreach (DataGridViewRow viewRow in dataGridView.Rows) { if (object.ReferenceEquals(((DataRowView)viewRow.DataBoundItem).Row, target)) break; }
型 | イベント | 発生タイミング |
---|---|---|
ListChangedEventHandler | ListChanged | Listプロパティ内の項目が追加、除去、移動されたときやDataSourceやDataMemberが変更されたとき |