• MvvmLight框架使用入门(三)


    MvvmLight框架使用入门(三)

     

      本篇是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即可测试跳转的逻辑。
  • 相关阅读:
    基于Kibana的可视化监控报警插件sentinl入门
    es聚合学习笔记
    spark streaming基本概念一
    es实战一:基本概念
    访问者模式(Visitor Pattern)
    模板方法模式(Template Method Pattern)
    策略模式(Strategy Pattern)
    状态模式(State Pattern)
    观察者(Observer)模式
    备忘录模式(Memento Pattern)
  • 原文地址:https://www.cnblogs.com/Jeely/p/11077818.html
Copyright © 2020-2023  润新知