2

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

コードビハインド

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}" />

MVVM

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

//ボタンのクリック時に ICommand プロパティを介して呼び出されます public void ExecuteCommand(object obj) { InvokeCallThroughAnonymousDelegateThread(); }

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

2 に答える 2

7

UI を更新しようとする場合は、ディスパッチャー スレッド内で行う必要があります。ただし、プロパティ変更イベントの場合、バックグラウンド スレッドからイベントが発生すると、WPFが自動的にディスパッチします。これについては、Bea Costa (元 WPF データ バインディング PM) のブログで詳しく読むことができます。

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

彼らはINotifyCollectionChangedイベントでも同じことをしようとしていましたが、以前のリリースではそれを実現できませんでした。4.5では、に加えてコレクションの変更イベントが自動的に同期されるようになりINotifyPropertyChangedました。

于 2012-04-05T16:15:34.790 に答える
2

NotifyPropertyChanged のスレッド コンテキストは、イベントを通じて WPF によって変更されますが、コード ビハインドはスレッド コンテキストを UI スレッドに変更しません。コードビハインドでは、代わりにこれを使用します。

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

        }, TaskScheduler.FromCurrentSynchronizationContext());

Dispatcher をいつ使用するかについては、どの ViewModel でも Dispatcher を使用していない中規模のプロジェクトがあります。Xaml リソース、弱いイベント処理を処理するために使用しており、MefedMVVM と Prism の内部で使用されています。

于 2012-04-05T15:53:10.807 に答える