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即可測試跳轉的邏輯。

 

 

 

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM