Zwei-Wege-binding-problem mit WPF ComboBox mit MVVM
Ich habe eine Activity
Objekt mit vielen Eigenschaften. Einer von Ihnen ist wie folgt:
public ActivityStatus Status
{
get { return status; }
set { status = value; NotifyPropertyChanged("Status"); }
}
Den ActivityStatus
Klasse hat nur zwei Eigenschaften:
public Guid Guid
{
get { return guid; }
set { guid = value; NotifyPropertyChanged("Guid"); }
}
public string Name
{
get { return name; }
set { name = value; NotifyPropertyChanged("Name"); }
}
und die Equals
Methoden:
public override bool Equals(object otherObject)
{
if (!(otherObject is ActivityStatus)) return false;
return Equals(otherObject as ActivityStatus);
}
public bool Equals(ActivityStatus otherStatus)
{
if (!(otherStatus is ActivityStatus) || otherStatus == null) return false;
return Guid == otherStatus.Guid && Name == otherStatus.Name;
}
Ich habe eine ActivityViewModel
Klasse DataContext
einer ActivityView
Klasse. Die ActivityViewModel
hat eine Activity
Eigenschaft des Typs Activity
und unter anderem ein ActivityStatuses
Eigenschaft des Typs ObservableCollection<ActivityStatus>
. In der ActivityView
ich habe eine ComboBox
wie folgt deklariert:
<ComboBox ItemsSource="{Binding ActivityStatuses}"
SelectedItem="{Binding Activity.Status, Mode=TwoWay}"
DisplayMemberPath="Name" />
Dies ermöglicht es mir, wählen Sie eine ActivityStatus
von der ComboBox
und diese richtig aktualisiert Status
Eigenschaft des Activity
im Activity
Eigenschaft im viewmodel. Das problem ist mit dem zwei-Wege-Bindung... beim laden eines neuen Activity
, die ComboBox.SelectedItem
nicht aktualisiert und zeigen die Activity.Status
- Eigenschaft-Wert.
Mit dieser Erklärung der ComboBox
, die SelectedItem
ist gebunden an die ActivityStatus
Objekt in der Activity
- und dies ist ein anderes Objekt mit gleichen Werten in den viewmodel - ActivityStatuses
Eigenschaft. Also das WPF-Framework nicht denken, dass die Gegenstände sind die gleichen, und nicht, wählen Sie das Element in der ComboBox
.
Wenn ich weisen Sie die Elemente aus der Sammlung mit dem gleichen Werte für die Activity.Status
Eigenschaft nach jedem laden eines Activity
, dann die ComboBox
findet eine übereinstimmung in seiner ItemsSource
Sammlung und richtig setzt die SelectedItem
Anzeige-Eigenschaft den Wert. Ich weiß nicht wirklich wollen, dies zu tun, aber da habe ich viele andere, die ähnliche Eigenschaften in th Activity
Klasse und ich werde wiederholen Sie diesen code, wo ich es will, um zwei-Weg-binden ComboBox
es.
So, ich habe auch versucht, die Bindung an ActivityStatus.Guid
- Eigenschaft wie folgt:
<ComboBox ItemsSource="{Binding ActivityStatuses}"
SelectedValue="{Binding Activity.Status.Guid, Mode=TwoWay}"
SelectedValuePath="Guid"
DisplayMemberPath="Name" />
Diese korrekt markiert das Objekt mit der gleichen Guid
wie die in der Activity.Status
Eigenschaft aus der ComboBox.ItemsSource
Sammlung beim laden verschiedener Activity
Objekte. Das problem mit dieser Methode ist, dass die SelectedValue
ist gebunden an die ActivityStatus.Guid
Eigenschaft in der ActivityStatus
Objekt und und so bei der änderung von Werten in der Benutzeroberfläche werden nur die 'Guid' - Eigenschaft des ActivityStatus
Objekt aktualisieren würden, verlassen Sie den Namen unverändert. Das Objekt in der Activity.Status
Eigenschaft nicht ändern, außer für den Wert seiner Guid
Eigenschaft.
Wie Sie sehen können, ich habe auch versucht, die Umsetzung der Equals
Methode, wie ich davon ausgegangen, dass die ComboBox
würde dieses vergleichen der Objekte, aber es machte keinen Unterschied. So endlich, ich bin an einem Verlust, und begierig, Sie zu finden, die eine einfache, saubere Weg, um dieses problem zu beheben... hoffentlich gibt es eine einfache Eigenschaft, die ich verpasst habe auf der ComboBox
.
Ich möchte einfach in der Lage sein, um wählen Sie ein Element in der ComboBox
und haben die Activity.Status
Objekt entsprechend ändern, und ändern Sie den Wert des Activity.Status
Eigenschaft von code und haben die ComboBox.SelectedItem
auch entsprechend aktualisieren. Ich wäre dankbar für jeden Rat.
UPDATE >>>
Nach dem Lesen Wird die Antwort, ich habe versucht, seinen code in eine neue Lösung zu und sah, dass es funktionierte wie erwartet. Ich habe dann untersucht, seinen code thorouhly und sah, dass es war das gleiche wie meins, so lief meine eigene Lösung wieder (zum ersten mal seit diesem post). Zu meiner völligen überraschung, es funktioniert wie erwartet, ohne dass ich änderungen am Programm-code!
Dies verwunderte mich sehr und ich habe einige Zeit damit verbracht, um herauszufinden, was passiert ist. Es stellt sich heraus, dass das problem war/ist Visual Studio 2010! Ich hatte Hinzugefügt, die Equals
Methoden, um meine Daten-Typen, wie die Letzte Etappe. Für einige Grund, warum Visual Studio nicht bauen die Datentypen Projekt, wenn die Anwendung ausgeführt wird.
So muss der Antrag wurde mit einer älteren dll-Datei und meine änderungen wurden nicht verwendet... ich habe Frage mich, warum meine Pause Punkte auf der Equals
Methoden wurden nie Treffer. Dies führte zu meiner Annahme, dass die Umsetzung der Equals
methids nicht helfen. Visual Studio hat das gleiche Verhalten heute und das ist, wie ich herausfand, was geschehen war.
Habe ich überprüft, das Projekt zu bauen, um in meiner Lösung, aber das listet die Datentypen Projekt an der richtigen Stelle in der Bestellung. Wenn Sie die Anwendung ausführen, obwohl Sie das Ausgabefenster in Visual Studio zeigt die Projekt-dlls geladen werden in einer anderen Reihenfolge. Ich bin mir nicht sicher, warum Sie die Anwendung ausführen funktioniert nicht mehr, eine komplette build, aber zumindest weiß ich, dass ich zu bauen, das Projekt nach änderungen in der it, bevor die Anwendung ausgeführt wird.
LETZTEN UPDATE - >>>
Ich habe gerade herausgefunden, warum mein Datentypen Projekt nicht zu bauen... ich sah Sie in der Configuration Manager-Fenster und sah, dass irgendwie die Plattform wurde nicht für das Projekt und die Build-checkbox geworden war deaktiviert! Ich habe keine Ahnung, wie das passiert ist, aber bin sehr erleichtert, dass ich endlich auf den Grund des Problems.
Danke @Wird, aber ich habe gerade herausgefunden, warum mein Datentypen Projekt nicht zu bauen... ich sah Sie in der Configuration Manager-Fenster und sah, dass irgendwie die Plattform wurde nicht für das Projekt und die Build-checkbox geworden war deaktiviert! Ich habe keine Ahnung, wie das passiert ist, aber bin sehr erleichtert, dass ich endlich auf den Grund des Problems.
InformationsquelleAutor Sheridan | 2011-05-26
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich habe schlechte Nachrichten für Sie. Es sollte funktionieren. Es ist ein Fehler/eine unerwartete Nebenwirkung woanders, das ist die Ursache Ihres Problems.
Warf ich zusammen eine schnelle Projekt, zu tun, was Sie zu tun versuchen. Wie sehen es hier geht.
Erstellen Sie ein neues WPF-Projekt namens NestedProperties. Fügen Sie eine neue Klasse an die Wurzel und fügen Sie den folgenden code (habe ich entfernt viele Sachen, so ist es ein bisschen hässlich):
Nun öffnen Hauptfenster und fügen Sie diese in:
Wenn Sie dies ausführen, werden Sie feststellen, Sie haben vier Aktivitäten und vier Zustände. Wenn Sie flip durch die Aktivitäten combo, Sie werden sehen, jeder Status ist gekennzeichnet Aktivität, was bedeutet, es ist die Instanz gegeben, um die Aktivität in den Konstruktor der ViewModel. Sie werden auch sehen, dass der Status der combobox ändert, wenn die Aktivität Veränderungen, was bedeutet, dass die
Equals
Methode funktioniert.Als Nächstes ändern Sie den status für jede Aktivität. Sie werden sehen, die Art von ändert sich der status auf Sammlung, was bedeutet, dass diese Instanz erstellt wurde, und Hinzugefügt, um den Status collection im Konstruktor.
Also, warum ist diese funktioniert, aber dein code nicht? Ich bin mir nicht sicher. Dein problem liegt an anderer Stelle in Ihrem code.
InformationsquelleAutor Will
Mann ich weiß nicht, ob ich folgte Ihrer Frage genau, aber wenn du sagst
Sind Sie mit dem hinzufügen, dass die neuen
Activity
zu IhremActivityStatuses
Sammlung? Denn wenn Sie nicht dann ich bin mir ziemlich sicher, dass die Bindung nicht arbeiten, weil Sie die SelectedItem-muss in der ItemsSource.Nur ein Gedanke.
InformationsquelleAutor Jose