更新属性和乒乓球事件
Updating Properties and ping-pong event
在将 Catel 用于 MVVM 框架的 WPF 应用程序中,我在视图模型中有 3 个不同的属性
public double? QtaDiv1 { get; set; }
public double? Exchange{ get; set; }
public double? QtaDiv2 { get; set; }
我已将 OnPropertyChanged 重写为
protected async override void OnPropertyChanged(AdvancedPropertyChangedEventArgs e)
{
if (e.PropertyName == "Data")
{
await GetValueDate(e);
}
else if (e.PropertyName == "QtaDiv1" || e.PropertyName == "Exchange")
{
ChangeQtaDiv2(QtaDiv1, Exchange);
}
if (e.PropertyName == "QtaDiv2")
{
ChangeQtaDiv1(QtaDiv2, Exchange);
}
else if (e.PropertyName == "SelectedCross")
{
await GetValueDate(e);
CheckForSplitVisibility();
}
base.OnPropertyChanged(e);
}
而我所做的是,如果 QtaDiv1 和 Exchange 具有我计算 QtaDiv2 的值
否则,如果用户(和 Exchange)更改了 QtaDiv2,我将更新 QtaDiv1。
这在我更新 QtaDiv2 之前工作正常,因为此时我在 QtaDiv1 上获得了一个 PropertyChanged,它调用了 QtaDiv2 上的更新等等...
我怎样才能打破这个咒语???我想设置一个包含更改值的字符串字段,但如果我这样做,我必须抑制 RaisePropertyChanged 通知(并且我必须转换为支持字段 属性),所以我不会得到验证他们
谢谢
您只需添加一个简单的 bool
变量来表示更改是否来自代码内部:
private bool isInternalChange = false;
如果是内部改动,可以忽略:
if (!isInternalChange)
{
if (e.PropertyName == "Data")
{
await GetValueDate(e);
}
else if (e.PropertyName == "QtaDiv1" || e.PropertyName == "Exchange")
{
isInternalChange = true;
ChangeQtaDiv2(QtaDiv1, Exchange);
isInternalChange = false;
}
if (e.PropertyName == "QtaDiv2")
{
isInternalChange = true;
ChangeQtaDiv1(QtaDiv2, Exchange);
isInternalChange = false;
}
else if (e.PropertyName == "SelectedCross")
{
await GetValueDate(e);
CheckForSplitVisibility();
}
base.OnPropertyChanged(e);
}
@Sheridan 的回答是正确的。正如@Boris B. 指出的那样,最好尝试一下……最后。使用 Catel 时可以这样做:
if (!_isInternalChange)
{
if (e.HasPropertyChanged(() => Data))
{
await GetValueDate(e);
}
else if (e.HasPropertyChanged(() => QtaDiv1) || e.HasPropertyChanged(() => Exchange))
{
using (StartInternalChange())
{
ChangeQtaDiv2(QtaDiv1, Exchange);
}
}
if (e.HasPropertyChanged(() => QtaDiv2))
{
using (StartInternalChange())
{
ChangeQtaDiv1(QtaDiv2, Exchange);
}
}
else if (e.HasPropertyChanged(() => SelectedCross))
{
await GetValueDate(e);
CheckForSplitVisibility();
}
base.OnPropertyChanged(e);
}
private IDisposable StartInternalChange()
{
return new DisposableToken<MyClass>(this,
x => x._isInternalUpdate = false,
x => x._isInternalUpdate = true);
}
在将 Catel 用于 MVVM 框架的 WPF 应用程序中,我在视图模型中有 3 个不同的属性
public double? QtaDiv1 { get; set; }
public double? Exchange{ get; set; }
public double? QtaDiv2 { get; set; }
我已将 OnPropertyChanged 重写为
protected async override void OnPropertyChanged(AdvancedPropertyChangedEventArgs e)
{
if (e.PropertyName == "Data")
{
await GetValueDate(e);
}
else if (e.PropertyName == "QtaDiv1" || e.PropertyName == "Exchange")
{
ChangeQtaDiv2(QtaDiv1, Exchange);
}
if (e.PropertyName == "QtaDiv2")
{
ChangeQtaDiv1(QtaDiv2, Exchange);
}
else if (e.PropertyName == "SelectedCross")
{
await GetValueDate(e);
CheckForSplitVisibility();
}
base.OnPropertyChanged(e);
}
而我所做的是,如果 QtaDiv1 和 Exchange 具有我计算 QtaDiv2 的值 否则,如果用户(和 Exchange)更改了 QtaDiv2,我将更新 QtaDiv1。
这在我更新 QtaDiv2 之前工作正常,因为此时我在 QtaDiv1 上获得了一个 PropertyChanged,它调用了 QtaDiv2 上的更新等等...
我怎样才能打破这个咒语???我想设置一个包含更改值的字符串字段,但如果我这样做,我必须抑制 RaisePropertyChanged 通知(并且我必须转换为支持字段 属性),所以我不会得到验证他们
谢谢
您只需添加一个简单的 bool
变量来表示更改是否来自代码内部:
private bool isInternalChange = false;
如果是内部改动,可以忽略:
if (!isInternalChange)
{
if (e.PropertyName == "Data")
{
await GetValueDate(e);
}
else if (e.PropertyName == "QtaDiv1" || e.PropertyName == "Exchange")
{
isInternalChange = true;
ChangeQtaDiv2(QtaDiv1, Exchange);
isInternalChange = false;
}
if (e.PropertyName == "QtaDiv2")
{
isInternalChange = true;
ChangeQtaDiv1(QtaDiv2, Exchange);
isInternalChange = false;
}
else if (e.PropertyName == "SelectedCross")
{
await GetValueDate(e);
CheckForSplitVisibility();
}
base.OnPropertyChanged(e);
}
@Sheridan 的回答是正确的。正如@Boris B. 指出的那样,最好尝试一下……最后。使用 Catel 时可以这样做:
if (!_isInternalChange)
{
if (e.HasPropertyChanged(() => Data))
{
await GetValueDate(e);
}
else if (e.HasPropertyChanged(() => QtaDiv1) || e.HasPropertyChanged(() => Exchange))
{
using (StartInternalChange())
{
ChangeQtaDiv2(QtaDiv1, Exchange);
}
}
if (e.HasPropertyChanged(() => QtaDiv2))
{
using (StartInternalChange())
{
ChangeQtaDiv1(QtaDiv2, Exchange);
}
}
else if (e.HasPropertyChanged(() => SelectedCross))
{
await GetValueDate(e);
CheckForSplitVisibility();
}
base.OnPropertyChanged(e);
}
private IDisposable StartInternalChange()
{
return new DisposableToken<MyClass>(this,
x => x._isInternalUpdate = false,
x => x._isInternalUpdate = true);
}