MvvmLight框架使用入门(三)

摘要:
这是关于开始使用MvvmLight框架的第三篇文章。我们将创建一个通用应用程序并应用MvvmLight框架。在创建UniversalApp之后,将上一篇文章中创建的HelloMvvvvmLight项目中的整个ViewModel文件夹复制到UWP项目中。当然,本文将不仅仅是关于这一点。我们将进一步介绍在UniversalApp中使用MvvmLight框架。接下来,我们将添加第二个页面,以了解MvvmLight如何支持页面间导航。ViewModelLocator类注册PageTwoViewModel,创建INavigationService的实例,并关联页面。

  本篇是MvvmLight框架使用入门的第三篇。从本篇开始,所有代码将通过Windows 10Universal App来演示。我们将创建一个Universal App并应用MvvmLight框架。

  首先通过VS2015创建一个名为UniversalApp的空工程(工程类型为Universal Windows),然后通过NuGet获取MvvmLight,这里需要注意的是,我们选择MvvmLightLib仅下载DLL文件,因为MvvmLight还未对Universal App做适配,并不会自动创建ViewModel以及ViewModelLocator等文件。

  在创建UniversalApp完成后,将上一篇创建的HelloMvvmLight工程中的ViewModel文件夹整个拷贝到UWP工程里(注意修改namespace)。这样MainViewModel以及ViewModelLocator文件就有了。

接着在App.xamlResources中添加对ViewModelLocator的引用:

    <Application.Resources>
        <ResourceDictionary>
            <vm:ViewModelLocator x:Key="Locator" />
        </ResourceDictionary>
    </Application.Resources>

  这里需要注意保持namespaceViewModelnamespace一致:xmlns:vm="using:UniversalApp.ViewModel"

  再下一步就是修改MainPage.xaml文件,将xaml的内容修改如下:

    <Page.DataContext>
        <Binding Path="Main" Source="{StaticResource Locator}"></Binding>
    </Page.DataContext>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"></RowDefinition>
            <RowDefinition Height="Auto"></RowDefinition>
        </Grid.RowDefinitions>
        <TextBlock Text="{Binding Title}"></TextBlock>
        <Button Grid.Row="1" Command="{Binding ChangeTitleCommand}">Click Me!</Button>
    </Grid>

  至此,一个简单的使用了MvvmLight框架的Uinversal App就完成了。

  按下Ctrl+F5,一个Win10风格的窗体就出现了。(细心的童鞋会发现Button默认不再撑开了)

  当然本篇不会只有这点东西,我们会进一步介绍MvvmLight框架在Universal App下的使用。

  接下来我们增加第二个页面,来看一下MvvmLight对页面间导航的支持。

  第一步新建PageTwoViewModel类:

    public class PageTwoViewModel
    {
        private INavigationService _navigationService;

        public ICommand GoBackCommand { get; set; }

        public PageTwoViewModel(INavigationService navigationService)
        {
            _navigationService = navigationService;
            GoBackCommand = new RelayCommand(()=> { _navigationService.GoBack(); });
        }
    }

  INavigationServiceMvvmLight为了抽象各类型的工程(WPF,Silverlight,Windows Runtime)不同的导航方法,而设计的接口,定义如下:

    public interface INavigationService
    {
        string CurrentPageKey { get; }

        void GoBack();

        void NavigateTo(string pageKey);

        void NavigateTo(string pageKey, object parameter);
    }

  通过string字符串确认唯一页面来进行跳转和返回,并可以传递object类型的参数。

  ViewModelLocator类注册PageTwoViewModel,以及创建INavigationService的实例并关联各Page

        public ViewModelLocator()
        {
            ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
            SimpleIoc.Default.Register<MainViewModel>();
            SimpleIoc.Default.Register<PageTwoViewModel>();

            var navigationService = this.CreateNavigationService();
            SimpleIoc.Default.Register<INavigationService>(() => navigationService);
        }

        private INavigationService CreateNavigationService()
        {
            var navigationService = new NavigationService();
            navigationService.Configure("MainPage", typeof(MainPage));
            navigationService.Configure("PageTwo", typeof(PageTwo));

            return navigationService;
        }

        public MainViewModel Main
        {
            get
            {
                return ServiceLocator.Current.GetInstance<MainViewModel>();
            }
        }

        public PageTwoViewModel PageTwo
        {
            get
            {
                return ServiceLocator.Current.GetInstance<PageTwoViewModel>();
            }
        }
    }

  至于为什么只要在PageTwoViewModel的构造函数参数中带有INavigationService,即可由IOC自动获取实例navigationService则超出了本文讨论的范围,有兴趣的同学自行学习。

  构建PageTwo.xaml页面并关联至PageTwoViewModel

    <Page.DataContext>
        <Binding Path="PageTwo" Source="{StaticResource Locator}"></Binding>
    </Page.DataContext>
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"></RowDefinition>
                <RowDefinition Height="Auto"></RowDefinition>
            </Grid.RowDefinitions>
            <TextBlock Text="Page Two"></TextBlock>
            <Button Grid.Row="1" Command="{Binding GoBackCommand}">Go Back</Button>
        </Grid>
    </Grid>

  修改MainViewModel类,增加GotoNextCommand等方法。同时我们可以看到手动获取navigationService对象的方法。

    public class MainViewModel : ViewModelBase
    {
        private string title;

        public string Title
        {
            get { return title; }
            set { Set(ref title , value); }
        }

        public ICommand ChangeTitleCommand { get; set; }

        public ICommand GotoNextCommand { get; set; }

        public MainViewModel()
        {
            Title = "Hello World";
            ChangeTitleCommand = new RelayCommand(ChangeTitle);
            GotoNextCommand = new RelayCommand(GotoNext);
        }

        private void GotoNext()
        {
            var navigationService = ServiceLocator.Current.GetInstance<INavigationService>();
            navigationService.NavigateTo("PageTwo");
        }

        private void ChangeTitle()
        {
            Title = "Hello MvvmLight";
        }
    }

  MainPage.xaml仅仅是增加了一个GotoNextButton

