SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

UWPアプリ開発の最前線

XAMLで条件分岐
~UWPの複数バージョンに対処する「条件付きXAML」

UWPアプリ開発の最前線 第1回

  • X ポスト
  • このエントリーをはてなブックマークに追加

条件付きXAMLの書き方

文法

 条件付き名前空間の書式は、次のようになります。

条件付き名前空間の書式
xmlns:{条件付き名前空間名}="http://schemas.microsoft.com/winfx/2006/xaml/presentation?{条件式}"

ただし、{条件式}は次のいずれか

肯定式:
IsApiContractPresent({コントラクト識別名}, {コントラクト バージョン番号})
IsTypePresent({UIコントロールの型名})
IsPropertyPresent({UIコントロールの型名},{プロパティ名})

否定式:
IsApiContractNotPresent({コントラクト識別名}, {コントラクト バージョン番号})
IsTypeNotPresent({UIコントロールの型名})
IsPropertyNotPresent({UIコントロールの型名},{プロパティ名})

 上で、コントラクト識別名というのは正式には「APIコントラクト」(API contract)と呼ぶようです。一般的にはWindows.Foundation.UniversalApiContract(UWPの共通API)だけで事足りるでしょう。そのほかにも、Windows.ApplicationModel.Calls.CallsVoipContractやデスクトップ エクステンションのWindows.ApplicationModel.Activation.ActivatedEventsContractなどなど、多数のコントラクトが定義されています。APIコントラクトの一覧は、Device Family Extension SDKs and API contractsをご覧ください。

 一般的に使うWindows.Foundation.UniversalApiContractコントラクトのバージョン番号と、Windows 10のバージョン/ビルドの関係を次の表に示しておきます。

UniversalApiContractコントラクトとWindows 10のバージョン
コントラクト番号 Windows 10のバージョン/ビルド
1 1507/10240
2 1511/10586
3 1607/14393
4 1703/15063
5 1709/16299

 先に示した例では、contract5Presentというのは1709/16299以上の場合、contract5NotPresentは1709/16299未満の場合という意味になります。

 また、書式説明中の「UIコントロールの型名」というのは、名前空間を付けたクラス名です。後述の例を見ていただくと分かるかと思います。

IDEサポート

 条件付き名前空間の記述は、長くて面倒ですね。Visual Studio 2017は、コントラクトによる条件付き名前空間を自動生成してくれます。

 XAMLに、プロジェクトに指定した最小バージョンのWindows 10では利用できないUIコントロールを記述すると、次の画像のように警告(青い波線)が出るとともに、「電球マーク」が出てきます(表示されないときは[Ctrl]+[.])。電球マークを展開すると条件付き名前空間の提案が表示されるので、[Enter]キーを押すとその条件付き名前空間がPageタグに挿入されます。

条件付き名前空間の自動生成
Visual Studio 2017による条件付き名前空間の自動生成サポート

 自動生成される条件付き名前空間は肯定式だけですが、否定式も必要なときはコピー&ペーストしてNotを書き加えてやればよいです(条件付き名前空間名と条件式の2箇所)。

 最もよく使うと思われるコントラクトによる条件付きXAMLは、このようにIDEがサポートしてくれます。上で条件付き名前空間の書式を説明しましたが、きっちり覚えていなくてもそんなに困ることはないでしょう。

Windows 10のバージョンで使い分ける例

 コントラクト(Windows 10のバージョン)による条件付き名前空間をプロパティに適用する例は、最初に示しました(アクリル効果の有無)。今度は、UIコントロールそのものの有無を切り分けてみましょう(⇒Page2.xaml)。

 ColorPickerコントロールは1709/16299で導入された新しいUIコントロールです。それ以前のWindows 10で実行されたときにはColorPickerコントロールの代わりにComboBoxコントロールを表示するようにするには、次のXAMLのようにします。

