通知视图模型的所有属性已更改为 null 或字符串为空

Notifying all properties of the viewmodel has changed with null or string empty

我来自开发 WPF 解决方案,在其中更新视图模型的所有属性非常简单:

OnPropertyChanged(String.Empty);

在通用 Windows 平台场景中,我只是对 update/refresh 属性使用相同的方法。这在大多数情况下都可以正常工作,但有时会引发如下错误:

COMException Error HRESULT E_FAIL has been returned from a call to a COM component. at System.ComponentModel.PropertyChangedEventHandler.Invoke(Object sender, PropertyChangedEventArgs e) at GeekyTool.Base.BindableBase.OnPropertyChanged(String propertyName) at Pooo.set_Root(UserRoot value) at Booo.d__26.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at GeekyTool.Base.PageBase.d__1.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<>c.b__6_0(Object state) at System.Threading.WinRTSynchronizationContext.Invoker.InvokeCore()

具有 INotifyPropertyChanged 接口实现的 OnPropertyChanged 方法如下所示:

public abstract class BindableBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    public virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    public virtual bool Set<T>(ref T storage, T value, [CallerMemberName]string propertyName = null)
    {
        if (object.Equals(storage, value))
            return false;
        storage = value;
        OnPropertyChanged(propertyName);
        return true;
    }
}

您可以探索 mvvm 库,但在 INotifyPropertyChanged 实现上没有什么不同。

GeekyTool Library on Github

我在堆栈跟踪中看到有一些异步代码,所以我建议仅使用 Dispatcher 调用 OnPropertyChanged(String.Empty),如下所示:

Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
    OnPropertyChanged(string.Empty);
});

CallerMemeberName 如果您不传入任何内容(或 null),则拉取呼叫成员名称 string.empty

我会先解决这个问题。

public bool IsValid
{
    get { return isValid; }
    set
    {
        if (isValid == value)
        {
            return;
        }

        isValid = value;
        OnPropertyChanged();
    }
}

这应该有效。通常在我不能使用 ReactiveObject 或 ObservableObject 的地方我倾向于使用这个。

感谢所有的回答,我试图修复一个不存在的错误。

在 OnPropertyChanged(string.Empty) 方法中引发错误,因为它伴随着之前页面的同步上下文问题。

当您在两个页面之间快速导航并且在 OnNavigatedTo 方法中有一些尚未完成的异步调用时,就会发生这种情况。正在等待异步方法,但在此页面中未处理用户等待直到完成。

只是知道不需要应用@PedroLamas 修复。确保在所有异步调用完成之前在页面上完成。