La liaison bidirectionnelle problème avec WPF zone de liste déroulante à l'aide de MVVM

J'ai un Activity objet avec de nombreuses propriétés. L'un d'eux est comme suit:

public ActivityStatus Status
{
    get { return status; }
    set { status = value; NotifyPropertyChanged("Status"); }
}

La ActivityStatus de classe dispose de deux propriétés:

public Guid Guid
{
    get { return guid; }
    set { guid = value; NotifyPropertyChanged("Guid"); }
}
public string Name
{
    get { return name; }
    set { name = value; NotifyPropertyChanged("Name"); }
}

et la Equals méthodes:

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;
}

J'ai un ActivityViewModel classe que le DataContext d'un ActivityView classe. Le ActivityViewModel a un Activity propriété de type Activity et, entre autres, un ActivityStatuses propriété de type ObservableCollection<ActivityStatus>. Dans le ActivityView j'ai un ComboBox déclarée comme suit:

<ComboBox ItemsSource="{Binding ActivityStatuses}" 
          SelectedItem="{Binding Activity.Status, Mode=TwoWay}"
          DisplayMemberPath="Name" />

Cela me permet de sélectionner un ActivityStatus de la ComboBox et ce met correctement à jour la Status propriété de la Activity dans le Activity propriété du viewmodel. Le problème est avec la liaison bidirectionnelle... lors du chargement d'un nouveau Activity, le ComboBox.SelectedItem n'est pas à jour pour afficher la Activity.Status la valeur de la propriété.

À l'aide de cette déclaration de la ComboBox, le SelectedItem est lié à la ActivityStatus objet dans le Activity et c'est un autre objet de l'un avec les mêmes valeurs dans le viewmodel ActivityStatuses de la propriété. Par conséquent, le Framework WPF ne pense pas que les articles sont de la même et ne pas sélectionner l'élément dans le ComboBox.

Si je affecter l'élément de la collection avec les mêmes valeurs pour les Activity.Status de la propriété après le chargement de chaque Activity, puis le ComboBox trouve une correspondance dans son ItemsSource collecte et définit correctement le SelectedItem propriété de l'affichage de la valeur. Je n'ai pas vraiment envie de faire ce que parce que j'ai beaucoup d'autres propriétés similaires dans th Activity classe et je vais répéter ce code n'importe où, je veux les deux sens de se lier à ComboBoxes.

Donc, j'ai aussi essayé de liaison à ActivityStatus.Guid propriété comme suit:

<ComboBox ItemsSource="{Binding ActivityStatuses}" 
          SelectedValue="{Binding Activity.Status.Guid, Mode=TwoWay}"
          SelectedValuePath="Guid" 
          DisplayMemberPath="Name" />

Correctement sélectionné l'objet avec le même Guid que celui de la Activity.Status bien de la ComboBox.ItemsSource collection lors du chargement de différents Activity objets. Le problème avec cette méthode est que la SelectedValue est lié à la ActivityStatus.Guid propriété dans le ActivityStatus objet et, ainsi, lorsque l'évolution des valeurs dans l'INTERFACE utilisateur, seul le "Guid" propriété de la ActivityStatus objet de mise à jour, en laissant le nom inchangé. L'objet dans la Activity.Status propriété ne change pas, sauf pour la valeur de son Guid propriété.

Comme vous pouvez le voir, j'ai aussi essayé la mise en œuvre de la Equals méthode que j'ai supposé que le ComboBox aurait à utiliser pour comparer les objets, mais il n'a fait aucune différence. Donc finalement, je suis à une perte et désireux de trouver un simple moyen propre à résoudre ce problème... je l'espère, il y a une propriété simple que j'ai raté sur le ComboBox.

Je veux simplement être en mesure de sélectionner un élément dans la ComboBox et ont la Activity.Status objet de modifier en conséquence et de modifier la valeur de la Activity.Status propriété de code et le ComboBox.SelectedItem également mettre à jour en conséquence. Je serais reconnaissant de tout conseil.

Mise à JOUR >>>

Après lecture de la réponse, j'ai essayé le code de l'échantillon dans une solution nouvelle et vu qu'il a fonctionné comme prévu. J'ai ensuite examiné son code thorouhly et vu que c'était le même que le mien, donc couru mon propre solution de nouveau (pour la première fois depuis ce post). À ma grande surprise, il a fonctionné comme prévu, sans me changer tout le code!

Cela me laisse perplexe grandement et j'ai passé un peu de temps pour savoir ce qui s'est passé. Il s'avère que le problème a été/est Visual Studio 2010! J'avais ajouté le Equals méthodes pour mon des types de données comme la dernière étape. Pour une raison que Visual Studio n'a pas construit les types de données du projet lors de l'exécution de l'application.

De sorte que la demande doit avoir été à l'aide d'un ancien fichier dll et mes modifications n'ont pas été utilisés... je ne me demande pourquoi mes points de rupture sur le Equals méthodes n'ont jamais été touchés. Cela a conduit à mon hypothèse que la mise en œuvre de la Equals methids n'a pas aidé. Visual Studio a le même comportement qu'aujourd'hui, et c'est ainsi que j'ai découvert ce qui s'était passé.

J'ai vérifié le projet de construction de l'ordre dans ma solution, mais qui répertorie les types de données de projet dans le bon endroit dans l'ordre. Lors de l'exécution de l'application bien que, la fenêtre de Sortie de Visual Studio affiche le projet dll chargées dans un ordre différent. Je ne suis pas sûr pourquoi l'exécution de l'application n'est plus une construction complète, mais au moins je sais que je dois construire ce projet après avoir fait des modifications avant l'exécution de l'application.

Dernière mise à JOUR >>>

Je viens de trouver pourquoi mon des types de données de projet n'a pas été... j'ai regardé dans le Gestionnaire de Configuration de la fenêtre et a vu que d'une certaine façon, la Plateforme était incorrecte de ce projet et la case à cocher générer était devenu décochée! Je n'ai aucune idée de comment c'est arrivé, mais je suis très soulagé que j'ai enfin réussi à le fond du problème.

Ce que vous avez ici est le classique "Projet de Référence/Référence de Fichier" problème. Vous devez supprimer toutes les références à d'autres projets dans votre solution et ajouter de nouveau comme références. Un fichier de référence n'est pas mis à jour automatiquement sur construire ou lorsque vous modifiez le type de version (par exemple, debug/release). Jamais naviguez vers le répertoire /bin pour ajouter une référence! Pour plus d'info à propos de Références cochez cette article msdn
Merci @Will, mais je viens de trouver pourquoi mon des types de données de projet n'a pas été... j'ai regardé dans le Gestionnaire de Configuration de la fenêtre et a vu que d'une certaine façon, la Plateforme était incorrecte de ce projet et la case à cocher générer était devenu décochée! Je n'ai aucune idée de comment c'est arrivé, mais je suis très soulagé que j'ai enfin réussi à le fond du problème.

OriginalL'auteur Sheridan | 2011-05-26