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