2013-08-14 5 views
7

Ich habe Google und hier nach Antworten gesucht, mein Problem ist etwas mit der folgenden Frage verwandt, aber anders genug, um eine neue Frage zu rechtfertigen.WPF: Combobox verlieren ausgewählten Index nach gebundenen ItemSource Sammlung Änderungen

Combo-box loses selection after collection changes

Im Grunde habe ich eine WPF-Combobox, die zu einer ObservableCollection-Klasse gebunden ist. Diese Klasse verfügt über zusätzliche Funktionen, um Benachrichtigungen über Sammeländerungen zu verzögern, wenn ich eine Reihe von Änderungen vornehmen muss, z. B. Löschen und Neubefüllen, um einen neuen Snapshot der Datenbank zu erhalten.

Meine Combobox-Bindung hat DisplayMemberPath und SelectedValuePath festgelegt. Der SelectedValuePath wird in eine Integer-Eigenschaft aufgelöst.

Das Problem ist das gleiche wie die referenzierte Frage, wenn ich die Werte in der gebundenen Sammlung aktualisieren, verliert die gebundene ComboBox ihre Auswahl und wird leer (SelectedIndex = -1).

Ich kann bestätigen, dass das CollectionChanged-Ereignis nicht ausgelöst wird, bis die Sammlung erneut ausgefüllt wurde und die Elemente wieder darin enthalten sind.

Mehr rätselhaft ist, wenn ich folgendes tun:

 using (_collection.DelayNotifications()) 
     { 
      var items = _collection.ToArray(); 
      _collection.Clear(); 
      _collection.AddRange(items); 
     } 

Die Combobox hat nicht seinen gewählten Wert verlieren.

Das schlägt vor, dass es bricht, wenn die Elemente in der Sammlung durch neue Elemente aus der Datenbank ersetzt werden - ich könnte dies akzeptieren, wenn ich nicht die SelectedValuePath-Bindung verwendet habe, sondern weil ich bin und die Integer-Werte sind das gleiche, sicherlich was ich mache, sollte funktionieren?

ich Ideen habe .NET 3.5 SP1

Wer bin mit?

bearbeiten

Aus den Kommentaren unten und Antwort des Blam. Ich akzeptiere, dass das die Gründe sind warum es tut es. Aber es hilft mir nicht wirklich.

Ich binde die SelectedValue-Eigenschaft der Combobox an eine Integer-Eigenschaft in meinem Ansichtsmodell. Wenn ich das SelectedItem binden wollte, müsste ich an eine Eigenschaft dieses Objekttyps in meinem Ansichtsmodell binden - aber es ist die Integer-Eigenschaft, nach der ich eigentlich suche.

Im Moment habe ich das Problem "behoben" (lesen Sie kleinere Hack), indem Sie eine Eigenschaft geändert Ereignis für die Eigenschaft 'SelectedValue' gezwungen ist. Dies scheint zu bewirken, dass die Combobox ihre interne Liste nach einem Element überprüft, das mit dem definierten SelectedValuePath übereinstimmt.

Die WPF-Combobox muss "wissen", dass sie einen SelectedValuePath-Wert gesetzt hat, daher halte ich es nicht für einen großen Sprung, anzunehmen, dass sie ihre Item-Matching-Logik anpassen würde. Dies geht jedoch außerhalb des für SO vorgesehenen Anwendungsbereichs.

Ich realisiere, ich werde wahrscheinlich nur akzeptieren, das ist nur, wie WPF funktioniert, aber nach dem Kampf mit Daten gebundenen Comboboxen in WinForms für ein paar Jahre, ich hoffte irgendwie, ich hätte nicht mit WPF :) Obwohl WPF Comboboxes viel besser sind als WinForms.

+0

ValuePath spielt keine Rolle, wenn es sich um ein anderes Objekt handelt ... Sie können nicht erwarten, dass die Bindung beibehalten wird, da sie an bestimmte Insanzen (Objekte) gebunden ist. Sobald Sie diese entfernen, geht die Bindung verloren ... – UIlrvnd

