WinForms ComboBox-Daten Bindung gotcha
-
08-06-2019 - |
Frage
Angenommen, Sie tun etwas wie das folgende
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 2 combo-Boxen gebunden, dass array, und alles funktioniert einwandfrei.Aber wenn Sie ändern Sie den Wert einer combo-box, es ändert sich die BEIDEN combo-Boxen, um die, die Sie gerade ausgewählt haben.
Nun, ich weiß, dass Arrays werden immer als Referenz übergeben (habe gelernt, dass, als ich erfuhr, C :D), aber warum auf der Erde würde den combo-Boxen gemeinsam?Ich glaube nicht, dass die combo-box-Steuerelement ist eine änderung der Auflistung überhaupt.
Als Problemumgehung können diese nicht erreichen würde die Funktionen, die erwartet/gewünscht
ComboBox box = new ComboBox();
box.DataSource = myitems.ToArray();
Lösung
Das hat damit zu tun, wie Daten, die Bindungen der Einrichtung in das dotnet-framework, insbesondere die BindingContext
.Auf eine hohe Ebene bedeutet dies, dass, wenn Sie haben nicht angegeben, sonst jeder form und alle Steuerelemente des Formulars teilen die gleichen BindingContext
.Wenn Sie die Einstellung der DataSource
Eigenschaft der ComboBox
verwenden Sie die BindingContext
um eine ConcurrenyMangager
die wraps in der Liste.Die ConcurrenyManager
verfolgt solche Dinge, wie die aktuelle position in der Liste.
Wenn Sie die DataSource
der zweite ComboBox
es wird die gleiche BindingContext
(die Formen), die Ausbeute wird eine Referenz auf die gleiche ConcurrencyManager
wie oben verwendet, um die Daten Bindungen.
Eine detaillierte Erläuterung finden Sie unter BindingContext.
Andere Tipps
Eine bessere Lösung (abhängig von der Größe der datasource) ist zu erklären, zwei BindingSource
Objekte (neu ab 2.00) binden die Sammlung zu denen und dann binden diese an die comboboxes.
Lege ich 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 wollen, um zu verwirren dich noch mehr, dann versuchen Sie immer erklären Bindungen in den Konstruktor.Das kann dazu führen, dass einige wirklich neugierig Fehler, daher habe ich immer bind im Load-Ereignis.