2009-11-02 5 views
1

J'ai un formulaire avec un DataGridView lequel DataSource est une BindingSource à une table. Cette vue aura une sélection de ligne unique et un bouton à supprimer, éditera la ligne sélectionnée actuelle dans un formulaire de popup et un bouton d'insertion qui utilisera également le même formulaire.Synchroniser un formulaire WinForm avec DatagridView

Ma question est comment puis-je synchroniser le formulaire pop avec la ligne en cours?

J'ai essayé d'utiliser l'événement RowStateChanged pour obtenir et stocker la ligne sélectionnée en cours d'utilisation dans le formulaire mais je coudnt. Après l'événement, je reçois la ligne qui a été sélectionnée auparavant. Autre chose que je ne comprends pas encore en C# comment avoir un seul recordSet et savoir quel est l'enregistrement en cours même si c'est un nouveau être inséré d'une manière qu'une fois dans le formulaire toutes les données entrées apparaîtront au même heure dans le DataGridView.

Répondre

1

Vous n'avez pas besoin de synchroniser le formulaire avec la ligne en cours. Voilà à quoi sert un BindingSource. Lorsque vous effectuez une liaison simple à BindingSource, chaque fois que son élément actuel change, les contrôles liés sont mis à jour et chaque fois que les valeurs dans les contrôles liés changent, les valeurs sous-jacentes dans l'élément lié sont mises à jour. Lorsque vous effectuez une liaison complexe (le contrôle lié affiche la liste de BindingSource, pas seulement l'élément en cours), la modification de Position sur le BindingSource modifie également la position actuelle dans le contrôle lié, et vice versa.Donc, dans ce cas, vous souhaitez lier les contrôles sur votre deuxième formulaire en utilisant une liaison simple, et le DataGridView sur votre première utilisation de liaison complexe.

La seule chose inhabituelle que vous devez faire est de vous assurer que les deux formulaires utilisent le mêmeBindingSource. Lorsque vous faites cela, en cliquant sur une nouvelle ligne dans le DataGridView met à jour le Position sur le BindingSource et le BindingSource pousse les valeurs de l'élément lié actuel à tous les contrôles simplement liés qui lui sont liés.

Ceci est facilement accompli. En supposant que Form1 est la forme avec le DataGridView et Form2 est celui avec les commandes simplement liés, faites ceci:

Dans Form1:

private BindingSource Source = new BindingSource(); 

Form1_Load(object sender, EventArgs e) 
{ 
    // set Source's DataSource to your DataTable here. 
    mainDataGridView.DataSource = source; 
    // create DataGridView columns and their bindings here. 

    Form2 f2 = new Form2(); 
    f2.TopMost = true; 
    f2.Source = Source; 
    f2.Show(); 
} 

En Form2:

public BindingSource Source { get; set; } 

public void Form2_Load(object sender, EventArgs e) 
{  
    idTextBox.DataBindings.Add("Text", Source, "id"); 
    descriptionTextBox.DataBindings.Add("Text", Source, "description") 
} 
+0

Vous l'avez, merci beaucoup. J'ai fait la chose et ça marche bien. Je ne sais pas encore comment valider mes changements et aussi, le test que j'ai fait, la nouvelle ligne ajoutée montre juste certaines valeurs du formulaire une fois qu'il est éliminé mais quand une autre ligne est sélectionnée, les valeurs sont là. –

+1

Dans la plupart des cas, les modifications sont validées chaque fois que 'Position' change, c'est-à-dire lorsque l'utilisateur passe à une autre ligne. Vous pouvez explicitement valider les modifications en attente sur la ligne en cours en appelant 'EndEdit' sur' BindingSource'. (Et vous pouvez les annuler en appelant 'CancelEdit'.) Dans la mesure où l'ajout d'une nouvelle ligne va: quand une nouvelle ligne est ajoutée, chaque colonne de la nouvelle ligne est remplie avec tout' DefaultValue' défini dans son 'DataColumn '. Ensuite, il est ajouté à la liste et tous les contrôles liés au complexe sont informés que la nouvelle ligne existe et qu'ils l'affichent. –

1

Vous pouvez facilement le synchroniser sans utiliser BindingSource.

La liaison de données Windows Forms est construite au-dessus de quelques interfaces les plus importantes sont: IList et IBindingList. Le premier est juste responsable de fournir l'accès aux éléments par leur index dans la liste (pour le rendre simple) le second est en réalité plus compliqué.

IBindingList - (qui est mis en œuvre par BindingSource) a des méthodes pour soutenir:

  • notification de changement
  • ajouter nouvel élément "vide"
  • tri
  • recherche

Le celui qui est important pour vous est évidemment la notification de changement. Malheureusement, BindingSource n'implémente pas ce bit de code. Vous pouvez faire deux choses ici - soit implémenter votre version de BindingSource avec une notification de modification, soit essayer de jouer avec les événements DGV et textboxes/comboboxes pour mettre à jour les données.

Personnellement, j'ai fait le premier (je peux partager le code que j'ai). "Autre chose que je ne comprends pas encore en C# comment avoir un seul recordSet et savoir quel est l'enregistrement en cours même si c'est un nouveau être inséré d'une manière qu'une fois dans le formulaire toutes les données entrées apparaîtront au en même temps dans DataGridView. "

Chaque formulaire a un objet BindingContext qui conserve CurrencyManagers - un pour chaque DataSource. De cette façon, chaque contrôle lié à la même source de données sait quel enregistrement est en cours. En fait, BindingNavigator joue avec le CurrencyManager approprié et appelle ses méthodes. (Je n'ai aucune idée pourquoi il nécessite BindingSource au lieu de dans IList minimum ou pour la fonctionnalité complète IBindingList)

+0

TKS Kubal pour la réponse, mais je pense que je ne comprends presque rien. Je suis nouveau en C#, et travaille principalement avec Java et je me souviens d'utiliser, dans le passé, les jeux d'enregistrements VB où je pouvais simplement revenir en arrière avec des données. Il semble maintenant que C# utilise un jeu d'enregistrements déconnecté et que les modifications apportées à DataGridView doivent être mises à jour «manuellement» dans la base de données. Je suis à la recherche d'un moyen simple pour cela, de préférence en utilisant seulement l'interface RAD, mais il semble que j'ai besoin d'apprendre beaucoup plus et je ne vois pas de bonne source à ce sujet pour pointer vers les meilleures pratiques. Je vais essayer de faire mes devoirs mais je cherche toujours une solution simple. –

+0

Il y a certainement des circonstances dans lesquelles vous voudrez entrer dans le monde de 'IBindingList' et' BindingContext' et 'CurrencyManager', mais garder les contrôles synchronisés avec un' DataTable' n'en fait pas partie. –