Question

Supposons que vous faites quelque chose comme ce qui suit

List<string> myitems = new List<string>
{
    "Item 1",
    "Item 2",
    "Item 3"
};

ComboBox box = new ComboBox();
box.DataSource = myitems;

ComboBox box2 = new ComboBox();
box2.DataSource = myitems

Nous avons donc maintenant 2 zones de liste déroulante liées à ce tableau, et tout fonctionne bien.Mais lorsque vous modifiez la valeur d’une zone de liste déroulante, les DEUX zones de liste déroulante sont remplacées par celle que vous venez de sélectionner.

Maintenant, je sais que les tableaux sont toujours passés par référence (j'ai appris cela quand j'ai appris C :D), mais pourquoi diable les zones de liste déroulante changeraient-elles ensemble ?Je ne pense pas que le contrôle de la zone de liste déroulante modifie du tout la collection.

En guise de solution de contournement, cela ne permettrait pas d'obtenir la fonctionnalité attendue/souhaitée.

ComboBox box = new ComboBox();
box.DataSource = myitems.ToArray();
Était-ce utile?

La solution

Cela a à voir avec la façon dont les liaisons de données sont configurées dans le framework dotnet, en particulier le BindingContext.À un niveau élevé, cela signifie que si vous n'avez pas spécifié le contraire, chaque formulaire et tous les contrôles du formulaire partagent le même BindingContext.Lorsque vous réglez le DataSource propriété le ComboBox utilisera le BindingContext pour obtenir un ConcurrenyMangager cela enveloppe la liste.Le ConcurrenyManager garde une trace de choses telles que la position actuellement sélectionnée dans la liste.

Lorsque vous définissez le DataSource de la seconde ComboBox il utilisera la même chose BindingContext (les formulaires) qui donneront une référence au même ConcurrencyManager comme ci-dessus utilisé pour configurer les liaisons de données.

Pour obtenir une explication plus détaillée, voir Contexte de liaison.

Autres conseils

Une meilleure solution (en fonction de la taille de la source de données) consiste à déclarer deux BindingSource les objets (nouveautés à partir de la version 2.00) lient la collection à ceux-ci, puis les lient aux listes déroulantes.

Je joins un exemple complet.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication2
{
    public partial class Form1 : Form
    {
        private BindingSource source1 = new BindingSource();
        private BindingSource source2 = new BindingSource();

        public Form1()
        {
            InitializeComponent();
            Load += new EventHandler(Form1Load);
        }

        void Form1Load(object sender, EventArgs e)
        {
            List<string> myitems = new List<string>
            {
                "Item 1",
                "Item 2",
                "Item 3"
            };

            ComboBox box = new ComboBox();
            box.Bounds = new Rectangle(10, 10, 100, 50);
            source1.DataSource = myitems;
            box.DataSource = source1;

            ComboBox box2 = new ComboBox();
            box2.Bounds = new Rectangle(10, 80, 100, 50);
            source2.DataSource = myitems;
            box2.DataSource = source2;

            Controls.Add(box);
            Controls.Add(box2);
        }
    }
}

Si vous voulez vous embrouiller encore plus, essayez de toujours déclarer les liaisons dans le constructeur.Cela peut entraîner certains vraiment bugs curieux, c'est pourquoi je me lie toujours à l'événement Load.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top