Updating Read-Only (Chained) Property in MVVM

I think this should be easy, but I cannot figure it out.

Take these properties from example ViewModel (ObservableViewModel implements 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) + "."; }
    }
}

      

Feelings like this [insert your adjective here] View using this ViewModel might look like this:

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

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

      

The problem I see is when the ToggleNameCommand is fired. The ShowFullName property is updated by the command as expected, but the name binding is never updated in the view.

What am I missing? How do I force the binding to update? Do I need to implement Name properties as DependencyProperties (and hence get from DependencyObject)? Seems a bit heavyweight to me and I'm hoping for a simpler solution.

Thanks, WTS

+2


a source to share


1 answer


You need to explicitly notify the name change, otherwise the binding system won't be able to find out. You can either call NotifyPropertyChanged on the "Name" property when you set ShowFullName, or you can change the Name property to have a private setter and update it explicitly (by calling NotifyPropertyChanged as part of the Name property defer), instead of evaluating the getter function.




Note that you will need to do the same for the other two read-only properties. Creating dependency properties will work as well, but I prefer to avoid them unless I implement the control that will be the target of the binding. They are heavy when you need property change notification.

+1


a source







All Articles