1

我有工人班

public event EventHandler<EventArgs> DataModified;

可以从 UI 线程以外的地方引发(它是从服务器获取更新的网络客户端)。我有 ModelView

ObservableCollection<DataModel> DataItems;

View 绑定到的。我的模型视图必须订阅 ModifiedEvent,这样才能反映 DataItems 的变化。如何从回调事件更新 DataItems?我无法从我的模型视图访问 UI Dispatcher(因为视图不应该知道模型视图)。处理此问题的正确 .NET 4.5 方法是什么?

4

2 回答 2

6

您可以创建一个包含 a 的服务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));

本课程基于Jeff Wilcox 的 windows phone 7 模拟

于 2012-09-10T12:52:17.660 回答
2

在 WinRT 中,您必须访问 CoreDispatcher。Window.Current. CoreDispatcher驻留在 Windows.UI 命名空间中,仅通过 我很想看看是否有人找到了解决方案。

在某些代码上查看此线程以使生活更轻松... 如何确定是否需要分派到 WinRT/Metro 中的 UI 线程?

于 2012-09-10T12:54:52.977 回答