在MVVM中刷新只读(链接)属性。

时间:2022-09-12 08:47:45

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):

以一个示例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) + "."; }
    }
}

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.

我看到的问题是,当ToggleNameCommand被解雇时。ShowFullName属性是由命令正确更新的,但是名称绑定不会在视图中更新。

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.

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

Thanks, wTs

谢谢你,但是

1 个解决方案

#1


1  

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.

您需要显式地通知名称已更改,否则绑定系统无法知道。您可以在设置ShowFullName时为属性“Name”调用NotifyPropertyChanged,也可以将Name属性修改为具有私有setter并显式更新(调用NotifyPropertyChanged作为Name属性setter的一部分),而不是让getter对函数求值。


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.

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

#1


1  

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.

您需要显式地通知名称已更改,否则绑定系统无法知道。您可以在设置ShowFullName时为属性“Name”调用NotifyPropertyChanged,也可以将Name属性修改为具有私有setter并显式更新(调用NotifyPropertyChanged作为Name属性setter的一部分),而不是让getter对函数求值。


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.

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