【问题标题】:WPF Command not Executed from a Continuation Task未从继续任务执行 WPF 命令
【发布时间】:2017-06-11 12:05:08
【问题描述】:

我有一个简单的 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 方法包含正确的目标元素(以便 WPF 可以遍历可视化树并找到命​​令绑定),则始终执行 coomand。 但这不能在 ViewModel 中完成,因为它不应该看到 View。

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

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

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

服务 - 一些视图是用户控件,与 Windows 不同,它们没有 Loaded、Unloaded 事件 - 因此没有注册和注销服务的好地方。还可以创建多个控件,从而多次注册同一个服务,那么Views和ViewModels之间的绑定就不会是1:1了。

问题很简单:

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

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

【问题讨论】:

    标签: c# wpf mvvm


    【解决方案1】:

    尝试使用ContinueWith 方法的正确重载,该方法实际上接受TaskScheduler 执行操作,即调用命令,返回UI 线程:

    task.ContinueWith(
        taskAntecedent =>
        {
            AppCommands.SomeCommand.Execute(null, null);
        },
        System.Threading.CancellationToken.None,
        TaskContinuationOptions.None,
        TaskScheduler.FromCurrentSynchronizationContext());
    

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

    【讨论】:

    • 我终于解决了这个问题,使用 CLR 事件并在 UserControl 的 Loaded、Unloaded 和 DataContextChanged 处理程序中挂钩/取消挂钩 ViewModel 的事件。构建示例需要大约两个小时,不幸的是我没有。我希望稍后再讨论这个问题。
    猜你喜欢
    • 2013-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多