Refreshing Read-Only (Chained) Property in MVVM
I'm thinking this should be easy, but I can't seem to figure this out.
Take these properties from an 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.FullNa开发者_运维技巧me : this.Initials); }
}
public string FullName
{
get { return mFirstName + " " + mLastName; }
}
public string Initials
{
get { return mFirstName.Substring(0, 1) + "." + mLastName.Substring(0, 1) + "."; }
}
}
The guts of such a [insert your adjective here] View using this ViewModel might look like:
<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 am seeing is when the ToggleNameCommand is fired. The ShowFullName property is properly updated by the command, but the Name binding is never updated in the View.
What am I missing? How can I force the binding to update? Do I need to implement the Name properties as DependencyProperties (and therefore derive from DependencyObject)? Seems a little heavyweight to me, and I'm hoping for a simpler solution.
Thanks, wTs
You need to explicitly notify that Name has changed, otherwise the Binding system has no way to know. You can either call NotifyPropertyChanged for the property "Name" when you set ShowFullName or you can modify the Name property to have a private setter and update it explicitly (calling NotifyPropertyChanged as part of the Name property setter), rather than having the getter evaluate a function.
Note that you'll need to do the same thing for the other two read-only properties. Making them Dependency properties would also work, but I prefer to avoid these unless I'm implementing a control which will be a target for Binding. They're heavy-weight if you only need property change notification.
精彩评论