1

有一个类似的问题(如何将 UI Dispatcher 传递给 ViewModel任何人都为我提供了一些示例或完整代码。我是 MVVM 的新手,所以我没有得到。

private async void BindMatchGridinAsync()
        {
            await BindMatchGridAsync(); 
        }        
        async Task<ObservableCollection<EfesBet.DataContract.GetMatchDetailsDC>> BindMatchGridAsync()
        {
            await Task.Run(() => 
                {
                    BindMatchGrid();
                });
            return null;
        }
        void BindMatchGrid()
        {
            BindMatchGridDel bindDel = new BindMatchGridDel(BindMatchGridData);
            matchList = new List<GetMatchDetailsDC>();            
            matchList = proxy.GetMatch().ToList();            
            dataGridParent.Dispatcher.BeginInvoke(bindDel, null);
        }
        public delegate void BindMatchGridDel();
        void BindMatchGridData()
        {
            dataGridParent.ItemsSource = matchList;
        }

现在,在这段代码 BindMatchGridinAsync() 中,我已将代码的构造函数放在文件(.cs 文件)后面。它正在提供适当的异步操作。但我需要在 ViewModel 中实现相同的功能。请建议我如何实施它。提前谢谢你。

4

5 回答 5

2

您正在像 WinForms 开发人员一样考虑这一点,其中每个控件都可以位于单独的线程上。

在 WPF 中有一个 UI 线程。这个线程称为 Dispatcher。所以每个控件都将使用相同的调度程序。

正如刚才提到的:

Application.Current.Dispatcher.BeginInvoke(new Action(DoSomething),null);

完全可以接受,并且可以与您的所有控件一起使用,因为所有控件都使用应用程序 Dispatcher。

于 2013-08-30T12:43:27.497 回答
0

最好的解决方案是以根本不需要调度程序的方式使用async和:await

async Task<ObservableCollection<GetMatchDetailsDC>> BindMatchGridAsync()
{
    var matchList = await Task.Run(() => BindMatchGrid());
    dataGridParent.ItemsSource = matchList;
    return new ObservableCollection<GetMatchDetailsDC>(matchList);
}

List<GetMatchDetailsDC> BindMatchGrid()
{
    matchList = new List<GetMatchDetailsDC>();            
    matchList = proxy.GetMatch().ToList();            
    return matchList;
}
于 2013-08-30T14:29:25.377 回答
0

You don't need to pass dispatcher, in your ViewModel try (WPF version):

Application.Current.Dispatcher.BeginInvoke(new Action(DoSomething),null);
于 2013-08-30T12:14:57.630 回答
0

不要这样做!使用 MVVM 的全部意义在于将 UI 实现与应用程序逻辑分开。如果您推送静态调用Application.Current.Dispatcher或类似调用,您会立即将您的视图模型绑定到 WPF 实现。您将如何在独立于 WPF 的情况下测试您的视图模型?

如果您真的想静态访问 UI 线程,那么至少使用一些抽象出您正在使用 WPF 的事实的东西,例如SynchronizationContext

public class MyViewModel : NotificationObject
{
    private SynchronizationContext _context;

    public MyViewModel()
    {
        _context = SynchronizationContext.Current;
    }
}

假设在 UI 线程上调用构造函数,您现在有一个私有变量,它为您提供了在调度程序上运行代码的后门。

更好的是,您可以SynchronizationContext.Current在 IoC 容器中注册(或它的抽象)并将其注入构造函数。那么您就不会依赖于 UI 线程正在构建视图模型这一事实。

于 2013-08-30T14:48:39.647 回答
0

使用MVVM Light,您可以使用DispatcherHelper静态类:

// Get the UI dispatcher :
var uiDispatcher = DispatcherHelper.UIDispatcher;
// Execute in UI :
// In current thread
DispatcherHelper.CheckBeginInvokeOnUI(() =>
{
    // In UI thread
});
于 2013-08-30T12:36:05.460 回答