WPF命令不是从继续任务执行的

时间:2017-06-11 12:05:08

标签: c# wpf mvvm

我有一个简单的MVVM应用程序。某些ViewModel执行异步处理,这需要通知View有关状态更新和处理完成的时间。

由于MVVM中对View的直接调用受到限制,因此我选择了 Commands 。不幸的是,即使任务被同步到主(UI)线程,从连续任务调用时也不会执行命令:

public void DoAction()
{
    //NOTE: command gets executed correctly
    AppCommands.SomeCommand.Execute(null, null);

    // run some task asynchronously
    Task task = new Task( ... );

    task.ContinueWith(
        taskAntecedent =>
        {
            //NOTE: command does not get executed at all!
            AppCommands.SomeCommand.Execute(null, null);
        },
        TaskScheduler.FromCurrentSynchronizationContext());

    task.Start();
}

如果Execute方法包含正确的目标元素,那么总是会执行coomand(这样WPF就可以在可视树上走,并找到命令绑定)。 但这不能在ViewModel中完成,因为它不应该看到View。

我尝试过的其他一些解决方案:

依赖注入 - 通过构造函数将View作为一些接口注入ViewModel。可行,但这会产生错误的空间:1。ViewModel不能在XAML中使用,因为ViewModel不再具有空的构造函数。 2.即使我定义了一个空的构造函数,开发者也可能忘记使用正确的构造并在其中注入适当的View(一些视图有几个可以被用户替换的ViewModel)。

路由事件 - ViewModel应该是可替换的,这意味着View必须从旧模型中取消挂钩事件并重新挂钩到需要在View中进行代码优化的新模型(不像MVVM一样)

服务 - 某些视图是UserControls,与Windows不同,它们没有Loaded,Unloaded事件 - 因此没有好的位置来注册和取消注册服务。还可以创建多个控件,从而多次注册相同的服务,然后Views和ViewModels之间的绑定不会是1:1。

问题很简单:

如何例如从UserControl的ViewModel关闭窗口,在View端或用户/开发人员没有大量额外编码?

我想在vanilla WPF中执行此操作,而不是使用第三方MVVM框架,因为应用程序应该是轻量级/易于理解的(尽可能少的黑魔法)。

1 个答案:

答案 0 :(得分:0)

尝试使用实际加入执行操作的ContinueWith的{​​{1}}方法的正确重载,即调用命令,返回UI线程:

TaskScheduler

如果由于某种原因这不起作用,我建议您提供a Minimal, Complete, and Verifiable example您的问题。