2016-04-19 15 views
4

Ich möchte eine Anwendung erstellen, die Daten aus einer Datenbank liest und dann über eine UI zeigt. Der Benutzer kann dann Felder hinzufügen/löschen/aktualisieren und sie in der DB speichern, ziemlich Standard, oder?DataBinding() funktioniert nicht mit Distinct() (Entity Framework)

Ich habe zwei Tabellen: Motoren und Maßnahmen. Motors Tisch hat viele Felder, einer von ihnen ist "Firma". Natürlich kann es mehrere Motoren von derselben Firma geben, daher möchte ich diese Firmen filtern und nur die verschiedenen in einer ComboBox bekommen.

Ich spiele immer noch mit der Sprache und VS, also habe ich eine einfache Version der Benutzeroberfläche gemacht, wo der Benutzer einen neuen Motor hinzufügen kann, in der Tat kann der Benutzer das Firmenfeld hinzufügen, weil ich ' Ich versuche, eine neue Firma hinzuzufügen und zu sehen, ob sie automatisch in der ComboBox aktualisiert wird.

Dazu verwende ich Entity Framework und dieses Tutorial von Msdn für die Datenbindung:

https://msdn.microsoft.com/en-us/data/jj682076.aspx

Das Problem ist, dass, wenn ich hinzufügen, einen neuen Motor (mit einer neuen Gesellschaft), es nicht aktualisiert, wenn ich die unterschiedlichen diejenigen Filter, meine ich, der folgende Code tut Arbeit und aktualisiert automatisch die comboBox mit allen Firmen:

 private void MainForm_Load(object sender, EventArgs e) 
    { 
     _context = new MotorsContext(); 
     _context.Motors.Load(); 

     this.companyBindingSource.DataSource = _context.companies.ToBindingList(); 
     companyBindingSource.ListChanged += CompanyBindingSource_ListChanged; 
    } 

und die folgende nicht:

private void MainForm_Load(object sender, EventArgs e) 
{ 
    _context = new MotorsContext(); 
    _context.Motors.Load(); 

    this.companyBindingSource.DataSource = _context.Motors.Local.ToBindingList().Select(x => x.company).Distinct(); 
    companyBindingSource.ListChanged += CompanyBindingSource_ListChanged; 
} 

ich eine Listchanged Methode erstellt habe, um zu sehen, wenn die Software nicht erkennt, dass die Liste hat in der Tat verändert. Im ersten Code wird zwar ausgelöst, im zweiten aber nicht. Vielleicht erkennt der Beobachter die Änderung in der Liste nicht, wenn ich einen Filter hinzufüge?

private void CompanyBindingSource_ListChanged(object sender, ListChangedEventArgs e) 
{ 
    MessageBox.Show("List changed!"); 
} 

Und schließlich die Add Motor-Taste:

private void button1_Click_1(object sender, EventArgs e) 
{ 
    if (!string.IsNullOrWhiteSpace(textBox1.Text)) 
    { 
     Motor m = new Motor(); 
     m.company = textBox1.Text; 
     _context.Motors.Add(m); 
     _context.SaveChanges(); 
     MessageBox.Show($"New motor, id: {m.motorID}"); 
    } 
} 

Mit der ersten Implementierung funktioniert die comboBox Update und zeigt jedes Unternehmen (für jeden Motor):

Push Button hinzufügen -> "Liste geändert!" Pop-up -> "Neuer Motor: id" Pop-up

Mit dem Filter:

Push Button hinzufügen -> "Neuen Motor: id" Pop-up

In der Tat wird der Motor ergänzt, aber nicht zeigen bis zum Neustart des Programms.

Jede Idee wird sehr geschätzt. Ich hoffe, ich habe mich gut erklärt.

Antwort

2

die folgende Zeile in dem zweiten Beispiel bricht die Bindung:

_context.Motors.Local.ToBindingList().Select(x => x.company).Distinct(); 

Der Grund ist, dass das Ergebnis der .Select(x => x.company).Distinct() ist keine BindingList<Motor>, sondern ein einfacher IEnumerable<string>

Mit dem folgenden Ersatz:

var _companies = _context.Motors.Select(x => x.company).Distinct().ToList(); 

this.companyBindingSource.DataSource = _companies; 
+0

Vielen Dank für Ihre Antwort DmitryG. Ich denke, du meinst _context.Motors.Select (x => x.company) .Distinct(). Load(). Es funktioniert jedoch nicht. Die ComboBox ist nicht mit Daten gefüllt. Wenn ich _context.Motors.Where (m => m.company == "UPV") schreibe. Load(); dann bekomme ich eine ComboBox mit drei "UPV" (weil ich 3 UPV-Motoren habe). Wenn ich ein neues mit UPV als Firma hinzufüge, fügt es der Liste hinzu, also habe ich 4. Das Problem ist, dass, wenn ich irgendeine andere Firma hatte, es auch hinzufügt, so dass es Firma == "UPV" nicht mehr filtert . Ich denke, dass der Filter im Load() -Satz nur in der ersten Ladung gilt, oder? – lyurealm

+0

>> Ich denke, dass der Filter im Load() -Satz nur in der ersten Ladung gilt, oder? Ja, du hast Recht. Sie sollten die Datenquelle nach einigen Änderungen aus dem Kontext neu laden. – DmitryG

+0

Hätten Sie etwas dagegen, dies zu erklären? Meinst du, dass ich _context.Motors.Select (x => x.company) .Distinct() .Load() vom AddButton auch aufrufen soll? – lyurealm

0

Diese Linie

this.companyBindingSource.DataSource = _context.Motors.Local.ToBindingList().Select(x => x.company).Distinct(); 

Rückgabe IEnumerable<T>. In Ihrem Fall sollten Sie es Liste sein, so fügen .ToList();

this.companyBindingSource.DataSource = _context.Motors.Local.ToBindingList().Select(x => x.company).Distinct().ToList(); 
+0

Zunächst einmal, danke für Ihre Antwort. Es scheint jedoch nicht einmal mit .ToList() zu funktionieren. – lyurealm

Verwandte Themen