MvvmCrossはMVVMで開発するために最近良く使われるフレームワークですが、outoloadのような挙動の部分があって戸惑うことがあります。
公式のサンプルなども、説明がWindowsストアプリ、Windows Phone、Androidなど入り混じるため理解しづらい面もあります。
今回はシンプルにWindowsストアアプリにMVVMCrossを導入し、ページ遷移を行うまでを紹介します。
新規プロジェクトから「空のアプリケーション(Windows)」を作成します。
MvvmCrossは共通部分をPCL(Portable Class Library)として実装する想定でサンプルが書かれていることが多いです。
必ずしもそうする必要はありませんが、今回も今後Windows PhoneやXamarinのプロジェクトを追加することを想定してPCLで作成します。
PCLはソリューションエクスプローラーでソリューションを選択した状態で、右クリック→「追加」→「新しいプロジェクト」をクリックして追加します。
「新しいプロジェクトの追加」ポップアップの左ナビ「Visual C#」を選択した状態で、中央のリストから「クラスライブラリ(ポータブル)」を選択します。
プロジェクト名を「{プロジェクト名}.Core」とつけます。これは作法的なもので名前は任意で構いません。
PCLで対応するプロジェクトを選択します。
現時点でWindows Phone 8.1はMvvmCrossに対応していませんが、追加しておきます(現時点では、エラーが出るので、後で外し方を説明します)。
OKボタンを押してPCLの作成を完了します。
Windowsストアアプリ側の参照にPCLプロジェクトを追加しておきます。
WindowsストアアプリとPCLそれぞれにNuGetからMvvmCrossを追加します。
PCLのプロジェクト名から右クリック→「NuGetパッケージの管理」をクリックします。
「NuGetパッケージの管理」ウィンドウの右上の検索窓に「MVVMCross」と入力します。
検索結果の一覧から「MvvmCross」を選択、右端の「インストール」をクリックします。
(最低限の導入であればMvvmCross – Hot Tuna MvvmCross Librariesで良いのですが、上記の場合ドキュメントやサンプルコードを導入してくれます)
現時点では以下のようにエラー出ます。
これはWindows Phone 8.1のプロジェクトが今のところMvvmCrossに対応していないためです。
エラーを解消するために、PCLのプロジェクト名を右クリック→「プロパティ」を選択します。
ターゲット欄の「変更」をクリックしてWindows Phone 8.1のチェックを外します。
再度、NuGetからMvvmCrossを追加します。
同じくWindowsストアアプリにもNuGetからMvvmCrossを追加します。
これで準備は完了です。
まずはViewファイルを追加します。
ViewファイルはWindowsストアアプリ側のプロジェクトに追加します。
基本、Viewはとそれぞれのプロジェクト。ViewModelとModelはPCLというのがセオリー(というか理想?)です。
ViewはViewsというフォルダに「{ページ名}View」という命名規則で作成します。
サンプルとしてFirstView.xamlというファイルが既存として追加されていますが、今回はあえて新規に作成します。
MainPageView.xamlというファイルをViewsフォルダ以下に作成してください(ページのタイプは説明では「空白のページ」を選びますがどれでも構いません)。
MainPageView.xamlを以下のように書き換えます。
<mvvm:MvxStorePage x:Class="MvvmCrossPageNaviSample.Views.MainPageView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:MvvmCrossPageNaviSample.Views" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mvvm="using:Cirrious.MvvmCross.WindowsStore.Views" mc:Ignorable="d"> <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <Button Command="{Binding pageNavigate}" Content="Button" HorizontalAlignment="Left" Margin="321,206,0,0" VerticalAlignment="Top"/> </Grid> </mvvm:MvxStorePage>
トップレベルのタグがPageからMvxStorePageに変更されている点と、xmlnsにmvvmという名前空間が追加されているのがポイントです。
ButtonにCommandが指定されているのも覚えておきましょう。
続いてMainPageView.xaml.csも編集します。
using Cirrious.MvvmCross.WindowsStore.Views; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.InteropServices.WindowsRuntime; using Windows.Foundation; using Windows.Foundation.Collections; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Controls.Primitives; using Windows.UI.Xaml.Data; using Windows.UI.Xaml.Input; using Windows.UI.Xaml.Media; using Windows.UI.Xaml.Navigation; // 空白ページのアイテム テンプレートについては、http://go.microsoft.com/fwlink/?LinkId=234238 を参照してください namespace MvvmCrossPageNaviSample.Views { /// <summary> /// それ自体で使用できる空白ページまたはフレーム内に移動できる空白ページ。 /// </summary> public sealed partial class MainPageView : MvxStorePage { public MainPageView() { this.InitializeComponent(); } } }
Pageクラスを継承していたものをMvxStorePageを継承した形に書き換えてあります。
続いてViewModelを追加します。
ViewModelはPCLプロジェクトの方にViewModelsというフォルダを作成してそこに追加していきます。
ViewModelは上記フォルダに「{ページ名}ViewModel.cs」という命名規則で追加してください。
今回はMainPageViewModel.csというファイルを作成します。
作成後、ソースを以下のように書き換えます。
using Cirrious.MvvmCross.ViewModels; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Input; namespace MvvmCrossPageNaviSample.Core.ViewModels { class MainPageViewModel : MvxViewModel { private MvxCommand _pageNavigate; public ICommand pageNavigate { get { _pageNavigate = new MvxCommand(_navigate); return _pageNavigate; } } private void _navigate() { ShowViewModel<FirstViewModel>(); } } }
MvxViewModelクラスを継承しているのと、ページ遷移用のCommandが追加されています。
6.残り調整
Windowsストアアプリプロジェクト側のApp.xaml.csのOnLaunchedメソッドの以下の行を削除、
rootFrame.Navigate(typeof(MainPage), e.Arguments);
かわりに以下を追加します。
var setup = new Setup(rootFrame); setup.Initialize(); var start = Cirrious.CrossCore.Mvx.Resolve<Cirrious.MvvmCross.ViewModels.IMvxAppStart>(); start.Start();
PCLプロジェクト側のApp.csの以下の行を書き換えます。
RegisterAppStart<ViewModels.FirstViewModel>();
を、以下に、
RegisterAppStart<ViewModels.MainPageViewModel>();
これはスタートページがMainPageだということを表しています。
最後にデバッグそて動作を確認します。
Buttonと書かれたボタンをクリックすると別のページ(FirstPage)に遷移すれば成功です。
今回のポイントを紹介します。
まず、MvvmCrossを利用するにはViewやViewModelを命名規則に則ったファイル名、フォルダに配置することで自動で読み込まれること。
MVVMで開発経験のある方なら、今回の処理でDataContextにViewModelを代入する処理がなかったことにお気づきかと思います。
ボタンイベントはCommandで送り、ページ遷移はShowViewModel<遷移したいページのViewModel>という形で指定した点です。
このへんの動きを知っておくと、MvvmCrossのソースコードが読みやすくなると思います。
今回のコードはGitHubにアップロードしてありますので、コードを触りながら確認したいという方はDLしてみてください。
Please give us your valuable comment