【问题标题】:Is there an easy Cailburn.Micro way to display a new Window/Dialog?是否有一种简单的 Cailburn.Micro 方式来显示新的窗口/对话框?
【发布时间】:2018-09-02 20:34:30
【问题描述】:

我一直在关注 Winforms 教程并使用 Caliburn.Micro 将其转换为 WPF 和 MVVM。但是,在 winforms 教程中,它调用了一个新表单。

CreatePrizeForm frm = new CreatePrizeForm();
frm.Show;

我想我可以使用 Caliburn.Micro ActivateItem 来做类似的事情。我已经包含了一些我的实验代码。

我的 ShellViewModel

public class ShellViewModel : Conductor<object>
{
    public void LoadFormOne()
    {
        MessageBox.Show("You are about to activate FirstChildViewModel");
        ActivateItem(new FirstChildViewModel());
    }

    public void LoadFormTwo()
    {
        MessageBox.Show("You are about to activate SecondChildViewModel");
        ActivateItem(new SecondChildViewModel());
    }
}

我的贝壳视图

<Window x:Class="ConductorTest.ShellView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:ConductorTest"
    mc:Ignorable="d"
    Title="ShellViewModel" Height="450" Width="800">
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <Button Grid.Column="1" Grid.Row="1"  x:Name="LoadFormOne" Content="Load Form One" />
    <Button Grid.Column="1" Grid.Row="3"  x:Name="LoadFormTwo" Content="Load Form Two" />
</Grid>
</Window>

一个 ChildViewModel

    public class FirstChildViewModel : Screen
    {
        public FirstChildViewModel()
        {
        }
    }

一个子视图

<Window x:Class="ConductorTest.FirstChildView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:ConductorTest"
    mc:Ignorable="d"
    Title="FirstChildView" Height="450" Width="800">
<Grid>
    <TextBlock>You are now in First Child View</TextBlock>
</Grid>
</Window>

所以我的想法是,如果我点击 LoadFormOne 按钮,它就会执行,

ActivateItem(new FirstChildViewModel());

然后会新建一个 FirstChildViewModel(),类似于

DisplayRootViewFor<ShellViewModel>();

在标准的 bootstrapper.cs 中,然后会启动一个新的 WPF 表单。

但显然不是。

我缺少什么或者 Caliburn.Micro 没有提供一种简单的方法来做到这一点?

谢谢

【问题讨论】:

标签: c# wpf mvvm dialog caliburn.micro


【解决方案1】:

为此目的有一个IWindowManager 接口。

public class ShellViewModel : Conductor<object> {
    private readonly IWindowManager window;

    public ShellViewModel(IWindowManager window) {
        this.window = window;
    }    

    public void LoadFormOne() {
        MessageBox.Show("You are about to activate FirstChildViewModel");
        var model = new FirstChildViewModel();
        ActivateItem(model);
        window.ShowDialog(model);
        //or
        //window.ShowWindow(model); //For non-modal
        DeactivateItem(model);
    }
}

【讨论】:

  • 您好 Nkosi,感谢您为我指出正确的方向,但添加后,代码无法编译。但是再次感谢您为我指明了正确的方向,因为我一直不知道接下来要看的方向。
【解决方案2】:

感谢 Nkosi 为我指明了正确的方向;看了他的回答后,我发现了这个链接https://csharp.hotexamples.com/examples/Caliburn.Micro/WindowManager/ShowDialog/php-windowmanager-showdialog-method-examples.html

然后我修改了我的代码来工作。

public class ShellViewModel : Conductor<object>
{
    private readonly IWindowManager window = new WindowManager();

    public void LoadFormOne()
    {
        MessageBox.Show("You are about to activate FirstChildViewModel");
        var model = new FirstChildViewModel();
        ActivateItem(model);
        window.ShowDialog(model);
        //or
        //window.ShowWindow(model); //For non-modal
        bool CloseItemAfterDeactivating = true;
        DeactivateItem(model, CloseItemAfterDeactivating);
    }
}

注意事项

  1. 在 Bootstrapper.cs 中你不能拥有

    DisplayRootViewFor<ShellViewModel(new WindowManager())>();
    

将新的 WindowManager 发送到 ShellViewModel,因此您不能让 ShellViewModel 的构造函数接受 WindowManager。所以我将“窗口”更改为在 ShellViewModel 启动时初始化的私有窗口。

  1. 你不能拥有

    DeactivateItem(模型);

编译器抱怨你需要第二个参数“close:指示是否在停用项目后关闭它。”。我已将代码更改为具有第二个参数。

我希望这对将来的其他人有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-02-13
    • 2017-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-19
    • 1970-01-01
    相关资源
    最近更新 更多