web-dev-qa-db-ja.com

WinFormsのBindingSourceを更新してもDatasourceコレクションは更新されません

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またはDataGridViewBindingList<T>ではないため、更新されないことはわかっていますが、BindingSourceを直接更新すると、myCollectionも同時に更新されるという印象を受けました。

BindingList<T>ではないコレクションを使用して、BindingSourceを直接操作するときにコレクションを更新する方法はありますか?

pdate:すべてのパーツ(Collection、BindingSource、DataGridView)でデータを更新する1つの方法は次のとおりです。

myCollection.Add(myCustomObject3);
myBindingSource.DataSource = null;
myBindingSource.DataSource = myCollection;

私はこの問題を攻撃するより良い方法があると確信していますが、これは私が期待していた結果を生成した唯一の方法です。

12
Jeff Clare

問題は、塗りつぶしアダプターです。フォームをロードすると、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);
6
Frank

代わりに実行できないコンテナを使用する場合は、データソースの変更後にResetBindings()を手動で呼び出す必要があります。

http://msdn.Microsoft.com/en-us/library/system.windows.forms.bindingsource.resetbindings.aspx

BindingSourceにバインドされたコントロールに、リスト内のすべての項目を再読み取りさせ、表示された値を更新させます。

2
Eric J.

個々のアイテムのリセットは機能します!

私は.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);                
        }

    }
1
tofo

私は少し前にこの問題に遭遇したと思います-私は自分のコードのファイルを検索しましたが、これが私にとってうまくいった解決策だと思います。

        // Applies pending changes to the underlying data source.
        this.bindingSource1.EndEdit();

これは、保存ボタンのクリックハンドラーのコンテキストでした。

1
Aaron Anodide