在我们公司,我们习惯于使用WinForms开发应用程序,
现在,我们决定使用Caliburn.Micro和Modern UI切换到WPF-MVVM。
我们要达到的目标是拥有一个小型应用程序,该应用程序应具有:
-1个现代 window
-在该现代窗口内2页
目标是在该页面内有一个按钮,该按钮可使用参数将Modern Window导航到第二页。

我一直在努力了解如何解决这个问题,我成功使用了Window(没有MUI),但是谈到MUI时,它并没有真正给我我们想要的结果。

到目前为止,我所做的就是

  • 创建一个新的MUI项目
  • 将Caliburn.Micro添加到项目
  • 将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>
    

  • 创建Bootstrapper类
    
    public class AppBootstrapper : BootstrapperBase
    {
        static AppBootstrapper()
        {
        }
        public AppBootstrapper()
        {
            Initialize();
        }
        protected override void OnStartup(object sender, StartupEventArgs e)
        {
            DisplayRootViewFor();
        }
    }
    
  • 创建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;
        }
    }
    
  • ModernWindowView.xaml和ModernWindowViewModel.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());
        }
    }
    
  • 最后是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函数导航到另一个 View 。

    最佳答案

    关于您的问题,为什么该功能什么都不做,我认为这可能与您项目的层次结构有关。使用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>
    

    在我的项目层次结构中,我有我的项目根目录(CSPROJ文件),MainWindow.xaml和一个Pages文件夹。在我的页面文件夹中,我有我的SettingsPage.xaml。我的mui:Link标记中的source属性指向主窗口指向settingsPage.xaml文件的真实路径。然后,MUI将加载并显示MUI ModernWindow类默认样式模板为您放置在主窗口中的内容提供程序中的路径。您无需进行任何其他代码即可导航(直到您需要复杂的 subview 导航)。

    我的settingsPage.xaml文件是普通用户控件,网格具有分配给ContentRoot静态资源样式的样式,因为它还将包含其他 View /页面。

    Mui的源代码可以在GitHub上的Mui GithubLink上找到。在这里,您可以下载示例程序,该程序的代码可在Link here for covience应用程序的同一存储库中找到。

    我对Caliburn.Micro不熟悉,所以我不确定两者如何集成在一起,例如Caliburn.Micro的功能要求。我确实知道MUI如何与MVVM light集成在一起,并且在我之前的研究中可以在互联网上找到很多这样的示例。

    关于c# - 如何使用mvvm在ModernWindow内部正确加载内容,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36413164/

    10-11 02:04