“BindingSource ne peut pas être sa propre source de données” - erreur lors de la réinitialisation de la source de liaison à partir d'une méthode d'une autre classe
Nous sommes la liaison d'une DataGridview
à l'aide de BindingSource
. Ainsi, dans le thread principal, nous avons donné comme ça.
class1BindingSource = new BindingSource();
class1BindingSource.DataSource = class1List;
this.dataGridView1.DataSource = class1BindingSource;
Après que j'ai mis un fond travailleur dans la forme et le déclenchement en un clic de bouton.
c'est à dire dans le bouton cliquez sur
this.backgroundWorker1.RunWorkerAsync()
Dans le BackgroundWorker
DoWork Event
je suis en train de mettre à jour le BindingSource
et il y en essayant de mettre à jour le DataGridview
.
De sorte que le BindingSource
reset est fait dans une méthode d'une autre classe.
DoWork Event
Class2 cl2 = new Class2();
cl2.UpdateBindingSource(class1BindingSource);
UpdateBindingSource Method
public void UpdateBindingSource(BindingSource bs)
{
Class1 c1 = bs.Current as Class1;
for (int i = 0; i < 1000; i++)
{
lock (bs.SyncRoot)
{
c1.MyProperty1 = i;
bs.ResetItem(0);
}
}
}
Maintenant, je me fais une exception comme BindingSource
ne peut pas être sa propre source de données. Ne définissez pas la DataSource
et DataMember
propriétés à valeurs qui renvoient à BindingSource
.
Si je fais cela dans mon DoWork Event
alors je peux réinitialiser l'élément dans le contrôle de fil lui-même à l'aide de BeginInvoke method
.
Mais en fait je suis en train de simuler notre scénario de l'application. Je tiens donc à résoudre ce dans ce format.
Quelqu'un peut-il m'aider sur ce point.
OriginalL'auteur Mahesh KP | 2013-01-10
Vous devez vous connecter pour publier un commentaire.
Le problème est que vous ne pouvez pas mettre à jour un
BindingSource
dans un autre thread que le thread gui. Cela est dû au fait que leBindingSource
va déclencher certains événements qui seront ensuite reçus par vos données affichage de la grille qui sera ensuite commencer à mettre à jour lui-même, qui ne cause qu'il ne sera pas fait sur le thread gui.Donc, juste avant que vous appelez
RunWorkerAsync()
vous devriez appelerclass1BindingSource.SuspendBinding()
et à l'intérieur de votreRunWorkerCompleted
vous devriez appelerclass1BindingSource.ResumeBinding()
.Également à ce que, dans votre
DoWork
vous n'aurez pas d'appeler une méthode sur la source de liaison (comme vous l'avez fait avecbs.ResetItem(0)
).Et également supprimer cette instruction lock. Il n'a tout simplement pas de sens (dans votre exemple) et si vous en avez vraiment besoin (dans votre code réel) envisager d'utiliser une
private object _Gate = new Object();
au sein de votre classe afin d'éviter toute blocages du monde extérieur, à causebs.SyncRoot
est publiquement disponible.j'ai compris que l'erreur est à l'origine lors de la tentative de mise à jour de la source de données à partir d'un autre thread, c'est à dire pas du thread d'INTERFACE utilisateur. Est-il possible d'invoquer ou d'appel gridview.BeginInvoke de cette méthode? je pense à ce, qui permettra également de résoudre le problème..
Supprimer la
lock
et labs.ResetItem()
appel; encapsuler lesc1.MyProperty1 = i' into a
Invoke()` appel. Mais cela peut conduire à d'autres problèmes, car vous êtes constamment en sautant entre deux threads. Il est donc préférable de suspendre la source de liaison, de faire les choses en arrière-plan et de reprendre la liaison quand il est terminé.Désolé, je ne comprenais pas, comment puis-je encapsuler la c1.MyPropert1=i à un appel invoke.Depuis, la chose est dans une autre classe. Aussi, si je retire ResetItem(), alors comment ça va relier le gridview?
OriginalL'auteur Oliver
J'ai eu le même problème:
- BindingSource qui ont des éléments avec INotifyPropertyChanged
- Une Tâche distincte, qui a mis à jour les éléments.
Les solutions proposées SuspendBinding etc ne fonctionnent pas. BindingSource doit avoir fait quelque chose comme IsInvokeRequired.
Heureusement, Ivan Stoev est venu avec l'idée géniale de sous-classer le BindingSource et faire quelque chose de similaire comme IsInvokeRequired. Merci Ivan!
Lien: Mise à jour BindingSource à partir d'une autre Tâche
OriginalL'auteur Harald Coppoolse
UpdateBindingSource()
ne prend pas beaucoup de temps, donc pas besoin d'utiliserbackgroundworker
. Vous pouvez appelerUpdateBindingSource()
dans le thread principal.Aussi, gardez datagridview manipulation dans le thread principal.
OriginalL'auteur Kamil