2017-03-27 16 views
2

私は同じくらい簡単だったのviewmodelのすべてのプロパティを更新するためにWPFのソリューション開発から来ている:ユニバーサルのWindowsプラットフォームのシナリオではがnullまたは文字列に変更された空の

OnPropertyChanged(String.Empty); 

を、私はちょうどプロパティを更新/リフレッシュする同じメソッドを持っています。これはほとんどの場合うまく動作しますが、次のようなエラーが発生することがあります。

COMException COMコンポーネントへの呼び出しからHRESULT E_FAILが返されました。 Booo.d__26.MoveNext()のPooo.set_Root(UserRoot値)のGeekyTool.Base.BindBase.BindableBase.OnPropertyChanged(String propertyName)のSystem.ComponentModel.PropertyChangedEventHandler.Invoke(Object Sender、PropertyChangedEventArgs e)---スタックトレースの終了GeekyTool.Base.PageBase.d__1.MoveNext()のSystem.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(タスクタスク)でSystem.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(タスクタスク)で例外がスローされた前の場所から取得します。 ---例外がスローされた前の場所からのスタックトレースの終了--- System.Runtime.CompilerServices.AsyncMethodBuilderCore。 < INotifyPropertyChangedインタフェースの実装と> c.b__6_0 System.Threading.WinRTSynchronizationContext.Invoker.InvokeCoreで(オブジェクトの状態)()

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実装では何も変わりません。

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

これがUWPで働いていれば驚きました。コードには、String.Emptyというプロパティ名を扱う特別なものは何もありません。あなたは完全なレクロを利用できますか? https://stackoverflow.com/help/mcve –

+1

@MattLacey、 'INotifyPropertyChangedを発生させます。PropertyChanged'イベントを 'string.empty'と一緒に使うのは、AFAIKがUWPで正常に機能してすべての(クラシックまたはコンパイルされた)バインディングを強制的にリフレッシュする"古い "トリックです! –

+0

x:bindを使用している場合は、ページのコードの背後にある 'this.Bindings.Update()'を呼び出して、そのページのすべてのバインディングを強制的に更新することができます。 – Rafael

答えて

2

ありがとうございました。私はそれがそこになかったというエラーを修正しようとしていました。

OnPropertyChanged(string.Empty)メソッドでは、以前のページの同期コンテキストの問題があるため、エラーを発生させます。

2つのページの間を非常に高速で移動し、まだ終了していないOnNavigatedToメソッドでいくつかの非同期呼び出しを行った場合に発生します。非同期メソッドが待たれていますが、このページでは、ユーザーがこれが完了するまで待つという処理は行われませんでした。

@PedroLamasを適用する必要がないことを知っているだけです。すべての非同期呼び出しが完了する前に、そのページでの作業が完了していることを確認します。

2

同じstring.emptyではないもの(またはnull)を渡します。

これを最初に修正します。

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

     isValid = value; 
     OnPropertyChanged(); 
    } 
} 

これは動作するはずです。私がReactiveObjectやObservableObjectを使うことができないところでは、これを使う傾向があります。

+0

質問はOnPropertyChanged(string.Empty)です。私ができることはそれを待たずに非同期操作です。あれは正しいですか?ありがとう! – soydachi

+0

正しいですが、 'Dispatcher'コールを待つ必要はありません。ここで必要なものは重要ではありません! –

1

CallerMemeberNameあなたの場合はメンバー名を呼ぶ引っ張る:そうは次のように、私はいくつかの非同期コードがあることをスタックトレースで見たので、私は唯一のDispatcherOnPropertyChanged(String.Empty)を呼び出すことをお勧めしたい

GeekyTool Library on Github

+1

はい、@PedroLamasによると、 'string.Empty'を使って' INotifyPropertyChanged.PropertyChanged'イベントを発生させることは、すべてのバインディングを更新/更新するように強制する "古い"トリックです。それが私がやっていることです。 – soydachi

関連する問題