刷新 MVVM 中的只读(链接)属性
我认为这应该很容易,但我似乎无法弄清楚。
从示例 ViewModel 中获取这些属性(ObservableViewModel 实现 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) + "."; }
}
}
使用此 ViewModel 的 [在此处插入形容词] 视图的内部可能如下所示:
<TextBlock x:Name="txtName"
Grid.Row="0"
Text="{Binding Name}" />
<Button x:Name="btnToggleName"
Command="{Binding ToggleNameCommand}"
Content="Toggle Name"
Grid.Row="1" />
我看到的问题是触发 ToggleNameCommand 时。该命令已正确更新 ShowFullName 属性,但视图中的名称绑定永远不会更新。
我缺少什么?如何强制更新绑定?我是否需要将 Name 属性实现为 DependencyProperties(因此从 DependencyObject 派生)?对我来说似乎有点重量级,我希望有一个更简单的解决方案。
谢谢, 工作时间
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.FullName : 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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您需要显式通知Name已更改,否则Binding系统无法知道。您可以在设置 ShowFullName 时为属性“Name”调用 NotifyPropertyChanged,也可以修改 Name 属性以拥有私有 setter 并显式更新它(调用 NotifyPropertyChanged 作为 Name 属性 setter 的一部分),而不是让 getter 评估功能。
请注意,您需要对其他两个只读属性执行相同的操作。使它们成为依赖属性也可以,但我更愿意避免这些属性,除非我要实现一个将成为绑定目标的控件。如果您只需要属性更改通知,那么它们是重量级的。
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.