かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

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