我在viewmodel中有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和Exchangehave值我计算QtaDiv2 否则,如果用户(和Exchange)更改了QtaDiv2,我会更新QtaDiv1。
这样可以正常工作,直到我更新QtaDiv2,因为此时我在QtaDiv1上得到一个PropertyChanged,它调用QtaDiv2上的更新等等......
我该如何打破这个咒语?我想过设置一个包含更改值的字符串字段,但是如果我这样做,我就要压制RaisePropertyChanged通知(我要转换为支持字段属性),这样我就不会对它们进行验证
由于
答案 0 :(得分:2)
您只需要添加一个简单的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);
}
答案 1 :(得分:1)
@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);
}