UIコントロールを条件付きXAMLで使い分ける例(その1)
<Page
  ……省略……
  
  xmlns:contract5Present="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractPresent(Windows.Foundation.UniversalApiContract,5)"
  xmlns:contract5NotPresent="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractNotPresent(Windows.Foundation.UniversalApiContract,5)"
  
  >

  ……省略……

    <contract5Present:ColorPicker x:Name="colorPicker"
       Grid.Column="1" VerticalAlignment="Center"
       Color="{x:Bind SampleData.SampleColor, Mode=TwoWay}"/>

    <contract5NotPresent:ComboBox x:Name="colorComboBox"
        PlaceholderText="Pick a color" Grid.Column="1" VerticalAlignment="Center"
        SelectionChanged="colorComboBox_SelectionChanged">
      ……省略……
    </contract5NotPresent:ComboBox>

  ……省略……

 条件付き名前空間の定義は、最初の例と同じです。条件付き名前空間の適用先が、この例ではUIコントロールになっています。UWP APIのコントラクトが5(すなわち、Windows 10 1709/16299)またはそれ以降で実行されたときは、contract5Presentを付けたColorPickerコントロールがインスタンス化されます。コントラクトが5未満のWindows 10で実行されたときは、contract5NotPresentを付けたComboBoxコントロールのインスタンスが生成されるのです(次の画像)。

1703で実行(ComboBox)
Windows 10 version 1703(build 15063)で実行:ComboBoxが表示される
1709で実行(ColorPicker)
Windows 10 version 1709(build 16299)で実行:ColorPickerが表示される

UIコントロールの有無で使い分ける例

 最後は、IsTypePresentIsTypeNotPresentを使ってUIコントロールの有無でXAMLを使い分ける例です(⇒Page3.xaml)。

 先ほどのColorPickerコントロールの例は、ColorPickerコントロール自体がサポートされているかどうかで切り分けても同じ結果が得られます。IsTypePresentIsTypeNotPresentを使って、次のXAMLのように書けます。

UIコントロールを条件付きXAMLで使い分ける例(その2)
<Page
  ……省略……
  
  xmlns:isColorPickerPresent="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsTypePresent(Windows.UI.Xaml.Controls.ColorPicker)"
  xmlns:isColorPickerNotPresent="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsTypeNotPresent(Windows.UI.Xaml.Controls.ColorPicker)"
  
  >

  ……省略……

    <isColorPickerPresent:ColorPicker x:Name="colorPicker"
      Grid.Column="1" VerticalAlignment="Center"
      Color="{x:Bind SampleData.SampleColor, Mode=TwoWay}" />

    <isColorPickerNotPresent:ComboBox x:Name="colorComboBox"
              PlaceholderText="Pick a color" Grid.Column="1" VerticalAlignment="Center"
              SelectionChanged="colorComboBox_SelectionChanged">
      ……省略……
    </isColorPickerNotPresent:ComboBox>

  ……省略……

 実行結果の画像は省略しますが、先ほどと同様になります。

 ColorPickerコントロールが使えるプラットフォーム(Windows 10 1709/16299またはそれ以降)では条件付き名前空間isColorPickerPresentが有効になるので、ColorPickerコントロールの方だけがインスタンス化されます。ColorPickerコントロールが使えないプラットフォームでは、逆にComboBoxコントロールだけがインスタンス化されるというわけです。

 なお、現時点(Visual Studio 2017 15.5)では、コントラクトによる条件付き名前空間ほどはIDEのサポートが充実していません。将来はサポートされるでしょうが、今のところは型による条件付き名前空間を自動生成してくれないようです。また、XAMLプレビューでは型による条件付き名前空間は無視され、XAMLエディターでは警告が出てしまうようです。

まとめ

 条件付きXAMLによって、新しいWindows 10で実行されているときだけ新しい機能(UIコントロールやプロパティ)を使い分けるということが、XAMLだけで簡単に記述できるようになりました。

 これからは、「以前のWindows 10もサポートしなけりゃならないから、新機能はちょっと……」とあきらめなくても良いのです。新しいWindows 10を使っているユーザーには、新しいUXを提供していきましょう!

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
UWPアプリ開発の最前線連載記事一覧

もっと読む

この記事の著者

biac(ばいあっく)

HONDA R&Dで自動車の設計をやっていた機械屋さんが、技術の進化スピードに魅かれてプログラマーに。以来30年ほど、より良いコードをどうやったら作れるか、模索の人生。わんくま同盟の勉強会(名古屋)で、よく喋ってたりする。2014/10~2019/6 Microsoft MVP (Windows Devel...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/10623 2018/01/25 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング