2010-02-25 3 views
3

Scénario:de Windows DataGridView BindingSource Index hors exception gamme

Fondamentalement, j'ai un

  • System.Windows.Forms.DataGridView

  • Une classe qui hérite BindingSource et IBindingList

  • Une classe qui a 2 propriétés standard List comme propriétés privées

DataGridView dgv = new ...

MyBindingSource BindingSource = new ...

liste MyList = new ...

La propriété DataGridView.DataSource se prépare à BindingSource et BindingSource.DataSource est défini sur l'une des listes privées de la liste

bindingSource.DataSource = list.ListA;

dgv.DataSource = bindingSource; Je reçois un tas d'informations en streaming à partir d'une base de données, et je convertis les informations en objets et les ajoute à MyList un à la fois et à la fin devrait être montré dans le DataGridView. Je souhaite que tout cela ait du sens, maintenant le problème: Après avoir ajouté un seul objet à la liste (pas la source de liaison) je veux que l'élément soit affiché dans le DataGridView. Mais la seule façon dont je peux actuellement obtenir que cela fonctionne est de construire une autre instance d'un bindingSource avec le nouvel objet 1 ajouté et de définir le DataGridView.DataSource à la nouvelle liaisonSource. Ce cours est horriblement inefficace et le datagridview doit invalider le tout à chaque fois, ce qui est douteux. Au lieu de cela, je veux que la liste notifie la BindingSource qui indique à DataGridView qu'un nouvel objet a été ajouté afin qu'il puisse faire sa chose. J'ai essayé ceci mais j'ai continué à obtenir une exception d'IndexOutOfrange en disant "l'article à l'index -1 n'a pas de valeur". J'ai regardé le BindingSource et en effet la position était -1 et la propriété Current a jeté cette même exception. Lorsque je crée la nouvelle BindingSource chaque fois que la position et les propriétés actuelles sont correctes.

Alors, que dois-je faire pour que ces propriétés soient mises à jour lorsque j'ajoute un élément à la liste? Je l'ai ouvert avec un réflecteur pour voir où il était placé et ressemblait à "CurrencyManager" avait quelque chose à voir avec ça. J'ai essayé quelques choses comme base.OnDataMemberChanged base.OnListChanged en vain.

Editer: J'ai oublié de mentionner que je ne reçois l'exception que lorsque je clique sur une rangée dans la vue DataGrid, il ajoute les éléments bien. Donc, c'est comme si DataGridView n'était pas synchronisé avec le BindingSource

+0

Êtes-vous capable d'utiliser 'DataTable's au lieu de' List's? J'ai fait beaucoup de choses avec DataTable <-> BindingSource <-> DGV et la mise à jour a toujours fonctionné parfaitement. Je ne suis pas sûr de me lier à List. – Ken

+0

Hmm je ne suis pas trop compétent avec DataTables et je devrais changer beaucoup de code. Donc, j'espère une solution pour ce que j'ai actuellement – Daniel

Répondre

1

Avez-vous envisagé d'utiliser un ObservableCollection? Chaque fois qu'il y a des éléments ajoutés ou retirés de la collection, il notifiera le contrôle auquel il est lié et qui a été mis à jour.Il fera également la même chose avec les propriétés des éléments de la collection ainsi (bien que vous devez soulever l'événement manuellement)

Je ne suis pas sûr de ce à cause pourrait être l'exception

2

Lorsque DataSource modifie son contenu, DataGridView efface sa grille et déclenche l'événement SelectionChanged et d'autres événements liés à l'interaction de l'utilisateur. Il est iportant de savoir que lorsque l'événement est levé, il n'y a aucune donnée à afficher, donc si vous avez un écouteur d'événement SelectionChanged et qu'il accède à des rangées ou colonnes à l'intérieur, il déclenchera une exception hors limite lors de l'accès aux lignes. Solution: vérifiez toujours Rows.count par rapport à la valeur 0 avant d'utiliser des ressources DataGrid. Cheers

Questions connexes