async/await in INotifyPropertyChanging EventHandler with can

本文关键字:EventHandler with can INotifyPropertyChanging in await async | 更新日期: 2023-09-27 18:35:39

我正在使用带有MVVM模式的WPF。

在我的模型类中,我使用从 PropertyChangingEventArgs 派生的自定义 EventArgs 实现 INotifyPropertyChanging 接口。这是必要的,因为我希望能够"取消"属性设置器。

此事件正在包含该模型的视图模型中处理。

在事件处理程序中,我必须

调用数据库,有时我必须根据结果通过事件参数取消属性设置器。

该模型类似于以下内容:

public class CancellablePropertyChangingEventArgs : PropertyChangingEventArgs
{
    public bool Cancel { get; set; }
}
public class Model : INotifyPropertyChanging
{
    public string MyProperty
    {
        get { return _myProperty; }
        set
        {
            var args = RaisePropertyChanging();
            if(!args.Cancel)
                _myProperty = value;
        }
    }
    public CancellablePropertyChangingEventArgs RaisePropertyChanging([CallerMemberName] string propertyName = "")
    {
        var eventArgs = new CancellablePropertyChangingEventArgs(propertyName);
        if(PropertyChanging != null)
        {
            PropertyChanging(this, eventArgs);
        }
        return eventArgs;
    }
}

包含上述模型并处理 PropertyChanging 事件的视图模型,在事件处理程序中,我有一个类似于下面的代码:

private async void HandleModelPropertyChanging(object sender, PropertyChangingEventArgs e)
{
    var args = e as CancellablePropertyChangingEventArgs;
    if(args.PropertyName = "MyProperty")
    {
        var result = await CallToDataBaseAsync(...);
        if(result == null)
            args.Cancel = true;
    }

}

我知道我的事件处理程序中的异步空意味着"触发并忘记",因此事件处理程序继续在 CallToDataBaseAsync 执行,而不是等待它等等。取消将始终为假。

但是,在不阻止 GUI 线程的情况下,我可以尝试任何其他可能的解决方案吗?

async/await in INotifyPropertyChanging EventHandler with can

我之前确实走过这条路 - 取消二传手是错误的方法,即使等待,它也不会像您期望的那样工作。设置此属性的 wpf 绑定需要您更改属性或引发异常作为验证机制。因此,通过不分配值和不触发事件来简单取消PropertyChanged将导致设置此属性的控件不同步 - 它将显示用户键入的数据,而不是属性中实际存储的数据。

如果您真的想尝试一下,请更改处理程序以返回 Task,但请记住这是有缺陷的解决方案 - 如果您附加了多个处理程序,则只会等待最后一个处理程序的结果。通过更多的工作,您可以聚合这些任务,但无论如何都是毫无意义的。