かずきのBlog@hatena

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

Visual Studio 2012 RCのMetro スタイル アプリのテンプレートを見てみる

Visual Studio 2012 RC + Windows 8 RPの環境をようやく整えて落ち着いてきた今日この頃です。マシン2台ともWindows 8 RPにしてしまいました。正式版が出たときにどうなることやらと思ってます。

Metro スタイル アプリのひな形

Visual Studio 2012 RCのMetro スタイル アプリのひな形ですがプロジェクトのCommonフォルダの下にいくつかクラスが定義されています。特に拘りがない限りは、これを使って作っていくのがVisual Studio 2012 RCの段階での一番お手軽な方法に見えます。ということで、このフォルダの中身をちょっと見てみようと思います。(わからなかったやつは除く)因みにBlank Appを選択するとCommonフォルダの下にはC#のコードは何も吐かれませんが、プロジェクトの空白のページ以外を追加しようとするとCommonフォルダの下に、ファイルを追加するか聞かれます。ここで「はい」を選択するとがっつりとファイルが追加されるので、こいつをつかえということなのでしょう。

作成されるファイル

それでは1つずつ見ていこうと思います。

BindableBase.cs

こいつは、INotifyPropertyChangedインターフェースの実装クラスになります。個人的にはBCLか、Visual Studioに同梱されてるアセンブリか何かに押し込んでほしいなと思ったりもするのですが、ソースコードで提供されるみたいです。何らかのMVVMフレームワークとかを使うのでなければ、画面にバインドするクラスは、このクラスを継承するようにしたらいいと思います。

C# 5.0の機能も使われていて、[CallerMemberName]属性をパラメータに指定してプロパティ名を文字列で指定しなくてもいいように作られています。例えば、バインド可能なNameプロパティを持ったPersonクラスは以下のように定義できます。

public class Person : BindableBase
{
    private string name;
    public string Name
    {
        get { return this.name; }
        set
        {
            // setterでSetPropertyを呼ぶだけ
            this.SetProperty(ref name, value);
        }
    }
}

さすがに自動プロパティみたいに簡略化はできませんが、今までプロパティ名を文字列で指定していたのに比べるとケアレスミスも減っていい感じです。このSetPropertyメソッドは以下のように定義されています。自作のクラスでも使えるシーンでは使ってもいいんじゃないかなと思います。因みに、SetPropertyメソッドの実装は以下のようになっています。

protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] String propertyName = null)
{
    if (object.Equals(storage, value)) return false;

    storage = value;
    this.OnPropertyChanged(propertyName);
    return true;
}

第三引数のpropertyNameがC# 5.0の新機能の1つである[CallerMemberName]属性によって修飾されています。これで、コンパイラが頑張って呼び出し元の名前を渡してくれるので人間が頑張らなくてもよくなってます。この機能地味に好きです。

Converter系

コンバータ系のクラスもいくつか生成されています。

BooleanNegationConverterクラス

名前の通りtrueをfalseにfalseをtrueに変換するコンバータです。

BooleanToVisibilityConverter

こちらもお馴染みBoolean型から、コントロールの表示・非表示を表すVisibility型に変換してくれます。なかったら必ず作るんじゃないかと思われるクラスなので、用意されてるのはありがたい気がします。

LayoutAwarePageクラス

このクラスは、かなりいろいろやってくれてます。

画面の表示系

画面のスナップやランドスケープ表示になったときに対応するVisualStateに切り替える処理がまず大事です。利用者は、Blendで定義されているVisualStateに見た目を設定するだけで、各状態の画面表示に対応できるようになっています。

画面の状態保持

そして、後述するSuspensionManagerと連携してページ単位のデータを保持する仕組みも用意してくれています。利用者は、LoadStateメソッドをオーバーライドして、Dictionaryから必要なページ単位の保存データを取得したり、SaveStateメソッドをオーバーライドしてDictionaryにページ単位の保存データを設定したりすることができます。

SuspensionManagerクラス

このクラスはVisual Studio 11 CP版の段階では、MSさんの公式サンプルに組み込まれていたクラスになります。こいつは、グローバルにアクセスできる便利な永続化可能な情報置き場として重宝します。あまり無秩序に使うと怖いことがおきると思うので、注意して使いましょう。

あとは、アプリがバックグラウンドに回った時にナビゲーションの履歴の保持や、SusupensionManagerクラスに登録されているデータを永続化したり、アプリの復帰時には復元処理をやってくれます。なので、利用者は、どんなデータをいつ、どこで詰めて、どういうときにデータの復元をするかということに専念できます。

StandardStyles.xaml

このxamlにはタイルやテキストの標準的なサイズやレイアウトのものが定義されています。まずは、見た目はここにあるものを使うようにするとMetroっぽい見た目を簡単に得ることができます。デザイン面などで差別化をはかりたい人は、ここにあるスタイルを継承してカスタマイズするか、気合を入れて1から作る感じになります。ただ、Metro デザインとして決められている部分(フォントサイズとか)もあるので、それらには従っておいたほうがいいでしょう。

謎いもの

以下のものは何かわかりません。

  • RichTextColumns.cs

まとめ

簡単にですが、どんなファイルがプロジェクトに含まれているのか見てみました。今後は、これらの挙動を理解して使っていこうかな〜というところなんですが、他のMVVM系ライブラリや、オレオレライブラリを作って、その上にアプリケーションを構築する人にとってはむしろ邪魔者なんじゃないだろうかと思うようなクラス群に仕上がってると思います。

ただ、初学者がとっかかりとしてとりあえず動くものを用意するためのセーフティネットとしてはいいものなのかなぁと感じています。もちろん、ここで定義されている機能があることを前提に、機能拡充をしたものをライブラリ化するというのもありだと思います。

とりとめもない文章になってしまいましたが、SuspensionManagerクラスよ、君だけは標準で入っててくれ。

以上