Существует ли простой способ Cailburn.Micro для отображения нового окна / диалогового окна? - PullRequest
0 голосов
/ 02 сентября 2018

Я следовал руководству по Winforms и конвертировал его в WPF и MVVM, используя Caliburn.Micro. Однако в учебнике 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());
    }
}

Мой Shellview

<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()
        {
        }
    }

A ChildView

<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 предоставляет простой способ сделать это?

Спасибо

Ответы [ 2 ]

0 голосов
/ 03 сентября 2018

Спасибо Нкоси за то, что он указал мне правильное направление; посмотрев на его ответ, я наткнулся на эту ссылку 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 : Указывает, закрывать ли элемент после его деактивации." Я изменил код, чтобы иметь второй параметр.

Я надеюсь, что это поможет кому-то еще в будущем.

0 голосов
/ 03 сентября 2018

Для этой цели существует интерфейс 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);
    }
}
...