Vă mulțumim pentru susținere

WinForms ComboBox de legare a datelor gotcha

Să presupunem că faceți ceva de genul următor

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

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

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

Deci acum avem 2 cutii combo legate la acea matrice și totul funcționează bine. Dar când schimbați valoarea unei casete combo, se schimbă ambele casete combo cu cea pe care tocmai ați selectat-o.

Acum, știu că Arrays sunt întotdeauna transmise prin referință (învățat că atunci când am învățat C: D), dar de ce pe pământ s-ar schimba cutia combo? Nu cred că controlul cutie combo modifică colecția.

Ca o muncă în jurul valorii de, nu acest lucru ar atinge funcționalitatea care este de așteptat / dorit

ComboBox box = new ComboBox();
box.DataSource = myitems.ToArray();
0
adăugat editat

3 răspunsuri

Acest lucru are legătură cu modul în care legările de date sunt configurate în cadrul dotnet, în special codul BindingContext . La un nivel ridicat, înseamnă că, dacă nu ați specificat altfel, fiecare formular și toate comenzile formularului au același cod . Când setați proprietatea DataSource , ComboBox va folosi BindingContext pentru a obține un ConcurrenyMangager care înfășoară lista. Codul ConcurrenyManager ține evidența unor lucruri precum poziția curentă selectată din listă.

Când setați DataSource al celui de-al doilea ComboBox , veți folosi același BindingContext (formularele) > ConcurrencyManager ca mai sus utilizat pentru a configura legăturile de date.

Pentru a obține o explicație mai detaliată, consultați BindingContext .

0
adăugat
Se pare că o mulțime de efort pentru a oferi nici un beneficiu și de a face legături de date obligatorii complet contra intuitiv.
adăugat autor Belmiris

O soluție mai bună (în funcție de mărimea sursei de date) este de a declara două obiecte BindingSource (noi începând cu 2.00) să lege colecția cu cele care apoi le leagă pe comboboxuri.

Eu anexez un exemplu 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 myitems = new List
            {
                "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);
        }
    }
}

Dacă doriți să vă confundați chiar mai mult, încercați întotdeauna declanșarea legăturilor în constructor. Asta poate duce la niște bug-uri curioase într-adevăr , de aceea întotdeauna se leagă în evenimentul Load.

0
adăugat
Am găsit unele dintre cele mai ciudate erori nedeclarate cu asta. Cel mai rău scenariu de caz a fost că un combobox a refuzat să se concentreze înapoi la orice alt control: D
adăugat autor Quibblesome
Vă mulțumim pentru indicarea faptului că legarea în constructor duce la unele bug-uri foarte curioase. Am avut o problemă similară și mi-am mutat codul la evenimentul Încărcare și a arătat datele legate.
adăugat autor bunggo

Aceasta ar putea fi doar o tipografie, dar în codul pe care l-ați furnizat, doar referiți prima casetă combo la setarea sursei de date:

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

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

Data source pentru box2 nu este setată.

0
adăugat