MvvmLight框架使用入门(三)

本文介绍了如何使用MvvmLight框架构建Windows10 Universal App,并演示了页面导航功能。通过具体步骤展示了如何设置ViewModel、使用INavigationService进行页面跳转。

本篇是MvvmLight框架使用入门的第三篇。从本篇开始,所有代码将通过Windows 10的Universal 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.xaml的Resources中添加对ViewModelLocator的引用:

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

这里需要注意保持namespace和ViewModel的namespace一致:xmlns:vm=”using:UniversalApp.ViewModel”
再下一步就是修改MainPage.xaml文件,将xaml的内容修改如下:

<Page.DataContext>
    <Binding Path="Main" Source="{StaticResource Locator}"/>
</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(); });
        }
    }

INavigationService是MvvmLight为了抽象各类型的工程(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}"/>    </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仅仅是增加了一个GotoNext的Button:

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

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

  1. 使用MvvmLight框架中的INavigationService来进行页面导航,虽然相对使用Frame导航稍稍增加了工作量,但具有以下几点好处:
  2. 不依赖具体的工程实现(WPF,Sliverlight,Windows Runtime)。
  3. View和ViewModel不直接产生依赖,双方通过中介INavigationService打交道。也就是说ViewModel中不会出现Windows.UI.Xaml.Controls的namespace。
  4. 将跳转的实现代码从View转移到ViewModel,使得单元测试可以脱离View,完全的通过ViewModel的UT即可测试跳转的逻辑。

原文地址:http://www.cnblogs.com/manupstairs/p/4928888.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值