WindowsフォームアプリのDataGridView
にカスタムコレクションを表示したい。このカスタムコレクションは、ICollection
およびIEnumerable
を実装します。コレクションを.DataSourceプロパティとして使用して、BindingSource
を設定しました。 DataGridView
は、DataSourceであるBindingSource
を使用するように設定されています。 BindingSource.Add()
メソッドを使用してコレクションに新しいアイテムを追加すると、DataGridView
が新しいアイテムで正しく更新されます。一方、BindingSource
DataSourceは以下を行いません。
MyCustomCollection myCollection = new MyCustomCollection();
myCollection.Add(myCustomObject1);
myCollection.Add(myCustomObject2);
myBindingSource.DataSource(myCollection);
myBindingSource.Add(myCustomObject3);
上記のコードでは、myBindingSourceの内部リストには適切な数のレコード(3)が含まれ、DataGridView
にも3つのレコードが含まれていますが、myCollectionには2つのレコードしか含まれていません。基礎となるmyCollectionを変更しても、BindingSource
またはDataGridView
はBindingList<T>
ではないため、更新されないことはわかっていますが、BindingSource
を直接更新すると、myCollectionも同時に更新されるという印象を受けました。
BindingList<T>
ではないコレクションを使用して、BindingSource
を直接操作するときにコレクションを更新する方法はありますか?
pdate:すべてのパーツ(Collection、BindingSource、DataGridView)でデータを更新する1つの方法は次のとおりです。
myCollection.Add(myCustomObject3);
myBindingSource.DataSource = null;
myBindingSource.DataSource = myCollection;
私はこの問題を攻撃するより良い方法があると確信していますが、これは私が期待していた結果を生成した唯一の方法です。
問題は、塗りつぶしアダプターです。フォームをロードすると、Fillが実行されます。必ずリフィルを行ってから、Resetバインディングでフォローアップしてデータの変更をポストすると、グリッドが更新されます。
例:
WorkTableAdapter.Insert(objData.XAttribute, "",
objData.YAttribute,objLoanData.Amount_IsValid, DateTime.Now, DateTime.Now);
this.WorkTableAdapter.Fill(this.POCDataSet.Work);
this.WorkBindingSource.ResetBindings(false);
代わりに実行できないコンテナを使用する場合は、データソースの変更後にResetBindings()を手動で呼び出す必要があります。
http://msdn.Microsoft.com/en-us/library/system.windows.forms.bindingsource.resetbindings.aspx
BindingSourceにバインドされたコントロールに、リスト内のすべての項目を再読み取りさせ、表示された値を更新させます。
個々のアイテムのリセットは機能します!
私は.ResetBindings(false)でうまくいかず、datsourceを再割り当てすると、1つのアイテムのみが頻繁に変更される場合、ポテンシアルオーバーヘッドでちらつきが発生しました。
PropertyChangedを使用して組み込みメカニズムを試しましたが、何も更新されていません。
ResetItem()を使用した個々のアイテムのリセットが機能しました!
for (int i = 0; i < bindingSource1.Count; i++)
{
bindingSource1.ResetItem(i);
}
さらに良い-bindningsourceの各データ項目に更新イベントがアタッチされている場合、バインドソースでオブジェクトを見つけ、オブジェクトのインデックスを使用してResetItem(idx)を呼び出すことができます。
この場合、カスタムイベント引数には、別のコレクションに含まれるデータオブジェクトへの辞書キーが含まれています。 bindningsource.IndexOf()を使用してオブジェクトが見つかった後、オブジェクトは個別に更新されます。
void Value_PropertyChanged(object sender, RegisterEventArgs e)
{
var idx = bindingSource1.IndexOf(registers_ref[e.registerID]);
if (idx>=0)
{
bindingSource1.ResetItem(idx);
}
}
私は少し前にこの問題に遭遇したと思います-私は自分のコードのファイルを検索しましたが、これが私にとってうまくいった解決策だと思います。
// Applies pending changes to the underlying data source.
this.bindingSource1.EndEdit();
これは、保存ボタンのクリックハンドラーのコンテキストでした。