Skip to content

アプリ内テーマのすすめ

Windows Phone Advent Calendar 20日目の記事です。

■はじめに
 Windows Phoneのアプリケーションに、アプリ内テーマを適用する方法を紹介します。参考文献はコチラです。
 
 複数の画面を持つアプリケーションで、各画面に配置しているボタンやチェックボックスなどの配色をカスタマイズしつつ、全体で統一したいということがあります。画面毎/コントロール毎にプロパティを編集してもできますが、色味を変えたくなった時に、その都度すべてのコントロールのプロパティを編集しなければならないのは大変なことです。
  
 Androidは自身のアプリケーションの外観を統一させるために、Style Resourceという機能があります(Android UI前身のSWINGがその機能を持っており、それを継承していると思われます)。Style Resourceにデザイン要素を定義し、それを参照している画面はStyle Resourceのデザイン定義に従って描画を行います。
 
 Windows Phoneで同じことができないかと調べたところ、冒頭の文献を見つけました。

■開発手順

  1. アプリ内テーマを適用したいプロジェクトに「Theme」フォルダを追加します。
    screen1

  2. Themeフォルダに「System.Windows.xaml」と「ThemeResources.xaml」を追加します。
    screen2
    ファイルは以下からダウンロードしてください。
    System.Windows.xaml
    ThemeResources.xaml

  3. 「System.Windows.xaml」と「ThemeResources.xaml」のビルドアクションを「Resource」に設定します。
    screen3

  4. App.xamlを編集します。
    1
    2
    3
    4
    5
    6
    7
    8
    
    <!--アプリケーション リソース-->
    <Application.Resources>
      <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
          <ResourceDictionary Source="Theme/System.Windows.xaml"/>
        </ResourceDictionary.MergedDictionaries>
      </ResourceDictionary>
    </Application.Resources>
  5. App.xaml.csを編集します。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    
    using System.Collections;
     
    public App()
    {
      ...
      InitializeComponent();
     
      // 以下を追加する
      MergeCustomColors();
     
      InitializePhoneApplication();
      ...
    }
     
    // テーマをマージするロジック
    private void MergeCustomColors()
    {
      var dictionaries = new ResourceDictionary();
     
      // TODO:自身のアプリケーション名に合わせること
      string source = @"/InAppTheme;component/Theme/ThemeResources.xaml";
     
      var themeStyles = new ResourceDictionary { Source = new Uri(source, UriKind.Relative) };
      dictionaries.MergedDictionaries.Add(themeStyles);
     
      ResourceDictionary appResources = App.Current.Resources;
      foreach (DictionaryEntry entry in dictionaries.MergedDictionaries[0])
      {
        SolidColorBrush colorBrush = entry.Value as SolidColorBrush;
        SolidColorBrush existingBrush = appResources[entry.Key] as SolidColorBrush;
        if (existingBrush != null && colorBrush != null)
        {
          existingBrush.Color = colorBrush.Color;
        }
      }
    }
  6. ThemeResources.xaml を編集します。配色を変更したいものだけを残して残りはコメントアウトすると良いようです。今回は
    PhoneAccentBrush
    PhoneForegroundBrush
    PhoneRadioCheckBoxCheckBrush
    の3つをカスタマイズしてみました。

    1
    2
    3
    4
    5
    6
    7
    8
    
    <Color x:Key="PhoneAccentColor">#FFF5B80C</Color>
    <SolidColorBrush x:Key="PhoneAccentBrush" Color="{StaticResource PhoneAccentColor}"/>
     
    <Color x:Key="PhoneForegroundColor">#FF86FF02</Color>
    <SolidColorBrush x:Key="PhoneForegroundBrush" Color="{StaticResource PhoneForegroundColor}"/>
     
    <Color x:Key="PhoneRadioCheckBoxCheckColor">#FFF50CD8</Color>
    <SolidColorBrush x:Key="PhoneRadioCheckBoxCheckBrush" Color="{StaticResource PhoneRadioCheckBoxCheckColor}"/>
  7. ビルド、実行すると以下のようになりました。
    screen4

■所感
 簡単な手順でテーマが設定できました。テーマで配色が管理できるのはとても便利ですね!しかし配色をあまりに変更してしまうと、他のアプリケーションと見栄えがかけ離れてしまい、エンドユーザーにそぐわないアプリケーションになり兼ねません。コーポレートカラー/ブランドカラーなどワンポイントに留める方がよさそうな気がしました。

 ただし、アクセシビリティへの対応には結構使えるんじゃないでしょうか。このBlog執筆時点でWindows Phoneはアクセシビリティ対応に不十分で、色弱などの視覚障がい者に優しくないアプリケーションがあるかもしれません。そのような方向けの配色を考慮したアプリケーションを作成するときに、役立つと思います。

ソースコードはこちら
InAppTheme.zip