2010-05-13 3 views
2

Je pense que cela devrait être facile, mais je n'arrive pas à le comprendre.Actualisation de la propriété en lecture seule (chaînée) dans MVVM

Prenez ces propriétés d'un exemple ViewModel (ObservableViewModel implémente INotifyPropertyChanged):

class NameViewModel : ObservableViewModel 
{ 
    Boolean mShowFullName = false; 
    string mFirstName = "Wonko"; 
    string mLastName = "DeSane"; 
    private readonly DelegateCommand mToggleName; 

    public NameViewModel() 
    { 
     mToggleName = new DelegateCommand(() => ShowFullName = !mShowFullName); 
    } 

    public ICommand ToggleNameCommand 
    { 
     get { return mToggleName; } 
    } 

    public Boolean ShowFullName 
    { 
     get { return mShowFullName; } 
     set { SetPropertyValue("ShowFullName", ref mShowFullName, value); } 
    } 

    public string Name 
    { 
     get { return (mShowFullName ? this.FullName : this.Initials); } 
    } 

    public string FullName 
    { 
     get { return mFirstName + " " + mLastName; } 
    } 

    public string Initials 
    { 
     get { return mFirstName.Substring(0, 1) + "." + mLastName.Substring(0, 1) + "."; } 
    } 
} 

Les entrailles d'un tel [insérer votre adjectif ici] Voir en utilisant ce ViewModel pourrait ressembler à:

<TextBlock x:Name="txtName" 
      Grid.Row="0" 
      Text="{Binding Name}" /> 

<Button x:Name="btnToggleName" 
     Command="{Binding ToggleNameCommand}" 
     Content="Toggle Name" 
     Grid.Row="1" /> 

Le problème que je vois est lorsque le ToggleNameCommand est déclenché. La propriété ShowFullName est correctement mise à jour par la commande, mais la liaison de nom n'est jamais mise à jour dans la vue.

Qu'est-ce qui me manque? Comment puis-je forcer la liaison à mettre à jour? Ai-je besoin d'implémenter les propriétés Name en tant que DependencyProperties (et donc dériver de DependencyObject)? Ça me semble un peu lourd et j'espère une solution plus simple.

Merci, WTS

Répondre

1

Vous devez informer explicitement ce nom a changé, sinon le système de fixation n'a aucun moyen de savoir. Vous pouvez appeler NotifyPropertyChanged pour la propriété "Name" lorsque vous définissez ShowFullName ou vous pouvez modifier la propriété Name pour avoir un setter privé et le mettre à jour explicitement (en appelant NotifyPropertyChanged dans le setter de propriété Name), plutôt que d'avoir un getter fonction.


Notez que vous devrez faire la même chose pour les deux autres propriétés en lecture seule. Les rendre dépendantes fonctionnerait également, mais je préfère les éviter sauf si j'implémente un contrôle qui sera une cible pour la liaison. Ils sont lourds si vous avez seulement besoin de notification de changement de propriété.

+0

Doh! Bien sûr! +1 pour vous, -1 pour moi. :) Au moins j'avais raison sur l'implémentation de DP, et la raison de l'éviter. –

+1

J'ai déjà rencontré ce problème, car il s'agit d'un problème courant lorsque vous avez plusieurs propriétés qui sont des vues différentes des mêmes données sous-jacentes. J'ai tendance à suivre le get; ensemble privé; approche ces jours-ci et encapsule la mise à jour dans une méthode RefreshX appelée chaque fois que l'une des propriétés sous-jacentes est modifiée. C'est plus propre pour moi, puisque j'utilise PostSharp pour implémenter INotifyPropertyChanged et de cette façon je n'ai pas besoin de créer un nouvel appel OnPropertyChanged explicite. –

Questions connexes