【问题标题】:Refreshing Read-Only (Chained) Property in MVVM刷新 MVVM 中的只读(链式)属性
【发布时间】:2011-02-19 03:15:16
【问题描述】:

我认为这应该很容易,但我似乎无法弄清楚。

从示例 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 绑定永远不会更新。

我错过了什么?如何强制绑定更新?我是否需要将 Name 属性实现为 DependencyProperties(因此从 DependencyObject 派生)?对我来说似乎有点重量级,我希望有一个更简单的解决方案。

谢谢, wTs

【问题讨论】:

    标签: wpf mvvm properties readonly


    【解决方案1】:

    需要明确通知Name发生了变化,否则Binding系统无从得知。您可以在设置 ShowFullName 时为属性“Name”调用 NotifyPropertyChanged,或者您可以修改 Name 属性以具有私有设置器并显式更新它(调用 NotifyPropertyChanged 作为 Name 属性设置器的一部分),而不是让 getter 评估函数。


    请注意,您需要对其他两个只读属性执行相同的操作。使它们成为依赖属性也可以,但我更愿意避免这些,除非我正在实现一个将成为绑定目标的控件。如果您只需要属性更改通知,它们就是重量级的。

    【讨论】:

    • 噢!当然! +1 为你,-1 为我。 :) 至少我对 DP 实现以及避免它的原因是正确的。
    • 我以前遇到过这个问题,因为当您有多个属性是相同基础数据的不同视图时,这是一个常见问题。我倾向于跟随get;私人套装;这些天来,将更新封装在一个 RefreshX 方法中,只要底层属性之一发生更改,就会调用该方法。这对我来说更干净,因为我使用 PostSharp 来实现 INotifyPropertyChanged,这样我就不需要创建新的显式 OnPropertyChanged 调用。
    猜你喜欢
    • 2023-03-09
    • 2010-12-17
    • 2019-01-18
    • 1970-01-01
    • 2011-04-04
    • 2013-01-14
    • 2010-11-22
    • 1970-01-01
    相关资源
    最近更新 更多