1

私は労働者クラスを持っています

public event EventHandler<EventArgs> DataModified;

これはUIスレッド以外から発生する可能性があります(サーバーから更新をフェッチするのはネットワーククライアントです)。私はModelViewを持っています

ObservableCollection<DataModel> DataItems;

ビューがバインドする先。モデルビューはModifiedEventにサブスクライブする必要があるため、DataItemの変更を反映できます。コールバックイベントからDataItemsを更新するにはどうすればよいですか?モデルビューからUIディスパッチャーにアクセスできません(ビューがモデルビューを認識していないため)。これを処理するための適切な.NET4.5の方法は何ですか?

4

2 に答える 2

6

を保持するサービスを作成CoreDispatcherし、ビューモデルに挿入する(または静的にする)ことができます

public static class SmartDispatcher
{
    private static CoreDispatcher _instance;
    private static void RequireInstance()
    {
        try
        {
            _instance = Window.Current.CoreWindow.Dispatcher;

        }
        catch (Exception e)
        {
            throw new InvalidOperationException("The first time SmartDispatcher is used must be from a user interface thread. Consider having the application call Initialize, with or without an instance.", e);
        }

        if (_instance == null)
        {
            throw new InvalidOperationException("Unable to find a suitable Dispatcher instance.");
        }
    }

    public static void Initialize(CoreDispatcher dispatcher)  
    {
        if (dispatcher == null)
        {
            throw new ArgumentNullException("dispatcher");
        }

        _instance = dispatcher;
    }

    public static bool CheckAccess()
    {
        if (_instance == null)
        {
            RequireInstance();
        }
        return _instance.HasThreadAccess;
    }

    public static void BeginInvoke(Action a)
    {
        if (_instance == null)
        {
            RequireInstance();
        }

        // If the current thread is the user interface thread, skip the
        // dispatcher and directly invoke the Action.
        if (CheckAccess())
        {
            a();
        }
        else
        {
            _instance.RunAsync(CoreDispatcherPriority.Normal, () => { a(); });
        }
    }
}

App.xaml.csでSmartDispatcherを初期化する必要があります。

 var rootFrame = new Frame();
 SmartDispatcher.Initialize(rootFrame.Dispatcher);

 Window.Current.Content = rootFrame;
 Window.Current.Activate();

このように使用します。

SmartDispatcher.BeginInvoke(() => _collection.Add(item));

このクラスは、 WindowsPhone7用のJeffWilcoxのアナログに基づいています。

于 2012-09-10T12:52:17.660 に答える
2

WinRTでは、CoreDispatcherにアクセスする必要があります。CoreDispatcherはWindows.UI名前空間に存在し、それを介してのみ公開されWindow.Current. ます。つまり、コンストラクター、プロパティ、またはヘルパークラスのいずれかでViewModelに渡す必要があります。確かに理想的ではありませんが、それを回避する方法は見つかりませんでした。誰かが解決策を見つけたかどうかを確認したいと思います。

作業を楽にするために、いくつかのコードでこのスレッドを参照してください... WinRT / MetroのUIスレッドにディスパッチする必要があるかどうかを判断するにはどうすればよいですか?

于 2012-09-10T12:54:52.977 に答える