かずきのBlog@hatena

日本マイクロソフトに勤めています。XAML + C#の組み合わせをメインに、たまにASP.NETやJavaなどの.NET系以外のことも書いています。掲載内容は個人の見解であり、所属する企業を代表するものではありません。

Universal Windows Platform版PrismのPrerelease版が出ました

github.com

朝起きてみるとできてました。 NuGetじゃなくてMygetっていうのにホストされてるので、使うためにひと手間必要です。

パッケージソースの追加

以下のURLをNuGetのパッケージソースに追加します。

https://www.myget.org/F/prismprerelease/api/v3/index.json

f:id:okazuki:20150928081219p:plain

プロジェクトにパッケージの追加

UWPのプロジェクトを作ってPrism.WindowsとPrism.Unity.Windowsをプロジェクトに追加します。

Appクラスのベースクラスを変更

Prism.Unity.Windows.PrismUnityApplicationを継承するように書き換えます。 OnLauncheApplicationAsyncメソッドをオーバーライドしてMainPageに遷移する処理を書いてみました。

using Prism.Unity.Windows;
using System.Threading.Tasks;
using Windows.ApplicationModel.Activation;

namespace App35
{
    /// <summary>
    /// 既定の Application クラスを補完するアプリケーション固有の動作を提供します。
    /// </summary>
    sealed partial class App : PrismUnityApplication
    {
        /// <summary>
        /// 単一アプリケーション オブジェクトを初期化します。これは、実行される作成したコードの
        ///最初の行であるため、main() または WinMain() と論理的に等価です。
        /// </summary>
        public App()
        {
            this.InitializeComponent();
        }

        protected override Task OnLaunchApplicationAsync(LaunchActivatedEventArgs args)
        {
            this.NavigationService.Navigate("Main", null);
            return Task.CompletedTask;
        }
    }
}

XAML側もPrismUnityApplicationに書き換えます。

<prism:PrismUnityApplication x:Class="App35.App"
                             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                             xmlns:prism="using:Prism.Unity.Windows"
                             xmlns:local="using:App35"
                             RequestedTheme="Light">

</prism:PrismUnityApplication>

ページの作成

最初からあるMainPageは削除してViews名前空間にMainPageを作成しました。 今までのストアアプリ版のPrismではPageをVisualStateAwarePageを基本クラスにするように書き換えてましたが、これが不要になりました。Pageクラスのままでいいです!これはポイント大きいですね。

VisualStateAwarePageが提供していた画面サイズに応じてVisualStateを切り替える機能はAdaptiveTriggerでできるようになったので妥当だと思います。VisualStateAwarePageの提供していたもう1つの機能のSessionStateの保存機能がほしい場合はPrism.Windows.Mvvm.SessionStateAwarePageを継承するようにPageを書き換えることで利用可能です。

なので、PageにはViewModelLocatorのAutoWireViewModelプロパティをつけるだけでよくなりました。

<Page x:Class="App35.Views.MainPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:local="using:App35.Views"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      xmlns:mvvm="using:Prism.Windows.Mvvm"
      mvvm:ViewModelLocator.AutoWireViewModel="True"
      mc:Ignorable="d">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    </Grid>
</Page>

ViewModelの作成

次はViewModelです。こいつはViewModelBaseクラスを継承するだけでOK。とりあえずHello world返すプロパティ作ってみました。画面遷移をViewModelでハンドリングするためのOnNavigatedToメソッドとOnnvigationFromメソッドも健在です。(こいつはオーバーライド必須じゃないので必要なときだけオーバーライドすればいい)

using Prism.Windows.Mvvm;
using Prism.Windows.Navigation;
using System.Collections.Generic;
using System.Diagnostics;

namespace App35.ViewModels
{
    public class MainPageViewModel : ViewModelBase
    {
        private string message = "Hello world";

        public string Message
        {
            get { return this.message; }
            set { this.SetProperty(ref this.message, value); }
        }


        public override void OnNavigatedTo(NavigatedToEventArgs e, Dictionary<string, object> viewModelState)
        {
            base.OnNavigatedTo(e, viewModelState);
            Debug.WriteLine("MainPageにきた");
        }

        public override void OnNavigatingFrom(NavigatingFromEventArgs e, Dictionary<string, object> viewModelState, bool suspending)
        {
            base.OnNavigatingFrom(e, viewModelState, suspending);
            Debug.WriteLine("MainPageから去る");
        }
    }
}

コンパイル時バインディング

コンパイル時バインディングをするために、MainPageにDataContextをキャストして公開するプロパティをつけます。

using App35.ViewModels;
using Windows.UI.Xaml.Controls;

// 空白ページのアイテム テンプレートについては、http://go.microsoft.com/fwlink/?LinkId=234238 を参照してください

namespace App35.Views
{
    /// <summary>
    /// それ自体で使用できる空白ページまたはフレーム内に移動できる空白ページ。
    /// </summary>
    public sealed partial class MainPage : Page
    {
        public MainPageViewModel ViewModel => this.DataContext as MainPageViewModel;

        public MainPage()
        {
            this.InitializeComponent();
        }
    }
}

そして、メッセージを表示するためのTextBlockをページにおいてHello worldの完成です。

<Page x:Class="App35.Views.MainPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:local="using:App35.Views"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      xmlns:mvvm="using:Prism.Windows.Mvvm"
      mvvm:ViewModelLocator.AutoWireViewModel="True"
      mc:Ignorable="d">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <TextBlock Text="{x:Bind ViewModel.Message}"
                   Style="{StaticResource BodyTextBlockStyle}" />
    </Grid>
</Page>

実行して動作確認

Hello worldってちゃんと出てますね。

f:id:okazuki:20150928082532p:plain

感想

Pageクラスの差し替えが必須じゃなくなってるので、とても使い勝手がよくなってます。 早く正式版が出てほしいですね。