WinForms ComboBox Datenbindung gotcha

stimmen
44

Angenommen, Sie so etwas wie die folgenden tun

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

So, jetzt haben wir zwei Combo-Boxen gebunden zu diesem Array, und alles funktioniert. Aber wenn Sie den Wert eines Kombinationsfeld ändern, ändert es beide Kombinationsfelder die, die Sie ausgewählt haben.

Nun, ich weiß, dass Arrays werden immer als Referenz übergeben (gelernt, dass, wenn ich C gelernt: D), aber warum auf der Erde würden die Combo-Boxen zusammen ändern? Ich glaube nicht, das Kombinationsfeld die Sammlung überhaupt ändern.

Als Arbeit um, sie würde die funcionality nicht dies zu erreichen, die erwartet / erwünscht

ComboBox box = new ComboBox();
box.DataSource = myitems.ToArray();
Veröffentlicht am 02/08/2008 um 17:09
quelle vom benutzer
In anderen Sprachen...                            


3 antworten

stimmen
37

Dies hat damit zu tun, wie Datenbindungen werden im Dotnet Framework, insbesondere die Einrichtung BindingContext. Auf hohem Niveau bedeutet dies , dass , wenn Sie nicht anders jedes Formular und alle Steuerelemente des Formulars die gleiche angegeben BindingContext. Wenn Sie die setzen DataSourceEigenschaft der ComboBoxwird die Verwendung BindingContextein erhalten ConcurrenyMangager, die die Liste wickelt. Der ConcurrenyManagerverfolgt solche Dinge wie die aktuell ausgewählte Position in der Liste.

Wenn Sie den Satz DataSourceder zweiten ComboBoxwird es für die gleichen Zwecke BindingContext(Formen) , die einen Verweis auf die gleiche Ausbeute wird ConcurrencyManagerwie oben verwendet , um die Datenbindungen einzurichten.

Um eine detailliertere Erläuterung siehe Binding .

Beantwortet am 02/08/2008 um 18:18
quelle vom benutzer

stimmen
20

Eine bessere Behelfslösung (abhängig von der Größe der Datenquelle) ist , zwei zu erklären BindingSourceObjekte (neu ab 2,00) binden , um die Sammlung zu der und dann diese an die Combobox binden.

Anbei ein vollständiges Beispiel.

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);
        }
    }
}

Wenn Sie mehr sich selbst dann verwirren wollen versuchen immer Bindungen in den Konstruktor zu deklarieren. Das kann in einigen führen wirklich neugierig Bugs, also immer binde ich in dem Load - Ereignis.

Beantwortet am 21/08/2008 um 15:48
quelle vom benutzer

stimmen
2

Dies könnte nur ein Tippfehler, aber in dem Code, den Sie, sofern Sie nur das erste Kombinationsfeld verweisen, wenn die Datenquelle einstellen:

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

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

Die Datenquelle für box2nicht gesetzt ist .

Beantwortet am 21/08/2008 um 18:12
quelle vom benutzer

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more