2

让我们假设属性 Name 在这样的视图中绑定到 TextBox。

private string name
public string Name
{
   get {return name;}
   set {
       name=value;
       OnPropertyChanged("Name");
   }
}

看法

<TextBox Text="{Binding Name, Mode=TwoWay"/>

当我们更新文本框中的文本时,它会调用 Name 属性中的 setter,进而引发 PropertyChanged 假设再次更新 UI。我很好奇 WPF 如何避免更新和引发事件的递归。是通过考虑该事件的发送者来完成的吗?

4

3 回答 3

3

A standard implementation of a property should look like this:

private string name;

public string Name
{
   get { return name; }

   set
   {
       if( name != value )
       {
           name = value;
           OnPropertyChanged("Name");
       }
   }
}

Note the additional if to make sure the event is only raised if the value of the property actually changed.

于 2013-04-17T04:37:13.563 回答
0

可以从这里的答案帮助你。

如果您将属性从 ui 设置为 viewmodel,它会像这样。

  • 设置器调用开始
  • 值集
  • INotifyPropertyChanged 已启动
  • INotifyPropertyChanged 完成
  • 二传手完成
  • getter 调用并完成
  • IDataErrorInfo 调用并完成

但是如果您在视图模型中设置属性,它会像这样

  • 设置器调用开始
  • 值集
  • INotifyPropertyChanged 已启动
  • getter 调用并完成
  • IDataErrorInfo 调用并完成
  • INotifyPropertyChanged 完成
  • 二传手完成

将属性从 UI 更改为 ViewModel 可能会导致死锁情况,这种情况可能会在两种情况下遇到结束较少的递归调用。为了阻止这种情况发生,当 WPF 对模型进行更改时,它会继续通过 INotifyPropertyChanged 跟踪更改,但此更改将在调度程序队列中排队,并在其当前更新完成后执行。

由于 viewmodel 中的更改不是由 WPF 发起的,因此 WPF 不会对操作进行排队,它会立即执行更改。

于 2013-04-17T06:01:46.483 回答
0

据我了解,没有递归。

1) TextBox 使用 viewmodel 属性更新值。

2) Viewmodel 引发更新,让 UI 知道发生了一些变化

3) TextBox 现在更新自己以匹配 viewmodel 值。

于 2013-04-17T04:23:02.323 回答