2012-04-05 5 views
2

新しいスレッドを開始しており、ビューモデルで定義されているプロパティを使用してUI要素を更新しようとしていますが、エラーなしで実行できますが、UI要素をコードビハインドで更新しようとすると、アクセスエラー(「別のスレッドが所有しているため、呼び出し元のスレッドはこのオブジェクトにアクセスできません」)。最初の質問は.. 2つのアプローチの違いは何ですか? 2番目の質問は、ViewModelでDisptacherを理想的に使用するときでしょうか?ボタン上のICommandプロパティを通じて呼び出されMVVM WPFでMVVM paternにディスパッチャは不要ですか?

private void Button_Click(object sender, RoutedEventArgs e) 
    { 
     Thread th = new Thread(new ThreadStart(delegate() 
      { 
       textbox.Text = "Rajib"; 
      } 
     )); 

     th.Start(); 
    } 

//inside XAML 
<TextBox x:Name="textbox" Text="{Binding UserInput, Mode=TwoWay}" /> 

の後ろ

コード
public string UserInput 
    { 
     get { return _UserInput; } 
     set { _UserInput = value; OnPropertyChanged("UserInput"); } 
    } 

// ます。public void ExecuteCommand(オブジェクトobj) { InvokeCallThroughAnonymousDelegateThread()をクリックしてください。 }

private void InvokeCallThroughAnonymousDelegateThread() 
    { 
     ThreadStart start = delegate() 
     { 
      UserInput = "Calling from diff thread"; 
     };   
     new Thread(start).Start(); 
    } 

答えて

7

UIを更新するには、ディスパッチャスレッド内で行う必要があります。ただし、プロパティ変更イベントの場合、WPF は、バックグラウンドスレッドからイベントが発生したときに、自動的にを送出します。あなたがビーコスタさん(旧WPFデータがPMを結合)ブログにこの詳細を読むことができます:

http://bea.stollnitz.com/blog/?p=34

彼らはINotifyCollectionChangedイベントのために同じことをするつもりが、以前のリリースでは、それに周りにやったことがなかったです。 INotifyPropertyChangedに加えて4.5 they will now be synchronizing collection changed events automaticallyの場合。

2

NotifyPropertyChangedは、イベントを通じてWPFによって変化し、そのスレッドコンテキストを持っていますが、あなたのコードは、背後にあるUIスレッドにスレッドコンテキストを変更しません。あなたの分離コードでは、代わりにこれを使用する:

Task.Factory.StartNew(() => 
     { 
      // Background work 
     }).ContinueWith((t) => { 
      // Update UI thread 

     }, TaskScheduler.FromCurrentSynchronizationContext()); 

を直接ディスパッチャを使用する際に関しては、私はどのViewModelにでDispatcherを使用していない中規模のプロジェクトを持っています。私はXamlリソース、弱いイベント処理に対処するためにこれを使用しています。これはMefedMVVMとPrismの内部で使用されています。

関連する問題