+0

Die von DelayNotificatons() zurückgegebene Methode des Objekts löst das CollectionChange-Ereignis mit dem ListReset-Flag aus. Ich würde immer noch davon ausgehen, dass die Combobox durch ihre neue Liste nach einem Integerwert suchen würde, auf den sie passt ... Wenn das nicht passiert, was sind meine Optionen? – Marlon

+0

In Ihrem Codebeispiel verwenden Sie dieselben Instanzen, da Sie nur die Sammlungen manipulieren. es wird nicht aussehen, da die ganze Zahl eine andere Instanz ist, obwohl es ** den gleichen Wert hat ... Hoffe, es macht sence lol ... – UIlrvnd

Antwort

4

Diese Aussage ist falsch

Ich könnte dies akzeptieren, wenn ich nicht die SelectedValuePath Bindung, Verwendung wurde, sondern weil ich

bin

Sie sind nicht zu SelectedValuePath Bindung.
Sie sind an eine Objektgruppe gebunden.
SelectedValuePath dient nur zur Berichterstellung und hat nichts damit zu tun, Objekte auf Gleichheit zu prüfen. DisplayMemberPath dient nur zur Berichterstellung und hat nichts damit zu tun, Objekte auf Gleichheit zu prüfen.

Sie verwechseln SelectValuePath mit SelectedItem.
ComboBox verwendet SelectedValuePath nicht um festzustellen, ob zwei Objekte gleich sind.

Aus der Dokumentation von SelectedValuePath:

Ruft den Pfad, der verwendet wird, um die SelectedValue vom SelectedItem zu bekommen.

In der Probe, die Sie Sie verwirrt laden die gleichen Objekte zurück in.

ich SelectedValuePath zu übernehmen werde, ist eine Eigenschaft mit dem Namen ID

Wenn Sie klar und ein Objekt mit einer ID erstellen von 6 ist es nicht gleich dem gelöschten Objekt mit einer ID von 6.

Versuchen Sie dies. Erstelle zwei Objekte (o1 und o2) mit einer ID von 6 und vergleiche o1.Equals (o2).

Wenn zwei Objekte mit einer ID von 6 gleich sein sollen, müssen Sie GetHashCode und Equals überschreiben. In Equals gibt true zurück, wenn beide eine ID von 6 haben. Und Sie können ID als GetHashCode verwenden.

String ist ein Referenztyp, der Sie täuschen wird.
Zeichenfolge s1 = "Katze";
Zeichenfolge s2 = "Katze";
s1.Equals (s2) gibt True zurück, wenn String Equals überschrieben wird, um den Wert zu vergleichen.

+0

Ja, ich verstehe das, aber ich ' Wenn ich nicht an SelectedItem binde, bin ich an SelectedValue gebunden. Daher würde ich nicht erwarten, dass die ComboBox die Gleichheit auf dem SelectedItem vergleicht.Obwohl ich denke, es kann nicht wirklich bestimmen, an welche Eigenschaften jemand gebunden hat, und seine interne Logik an Suite anpassen. – Marlon

+0

Wie in meiner Antwort und Kommentar von Stefen no enthalten, sind Sie NICHT an SelectedValue gebunden. Sie sind an eine Sammlung von Objekten gebunden. DisplayMemberPath und SelectedValuePath dienen nur zur Berichterstattung. Das ist die Antwort. Warum lehnen Sie es ab, anstatt es anzuwenden? – Paparazzi

+0

Ich lehne es nicht ab - ich erkläre einfach nur, was ich tue. Ich glaube nicht, dass meine Logik so unbegründet war. Siehe meine Bearbeitung der Frage. Ich werde es ein paar Tage geben, aber wahrscheinlich werde ich deine Antwort akzeptieren. – Marlon

Verwandte Themen