<Button Grid.Row="2" Command="{Binding GotoNextCommand}">Go to Next!</Button>

  大功告成,按下Ctrl+F5试试吧。

  使用MvvmLight框架中的INavigationService来进行页面导航,虽然相对使用Frame导航稍稍增加了工作量,但具有以下几点好处:

  1.   不依赖具体的工程实现(WPF,Sliverlight,Windows Runtime)
  2.   ViewViewModel不直接产生依赖,双方通过中介INavigationService打交道。也就是说ViewModel中不会出现Windows.UI.Xaml.Controlsnamespace
  3.   将跳转的实现代码从View转移到ViewModel,使得单元测试可以脱离View,完全的通过ViewModelUT即可测试跳转的逻辑。

 

 

 

 

 

 

免责声明:文章转载自《MvvmLight框架使用入门(三)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇【转】预装Win8/8.1 中文版系统升级为专业版或专业版含媒体中心版的简单方法Ubuntu 修改sudoers之后无法用sudo怎么恢复下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

随便看看

Hibernate 数据的批量插入、更新和删除

对于这个批处理场景,Hibernate提供了一个批处理解决方案。接下来,我们将从批插入、批更新和批删除三个方面介绍如何处理此批处理场景。为了避免这种情况,Hibernate为批量更新和批量删除提供了类似于SQL的HQL语法。...

Jmeter中获取返回结果中的值

在jmeter的测试中,通常需要在下一个请求中使用上一个请求的返回值。如何获得返回值非常重要。插件下载地址为:http://jmeter-plugins.org/wiki/JSONPathExtractor/下载后,将lib文件夹放在jmeter目录中。...

安装gulp教程(整理)

所以安装nodejs。...

H3C系列之三层交换机系统版本升级

本文中涉及的硬件和软件交换机:H3CS3600-28TP-SItftp软件:tftpd32软件升级文件:S36SI_ E-CMW310-R1702P44.zip升级文件描述如下:S36SI_ E-CMW310-R1702P44-S168.bin168-bitSSH加密应用程序S3600_ V606.btmbootrom(downloadedynetworkp...

uniapp安卓真机调试提示检测不到手机【解决办法】

以下是具体的解决方案:步骤1:打开、查找、单击并单击7次或更多次,以允许开发人员进行选择。...

Linux(debian7)操作基础(四)之CPU频率调整 Linux系统CPU频率调整工具使用

在Linux中,内核的开发人员定义了一组框架模型,以实现动态调整CPU频率的目的,这就是CPUFreq系统。交互式:交互式模式,直接连接到最高频率,然后CPU负载缓慢降低,导致相对较高的功耗。Interactive根据计划的CPU数量来调整频率,以节省电力。InteractiveX根据CPU负载调整CPU频率,而不会过度降低频率。用户空间:用户定义的模式。该...