【问题标题】:Update modal dialog in Caliburn Micro from outside the dialog's VM从对话框的 VM 外部更新 Caliburn Micro 中的模态对话框
【发布时间】:2021-12-11 23:38:21
【问题描述】:

我遇到以下情况:我正在尝试将文件加载到应用程序中(这是一个使用 Caliburn Micro 的基于 C# 的 WPF 应用程序)。

这个文件的性质并不重要,但加载过程包含许多步骤,对于大文件,可能需要一段时间才能完成。

我想要做的是在我的应用程序中显示一个模态对话框,该对话框在加载过程开始时显示,最后关闭并在加载过程中由应用程序更新,以便对话框中的文本反映应用程序已到达加载过程中。

我已经通过在对 windowmanager.ShowDialog() 的调用中传入关联的视图模型来显示视图,但是没有任何反应。我只能假设这是因为对话框可能是同步显示的,因此永远不会到达完成加载和更新对话框的后续调用。

本质上这是我目前正在尝试的事情(VM 有一个在视图中使用的消息字符串属性):

windowManager.ShowDialog(ProgressDialogVM);

doSomething();
ProgressDialogVM.Message = "Step 2";
doSomethingElse();
ProgressDialogVM.Message = "Step 3";
doSomethingElseAgain();
ProgressDialogVM.Message = "Step 4";

ProgressDialogVM.TryClose();

对话框 VM 中的属性如下所示:

private string message = "";
public string Message
{
    get
    {
        return message;
    }
    set
    {
        if (value != message)
        {
            message = value;
            NotifyOfPropertyChange(nameof(message));
        }
    }
}

最后是用于文本框的 XAML,以防此处相关:

<TextBlock Grid.Row="1" Text="{Binding Path=Message, UpdateSourceTrigger=PropertyChanged}" />

任何关于如何做到这一点的想法将不胜感激。

编辑 我已经到了可以显示窗口并让代码执行的地步了。我什至可以在视图模型中成功设置属性并在窗口中显示初始值。然而,现在的问题是该值虽然可以设置,但并未在相应的视图中更新。它非常高兴地显示了初始值,但在那之后没有任何变化。

因此,在窗口下方的测试示例中,窗口将显示“步骤 0”,但不会更新为显示“步骤 1”。

ProgressDialogViewModel ProgressDialogVM = new ProgressDialogViewModel();  
ProgressDialogVM.Message = "Step 0";
windowManager.ShowWindow(ProgressDialogVM, null, null);
ProgressDialogVM.Message = "Step 1";

【问题讨论】:

  • 什么是ProgressDialogVM?它是否继承自MessageBox
  • 它继承自 Screen。 MessageBox 似乎是一个密封类。

标签: c# wpf caliburn.micro


【解决方案1】:

WindowManager.ShowDialog() 打开一个模态窗口,这就是为什么它会阻止主/父窗口中的进一步操作,直到模态窗口关闭。这就是为什么在打开 ProgressDialogVM 时无法执行第一个代码示例中的后续步骤的原因。

在第二种情况下,您使用了WindowManager.ShowWindow,它打开了一个非模态窗口。这允许在主/父窗口中进一步执行代码。但是,看起来后续操作是同步的,因此 UI 线程无法用于在 ProgressDialogVM 上进行 UI 更新。

你可以做的是确保像doSomethingElse这样的中间操作是异步的。

progressDialogVm.Message = "State 01";
_windowManager.ShowWindow(progressDialogVm,null,null);
await DoSomething();
progressDialogVm.Message = "State 02";
await DoSomethingElse();

这将确保 ProgressDialog 中的消息文本根据需要更新。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多