Как правильно загрузить контент в ModernWindow с помощью mvvm

В нашей компании мы привыкли разрабатывать наши приложения с помощью WinForms, теперь мы решили перейти на WPF-MVVM с Caliburn.Micro и современным пользовательским интерфейсом. То, что мы пытаемся достичь, это иметь небольшое приложение, которое имеет: - 1 современное окно - 2 страницы внутри этого современного окна цель состоит в том, чтобы иметь кнопку внутри этой страницы, которая перемещает современное окно на вторую страницу с параметрами.

Я работал, пытаясь понять, как это сделать, мне удалось с окном (без MUI), но когда дело доходит до MUI, это не дает мне желаемого результата.

До сих пор все, что я сделал, это

  1. Создайте новый проект MUI
  2. Добавьте Caliburn.Micro в проект
  3. Измените App.xaml на

    <Application x:Class="MuiWithCaliburn01.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:MuiWithCaliburn01">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary>
                    <local:AppBootstrapper x:Key="bootstrapper" />
                    <local:ModernContentLoader x:Key="ModernContentLoader" />
                </ResourceDictionary>
                <ResourceDictionary Source="/FirstFloor.ModernUI;component/Assets/ModernUI.xaml" />
                <ResourceDictionary Source="/FirstFloor.ModernUI;component/Assets/ModernUI.Light.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
    

  4. Create the Bootstrapper Class

    
    public class AppBootstrapper : BootstrapperBase
    {
        static AppBootstrapper()
        {
        }
        public AppBootstrapper()
        {
            Initialize();
        }
        protected override void OnStartup(object sender, StartupEventArgs e)
        {
            DisplayRootViewFor();
        }
    }
    
  5. Создайте класс ModernContentLoader

    
    public class ModernContentLoader : DefaultContentLoader
    {
        protected override object LoadContent(Uri uri)
        {
            var content = base.LoadContent(uri);
            if (content == null)
                return null;
            var vm = Caliburn.Micro.ViewModelLocator.LocateForView(content);
            if (vm == null)
                return content;
            if (content is DependencyObject)
            {
                Caliburn.Micro.ViewModelBinder.Bind(vm, content as DependencyObject, null);
            }
            return content;
        }
    }
    
  6. Модервиндоввиев.xaml и Модервиндоввиевмодел.cs

    
    < mui:ModernWindow x:Class="MuiWithCaliburn01.ModernWindowView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:mui="http://firstfloorsoftware.com/ModernUI"
        ContentLoader="{StaticResource ModernContentLoader}">
    < mui:ModernWindow.MenuLinkGroups>
        < mui:LinkGroupCollection>
            < mui:LinkGroup DisplayName="Hello">
                < mui:LinkGroup.Links>
                    < mui:Link Source="Child1View.xaml" DisplayName="Click me">< /mui:Link>
                < /mui:LinkGroup.Links>
            < /mui:LinkGroup>
        < /mui:LinkGroupCollection>
    < /mui:ModernWindow.MenuLinkGroups>
    < /mui:ModernWindow>
    

    class ModernWindowViewModel : Conductor.Collection.OneActive
    {
        public ModernWindowViewModel()
        {
            //this function is doing nothing in the ModernWindow, but it works great in the Window.
            ActivateItem(new Child1ViewModel());
        }
    }
    

  7. И, наконец, Child1View.xaml

    <UserControl x:Class="MuiWithCaliburn01.Child1View"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
        xmlns:mui="http://firstfloorsoftware.com/ModernUI"
        mc:Ignorable="d" 
        xmlns:cal="http://www.caliburnproject.org"
        xmlns:model="clr-namespace:MuiWithCaliburn01"
        d:DataContext="{x:Type model:Child1ViewModel}"
        d:DesignHeight="300" d:DesignWidth="300">
        <Grid>
            <Button cal:Message.Attach="ClickMe" Width="140" Height="50">Hello World</Button>
        </Grid>
    </UserControl>
    

    и Child1ViewModel.cs

    public class Child1ViewModel : Conductor<IScreen>
    {
        public void ClickMe()
        {
            MessageBox.Show("Hello");
        }
    }
    

Мой вопрос, шаг 6, почему функция ничего не делает? и если мой путь неправильный, может ли кто-нибудь указать мне лучший путь?

И если это лучший подход, как я могу перейти от функции ClickMe к другому представлению.


person Ahmad Hammoud    schedule 04.04.2016    source источник
comment
Я понимаю, что это не тот ответ, который вы ищете, но реальность заключается в том, чтобы перейти от Winforms к Caliburn. Micro + MUI + MVVM напрямую — это очень плохая идея. Сначала вы должны изучить каждый из них отдельно, а затем пытаться интегрировать. Их трудно понять (даже если они не кажутся таковыми), они начинаются с кошмара, когда вы смешиваете все неизвестные в одном плавильном котле.   -  person Maverik    schedule 12.04.2016


Ответы (1)


Что касается вашего первого вопроса о том, почему функция ничего не делает, я думаю, что это может быть связано с иерархией вашего проекта. Используя MUI, это главное (и единственное) окно для одного из моих приложений.

<mui:ModernWindow x:Class="namespace.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:mui="http://firstfloorsoftware.com/ModernUI"
    Title="Window Title" IsTitleVisible="True"
    ContentSource="/Pages/Home.xaml"
    Style="{StaticResource MyModernWindow}">

<mui:ModernWindow.TitleLinks>
    <mui:Link DisplayName="settings" Source="/Pages/SettingsPage.xaml" />
</mui:ModernWindow.TitleLinks>

in my project hierarchy, i have my project root (CSPROJ file), MainWindow.xaml then a Pages folder. Inside my pages folder i have my SettingsPage.xaml. The source attribute in my mui:Link tag points to the realitive path of my main window to my settingsPage.xaml file. MUI will then load and display that path in the content provider that is put in your main window for you by the MUI ModernWindow class default style template. No additional code is needed on your part to navigate (until you want complex sub view navigation).

мой файл settingsPage.xaml представляет собой обычный пользовательский элемент управления с сеткой, имеющей стиль, назначенный стилю статического ресурса ContentRoot, поскольку он также будет содержать дополнительные представления/страницы.

Исходный код Mui можно найти на GitHub по адресу Mui GithubLink. Здесь вы можете скачать образец программы, код которого находится в том же репозитории в приложении Ссылка для ознакомления.

Я не знаком с Caliburn.Micro, поэтому я не уверен, как они интегрируются вместе, например, требования Caliburn.Micro для работы. Я знаю, как MUI интегрируется с MVVM light, и есть много примеров этого, найденных в Интернете в моем предварительном исследовании.

person xtreampb    schedule 08.04.2016