PropertyChanged?.Invoke(...) 调用 在单步执行 Set 语句时再次调用 setter
我有一个实现 INotifyPropertyChanged 的简单基类。该代码有效。但是,当我单步执行 Set 语句时,当 Set 语句调用 SetProperty() 时,我注意到 PropertyChanged?.Invoke(...) 调用再次调用 setter。
因此,子类中的 setter 代码看起来像:
private string someProperty ;
public string SomeProperty { get => someProperty ;
set {
// Do some tests on value to make sure it's valid
SetProperty(ref someProperty, value);
// Now do some other stuff once that is set
}
当我单步执行它时,调用堆栈显示:
- SomeProperty.Set( valuetype value); ????怎么又来了???? --- 5
- 外部代码 --- 4
- OnPropertyChanged(string propertyName ) --- 3
- SetProperty(field, value) --- 2
- SomeProperty.Set( valuetype value) ---- 初始设置执行
代码片段:
public abstract class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
Dev.Tools.Assert(propertyName != null, "propertyName can't be null.... ");
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
// This is used to support change tracking. But
// the problem happens even when TrackChangedFields is false.
// The EqualityComparer prevents this from being recursive.
public virtual bool SetProperty<T>(ref T field, T newValue, [CallerMemberName] string propertyName = null)
{
if (!EqualityComparer<T>.Default.Equals(field, newValue))
{
field = newValue;
OnPropertyChanged(propertyName);
if (TrackChangedFields && !IgnoreFieldList.Contains(propertyName))
{
ChangedFieldList.Add(new ChangedRecordDetail(propertyName, field, newValue, ViewModelName));
}
return true;
}
return false;
}
知道为什么PropertyChanged?.Invoke() 调用导致集合再次触发?
同样,这段代码运行良好。我只是不明白为什么会发生第二次对 setter 的调用,也不明白该怎么做才能只调用一次 setter。
I have a simple base class that implements INotifyPropertyChanged. The code works. But when I was stepping through a Set statement, when the Set statement called SetProperty(), I noticed that the PropertyChanged?.Invoke(...) call was calling the setter again.
So the setter code in the subclass looks something like:
private string someProperty ;
public string SomeProperty { get => someProperty ;
set {
// Do some tests on value to make sure it's valid
SetProperty(ref someProperty, value);
// Now do some other stuff once that is set
}
When I step through it the call stack shows:
- SomeProperty.Set( valuetype value); ????? Why again???? --- 5
- External Code --- 4
- OnPropertyChanged(string propertyName ) --- 3
- SetProperty(field, value) --- 2
- SomeProperty.Set( valuetype value) ---- Initial set execution
Code snippet:
public abstract class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
Dev.Tools.Assert(propertyName != null, "propertyName can't be null.... ");
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
// This is used to support change tracking. But
// the problem happens even when TrackChangedFields is false.
// The EqualityComparer prevents this from being recursive.
public virtual bool SetProperty<T>(ref T field, T newValue, [CallerMemberName] string propertyName = null)
{
if (!EqualityComparer<T>.Default.Equals(field, newValue))
{
field = newValue;
OnPropertyChanged(propertyName);
if (TrackChangedFields && !IgnoreFieldList.Contains(propertyName))
{
ChangedFieldList.Add(new ChangedRecordDetail(propertyName, field, newValue, ViewModelName));
}
return true;
}
return false;
}
Any idea why the PropertyChanged?.Invoke() call is causing the set to fire again?
Again, this code works fine. I just don't understand why the 2nd call to the setter is happening nor what to do to only have the setter called once.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论