使用 Caliburn.Micro 4.0.x 和 WPF 的对话框

Posted

技术标签:

【中文标题】使用 Caliburn.Micro 4.0.x 和 WPF 的对话框【英文标题】:Dialog using Caliburn.Micro 4.0.x and WPF 【发布时间】:2021-05-02 13:13:53 【问题描述】:

我正在使用 Caliburn.Micro 4.0.136-rc 并希望显示一个对话框,要求用户输入。

我找到的只是几年前的答案,使用的是 CM 中不再提供的类。其他人链接到死网站上的解决方案。

我使用的是继承自 Screen 的 ViewModel。如何使用 CM 和 MVVM 创建和显示 Dialog?

【问题讨论】:

您能否提供几年前答案之一的链接,使用 CM 中不再可用的类? 这是我搜索 Dialog 和 CM 时的最佳结果:***.com/questions/17510704/… 接受的答案很短,所有链接都指向死网站。下一个响应使用 WindowManager.ShowDialog()。找不到这个方法。 这是 404 的博客文章的更新链接:web.archive.org/web/20170113153246/http://devlicio.us/blogs/… 而this page 有关于如何合成屏幕的详细信息。在页面上搜索IDialogManager 谷歌搜索“Caliburn.Micro.HelloScreens.zip”引导我here。当然,它可能会使用您前面提到的一些缺失的类,但它是一个开始的地方。 【参考方案1】:

我发现了两种使用 Caliburn.Micro 显示对话框的可能方式

IWindowManager

基于此页面https://csharp.hotexamples.com/examples/Caliburn.Micro/WindowManager/ShowDialog/php-windowmanager-showdialog-method-examples.html

我使用的是 IoC,所以我通过构造函数将 IWindowManager 注入到 ViewModel。

有了这个引用,就可以调用 ShowDialogAsync() 并从对话框中指向 ViewModel。这是重要的部分:

        private readonly IWindowManager _windowManager;

        public ShellViewModel(IWindowManager windowManager)
        
            _windowManager = windowManager;
        

        protected override async void OnViewLoaded(object view)
        
            await Task.Delay(1500);
            await _windowManager.ShowDialogAsync(new UsrControlViewModel());
        

MaterialDesignInXAML

在我的项目中已经使用了 MaterialDesignInXAML 包,所以这可能不是每个人都可以接受的。

这是对话框的文档部分:https://github.com/MaterialDesignInXAML/MaterialDesignInXamlToolkit/wiki/Dialogs

我发现了一个问题,该问题描述了如何使用 MaterialDesignInXAML 显示对话框,并且该绑定在 Caliburn.Micro 中失败。虽然这似乎是 Caliburn.Micro 的问题,但 Keboo 提供了一个解决方案和变通方法。

线程:https://github.com/MaterialDesignInXAML/MaterialDesignInXamlToolkit/issues/1085

从那个线程来看,重要的一点是:

视图模型

public async Task OpenDialog()

    var viewModel = new UsrControlViewModel();
    UIElement uiElement = ViewLocator.LocateForModel(viewModel, null, null);
    ViewModelBinder.Bind(viewModel, uiElement, null);
    await DialogHost.Show(uiElement, 
    new DialogOpenedEventHandler((sender, args) => viewModel.WithDialogSession(args.Session)));
    var result = viewModel.Text;

查看

    <materialDesign:DialogHost>
        <materialDesign:DialogHost.DialogContent>
            <ContentControl />
        </materialDesign:DialogHost.DialogContent>
        <!-- rest of my view -->
    </materialDesign:DialogHost>

我将采用第二种方法,因为 MaterialDesignInXAML 已在此项目中使用。

【讨论】:

这是很难找到的非常好的信息。我也有一个 Material Design / Caliburn.Micro 应用程序,这是我必须解决的最困难的事情之一。我最终直接为视图设置了 DataContext 以解决这个UserView view = new UserView DataContext = IoC.Get&lt;UserViewModel&gt;() 。我更喜欢这种方法,因为它是 Caliburn.Micro 原生的。

以上是关于使用 Caliburn.Micro 4.0.x 和 WPF 的对话框的主要内容,如果未能解决你的问题,请参考以下文章

使用 WPF 和 Caliburn.Micro 在视图中添加多个视图

Caliburn.Micro 能否很好地与用户控件配合使用?

Caliburn.Micro框架之Bindings

MVVM框架 -- Caliburn.Micro 系列文章

Caliburn.Micro 无法匹配来自不同程序集的 View 和 ViewModel

使用 Caliburn.Micro 附加到多个事件