更新属性和乒乓球事件

本文关键字:事件 乒乓球 属性 更新 | 更新日期: 2023-09-27 18:00:55

在一个使用Catel for MVVM Framework的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);
}