2010-02-12 26 views
13

Ich bin neu in der Datenbindung.WinForms Datenbindung

Ich habe diese Klassen:

public class Foo : List<Bar> 
{ 
    public string FooName { get; set; } 
} 

public class Bar 
{ 
    public string BarName { get; set; } 
    public string BarDesc { get; set; } 
} 

Und ich habe eine List<Foo>

I Foo Artikel in ComboBox und Bar Artikel in ListBox haben möchten. Wenn ich das ausgewählte Element in ComboBox ändere, möchte ich ListBox ändern. Wenn ich das ausgewählte Element in ListBox ändere, möchte ich TextBox mit BarDesc gefüllt haben.

Folgende Arbeiten nur für ListBox und ComboBox:

comboBox1.DataSource = foos; 
comboBox1.DisplayMember = "FooName"; 
listBox1.DataBindings.Add("DataSource", foos, ""); 
listBox1.DisplayMember = "BarName"; 

ich nicht jetzt, wie Bar in ListBox zu TextBox.Text Eigenschaft ausgewählt zu binden. Vielleicht ist eine Bindung für listBox1 keine gute Idee.

Vielleicht sollte ich so etwas tun:

((CurrencyManager)listBox1.BindingContext[foos]).CurrentChanged += new EventHandler((o, a) => 
{ 
    textBox1.DataBindings.Clear(); 
    textBox1.DataBindings.Add("Text", listBox1.DataSource, "BarDesc"); 
}); 

Wie kann ich mein Problem lösen?

+0

Microsoft wollte nie, dass Klassen von 'List ' erben. Ich denke, sie empfehlen 'Collection ' als Basisklasse. – ja72

+0

Ich wusste nichts davon, aber selbst wenn ich zu Collection wechseln würde, wäre das Problem geblieben. Wie auch immer, heutzutage würde ich lieber nicht die Liste "" erweitern, sondern sie stattdessen in "Foo" als eine Eigenschaft zusammenfassen. – prostynick

+0

Ja, das war nur eine Bemerkung, die nichts mit der Lösung des Problems zu tun hat. Siehe http://stackoverflow.com/q/21692193/380384 – ja72

Antwort

17

Um all dies zu machen, musste ich die Items Eigenschaft der Foo Klasse hinzufügen. Dies ist die "Verbindung/Beziehung" zwischen den zwei Bindungsquellen.

public partial class Form1 : Form { 
    public class Foo : List<Bar> { 
     public string FooName { get; set; } 
     public Foo(string name) { this.FooName = name; } 
     public List<Bar> Items { get { return this; } } 
    } 
    public class Bar { 
     public string BarName { get; set; } 
     public string BarDesc { get; set; } 
     public Bar(string name, string desc) { 
      this.BarName = name; 
      this.BarDesc = desc; 
     } 
    } 
    public Form1() { 

     InitializeComponent(); 

     List<Foo> foos = new List<Foo>(); 

     Foo a = new Foo("letters"); 
     a.Add(new Bar("a", "aaa")); 
     a.Add(new Bar("b", "bbb")); 
     foos.Add(a); 

     Foo b = new Foo("digits"); 
     b.Add(new Bar("1", "111")); 
     b.Add(new Bar("2", "222")); 
     b.Add(new Bar("3", "333")); 
     foos.Add(b); 

     //Simple Related Object List Binding 
     //http://blogs.msdn.com/bethmassi/archive/2007/04/21/simple-related-object-list-binding.aspx 

     BindingSource comboBoxBindingSource = new BindingSource(); 
     BindingSource listBoxBindingSource = new BindingSource(); 

     comboBoxBindingSource.DataSource = foos; 
     listBoxBindingSource.DataSource = comboBoxBindingSource; 
     listBoxBindingSource.DataMember = "Items"; 

     comboBox1.DataSource = comboBoxBindingSource; 
     comboBox1.DisplayMember = "FooName"; 

     listBox1.DataSource = listBoxBindingSource; 
     listBox1.DisplayMember = "BarName"; 

     textBox1.DataBindings.Add("Text", listBoxBindingSource, "BarDesc"); 

    } 
} 
+1

Oh, das ist schön 'öffentliche Liste Items {get {return this; }} ' Warum habe ich nicht darüber nachgedacht? :) – prostynick

+1

Weil es nicht sofort offensichtlich ist, dass Sie das Objekt selbst durch eine seiner Eigenschaften zurückgeben wollen/können, es sei denn, Sie haben es zuvor schon einmal passiert. Ich wette, du wirst dich noch viele Jahre an diese Technik erinnern. :O) – AMissico

1

Verwenden Binding für all Ihre komplexe Datenbindung Bedürfnisse:

// bind to List<Foo> 
BindingSource comboBoxBindingSource = new BindingSource(); 
comboBoxBindingSource.DataSource = foos; 
// use this binding source in comboBox1 
// for display use FooName 
comboBox1.DataSource = comboBoxBindingSource; 
comboBox1.DisplayMember = "FooName"; 

// bind to comboBox1's SelectedValue 
// it will point to the Foo selected in combobox 
BindingSource listBoxBindingSource = new BindingSource(); 
listBoxBindingSource.DataSource = comboBox1; 
listBoxBindingSource.DataMember = "SelectedValue"; 
// use this binding source in listBox1 
// for display use BarName 
listBox1.DataSource = listBoxBindingSource; 
listBox1.DisplayMember = "BarName"; 

// bind to comboBox'1s SelectedValue (reusing listBoxBindingSource) 
// and set Text to value of BarDesc 
textBox1.DataBindings.Add("Text", listBoxBindingSource, "BarDesc"); 
0

Sie wahrscheinlich die Valuemember auf der Combo und Listenfeld setzen sollen. Möglicherweise müssen Sie auch bindingSource.CurrentChanged verarbeiten und das Listenfeld erneut an die aktuell ausgewählte Liste binden.

Verwandte Themen