web-dev-qa-db-fra.com

La mise à jour de BindingSource dans WinForms ne met pas à jour la collection de sources de données

Je souhaite afficher une collection personnalisée dans une DataGridView dans une application Windows Forms. Cette collection personnalisée implémente ICollection et IEnumerable. J'ai configuré une BindingSource en utilisant la collection en tant que propriété .DataSource. La DataGridView est configurée pour utiliser ma BindingSource en tant que source de données. Lorsque j'ajoute un nouvel élément à la collection à l'aide de la méthode BindingSource.Add(), la variable DataGridView est mise à jour correctement avec le nouvel élément. La source de données BindingSource, en revanche, ne:

MyCustomCollection myCollection = new MyCustomCollection();

myCollection.Add(myCustomObject1);
myCollection.Add(myCustomObject2);

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

Dans le code ci-dessus, la liste interne de myBindingSource contient le nombre correct d'enregistrements (3), et la variable DataGridView contient également trois enregistrements, mais myCollection ne contient que deux enregistrements. Je sais que changer le myCollection sous-jacent ne mettra PAS à jour le BindingSource ou le DataGridView, car ce n'est pas un BindingList<T>, mais j'avais l'impression que la mise à jour directe d'un BindingSource permettrait de s'assurer que myCollection était mis à jour en même temps.

Existe-t-il un moyen d’utiliser une collection qui n’est pas un BindingList<T> et de le mettre à jour lorsqu’il interagit directement avec la BindingSource?

Mise à jour : Les données mises à jour pour toutes les parties (Collection, BindingSource, DataGridView) sont les suivantes:

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

Je suis à peu près sûr qu'il existe un meilleur moyen de s'attaquer à ce problème, mais c'est la seule méthode qui a généré les résultats que j'attendais. 

12
Jeff Clare

Le problème est Fill Adapter . Lorsque vous chargez votre formulaire, le Remplir est fait pour vous. Assurez-vous simplement de faire une recharge, puis effectuez un suivi avec Réinitialiser les liaisons et modifiez les données. La grille sera mise à jour.

Exemple :

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

Si vous utilisez un conteneur qui ne peut pas le faire pour vous, vous devrez appeler manuellement ResetBindings () après la modification de la source de données.

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

Force un contrôle lié à BindingSource à relire tous les éléments de la liste et à actualiser leurs valeurs affichées.

2
Eric J.

Réinitialiser un élément individuel fonctionne!

Je n'ai pas eu de chance avec .ResetBindings (false) et la réaffectation de la source de données a provoqué un scintillement avec une surcharge potentielle si un seul élément changeait fréquemment.

J'ai essayé le mécanisme intégré en utilisant PropertyChanged mais rien n'a été mis à jour.

Réinitialiser un élément individuel en utilisant ResetItem () a fonctionné! 

        for (int i = 0; i < bindingSource1.Count; i++)
        {
            bindingSource1.ResetItem(i);   
        }

Et même mieux - si vous avez un événement de mise à jour attaché à chaque élément de données dans bindningsource, vous pouvez localiser l'objet dans la source de liaison et utiliser l'index de l'objet pour appeler ResetItem (idx).

Dans ce cas, mes arguments d'événement personnalisés contiennent une clé de dictionnaire pour l'objet de données contenu dans une collection séparée. Une fois que l’objet est localisé dans l’utilisation de bindningsource.IndexOf (), il est actualisé individuellement.

    void Value_PropertyChanged(object sender, RegisterEventArgs e)
    {

        var idx = bindingSource1.IndexOf(registers_ref[e.registerID]);
        if (idx>=0)
        {
            bindingSource1.ResetItem(idx);                
        }

    }
0
tofo