简体   繁体   English

通知viewmodel的所有属性已更改为null或字符串为empty

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

I'm coming from developing WPF solutions where to update all properties of the viewmodel was as simple as: 我来自开发WPF解决方案,在那里更新viewmodel的所有属性非常简单:

OnPropertyChanged(String.Empty);

In the Universal Windows Platform scenario, I just have the same method to update/refresh the properties. 在通用Windows平台方案中,我只有相同的方法来更新/刷新属性。 This works fine in most of cases but sometimes it raise an error something like this: 在大多数情况下,这可以正常工作,但有时会引发如下错误:

COMException Error HRESULT E_FAIL has been returned from a call to a COM component. COMException错误HRESULT E_FAIL已从对COM组件的调用返回。 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() 在System.ComponentModel.PropertyChangedEventHandler.Invoke(Object sender,PropertyChangedEventArgs e)在GeekyTool.Base.BindableBase.OnPropertyChanged(String propertyName)在Pooo.set_Root(UserRoot value)在Booo.d__26.MoveNext()---堆栈跟踪结束从之前引发异常的位置开始-在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)在GeekyTool.Base.PageBase.d__1.MoveNext() ---从之前抛出异常的位置开始的堆栈跟踪---在System.Runtime.CompilerServices.AsyncMethodBuilderCore。<> c.b__6_0(Object state)在System.Threading.WinRTSynchronizationContext.Invoker.InvokeCore()

The OnPropertyChanged method with an INotifyPropertyChanged interface implementation look like this: 具有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;
    }
}

You can explore the mvvm library, but nothing different on the INotifyPropertyChanged implementation. 您可以探索mvvm库,但在INotifyPropertyChanged实现上没有什么不同。

GeekyTool Library on Github Github上的GeekyTool库

I see on the stack trace that there's some async code, so I'd suggest only invoking OnPropertyChanged(String.Empty) with the Dispatcher , like so: 我在堆栈跟踪中看到有一些异步代码,因此建议仅使用Dispatcher调用OnPropertyChanged(String.Empty) ,如下所示:

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

Thank's for all the answers, I was trying to fix an error that it isn't was there. 感谢所有的答案,我正在尝试修复一个错误,提示它不存在。

In the OnPropertyChanged(string.Empty) method raise the error because it comes with an sync context issue from the page before. 在OnPropertyChanged(string.Empty)方法中引发错误,因为它带有来自上一页的同步上下文问题。

It happens when you are navigating between two page very fast and has some async calls in the OnNavigatedTo method where they aren't finished yet. 当您在两个页面之间快速浏览并且在OnNavigatedTo方法中有一些异步调用(尚未完成)时,就会发生这种情况。 The async method are awaited, but in this page was not handled that the user wait until this is finished. 等待异步方法,但是在此页面中,用户没有等待该操作完成。

Just to know that no need to apply @PedroLamas fix. 只知道不需要应用@PedroLamas修复程序。 Ensuring on the page before that all async calls are finished it's done. 确保在所有异步调用完成之前在页面上完成。

CallerMemeberName pulls calling member name if you pass in nothing (or null) that isn't the same string.empty 如果您不传入任何不相同的字符串(或null),则CallerMemeberName会提取呼叫成员名称。

I'd fix that first. 我先解决这个问题。

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

        isValid = value;
        OnPropertyChanged();
    }
}

This should work. 这应该工作。 Often where I can't use ReactiveObject or ObservableObject I tend to use this. 通常在无法使用ReactiveObject或ObservableObject的地方,我倾向于使用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM