SlideShare ist ein Scribd-Unternehmen logo
1 von 388
Downloaden Sie, um offline zu lesen
1
かずきの UWP 入門
2
目次
1. 本書について........................................................................................................................ 10
2. Universal Windows Platform とは ....................................................................................... 10
2.1. UWP アプリまでの歴史............................................................................................... 11
2.1.1. .NET Framework 3.0 ............................................................................................ 11
2.1.2. Silverlight.............................................................................................................. 11
2.1.3. Windows Phone 7.x .............................................................................................. 11
2.1.4. Windows 8 ............................................................................................................ 12
2.1.5. Universal app........................................................................................................ 12
2.1.6. Universal Windows Platform ................................................................................ 12
2.2. 開発の前に ................................................................................................................... 12
2.3. デバイスファミリ ........................................................................................................ 13
2.4. アダプティブ UI........................................................................................................... 14
2.5. Hello world................................................................................................................... 14
2.5.1. 前準備................................................................................................................... 14
2.5.2. プロジェクトの作成 ............................................................................................. 15
2.5.3. 画面の作成............................................................................................................ 17
2.5.4. プログラムの実行................................................................................................. 21
2.5.5. まとめ................................................................................................................... 25
3. XAML................................................................................................................................... 25
3
4. UWP のコントロールの基本クラス..................................................................................... 30
4.1. DependencyObject....................................................................................................... 30
4.1.1. 依存関係プロパティ ............................................................................................. 31
4.1.2. 添付プロパティ..................................................................................................... 35
4.1.3. スレッド操作 ........................................................................................................ 36
4.2. FrameworkElement ...................................................................................................... 37
4.3. Control ......................................................................................................................... 39
4.4. ContentControl ............................................................................................................ 39
4.5. ItemsControl ................................................................................................................ 39
4.6. Panel ............................................................................................................................ 40
5. データバインディング ......................................................................................................... 41
5.1. 実行時データバインディング ...................................................................................... 41
5.2. コンパイル時データバインディング............................................................................ 48
6. アプリケーションライフサイクル ....................................................................................... 53
6.1. アプリケーションの起動シーケンス............................................................................ 53
6.2. サスペンド時の処理..................................................................................................... 55
6.3. サスペンドからの復帰 ................................................................................................. 56
6.4. アプリケーションライフサイクルに対応したサンプル............................................... 56
7. ローカルデータとローミングデータ ................................................................................... 61
7.1. ローカルアプリデータ ................................................................................................. 62
4
7.2. ローミングデータ ........................................................................................................ 65
7.3. 一時アプリデータ ........................................................................................................ 66
8. Advanced XAML .................................................................................................................. 66
8.1. Style.............................................................................................................................. 66
8.1.1. 定義済みのスタイル ............................................................................................. 69
8.2. アニメーション ............................................................................................................ 70
8.2.1. キーフレームを使ったアニメーション ................................................................ 75
8.2.2. ThemeAnimation.................................................................................................. 76
8.2.3. ThemaTransition.................................................................................................. 79
8.3. Visual State Manager.................................................................................................... 82
8.4. Behavior ....................................................................................................................... 90
8.4.1. インストール ........................................................................................................ 90
8.4.2. 組み込み Behavior ................................................................................................ 91
8.4.3. Behavior の使い方 ................................................................................................ 92
8.4.4. Behavior の作成.................................................................................................... 95
8.4.5. Behavior の細かい使い方 ................................................................................... 103
8.5. DataTemplate ............................................................................................................ 103
8.5.1. ContentControl 系での使用................................................................................ 103
8.5.2. ItemsControl 系での使用.................................................................................... 110
8.6. ControlTemplate........................................................................................................ 114
5
8.6.1. クリック可能なテキストの作成 ......................................................................... 114
8.6.2. コントロールの Visual State............................................................................... 116
9. 代表的なコントロール ....................................................................................................... 120
9.1. レイアウトパネル ...................................................................................................... 120
9.1.1. StackPanel .......................................................................................................... 120
9.1.2. Grid .................................................................................................................... 122
9.1.3. Canvas ................................................................................................................ 126
9.1.4. RelativePanel ...................................................................................................... 128
9.2. Border ........................................................................................................................ 131
9.3. TextBlock ................................................................................................................... 133
9.4. Button ........................................................................................................................ 135
9.5. TextBox...................................................................................................................... 138
9.6. CheckBox ................................................................................................................... 140
9.7. RadioButton ............................................................................................................... 141
9.8. RepeatButton ............................................................................................................. 145
9.9. ToggleSwitch.............................................................................................................. 147
9.10. ToggleButton ......................................................................................................... 149
9.11. ComboBox.............................................................................................................. 150
9.12. CalendarDatePicker ............................................................................................... 153
9.13. CalendarView ......................................................................................................... 156
6
9.14. DatePicker.............................................................................................................. 158
9.15. TimePicker............................................................................................................. 160
9.16. FlipView ................................................................................................................. 162
9.17. Frame ..................................................................................................................... 168
9.18. CommandBar ......................................................................................................... 170
9.19. ListView と GridView............................................................................................. 175
9.19.1. 選択項目の操作................................................................................................... 180
9.20. Image...................................................................................................................... 191
9.20.1. XAML 内での URL............................................................................................. 191
9.20.2. 画像の表示例 ...................................................................................................... 192
9.20.3. ユーザーの指定したファイルの表示.................................................................. 194
9.20.4. 画像の表示時の拡大方法方法............................................................................. 198
9.21. InkCanvas............................................................................................................... 200
9.21.1. ペン以外での入力の受け付け............................................................................. 201
9.21.2. ペンの色・太さを変える .................................................................................... 202
9.21.3. 文字認識 ............................................................................................................. 204
9.22. MapControl ............................................................................................................ 206
9.23. MediaElement ........................................................................................................ 215
9.24. Povot ...................................................................................................................... 217
9.25. PasswordBox .......................................................................................................... 221
7
9.26. ProgressBar ............................................................................................................ 223
9.27. ProgressRing .......................................................................................................... 225
9.28. ScrollViewer ........................................................................................................... 226
9.29. Slider ...................................................................................................................... 231
9.30. WebView ................................................................................................................ 232
9.31. AugoSuggestBox..................................................................................................... 237
9.32. SplitView ................................................................................................................ 248
9.32.1. ハンバーガーメニューの実装............................................................................. 249
10. 共有................................................................................................................................ 253
10.1.1. 共有の送信側の作成 ........................................................................................... 253
10.1.2. 共有の受信側の作成 ........................................................................................... 260
11. バックグラウンドタスク ............................................................................................... 265
11.1.1. バックグラウンドタスクの作成と登録 .............................................................. 265
11.1.2. バックグラウンドタスクとフォアグランドの連携 ............................................ 269
11.1.3. バックグラウンドタスクの追加情報.................................................................. 275
11.1.4. システムイベントへの応答 ................................................................................ 275
12. タイルとトースト .......................................................................................................... 276
12.1.1. タイルやトーストを作成するための補助ツール................................................ 276
12.1.2. ライブタイル ...................................................................................................... 278
12.1.3. セカンダリタイル............................................................................................... 281
8
12.1.4. トースト ............................................................................................................. 284
13. プッシュ通知.................................................................................................................. 293
14. コルタナ連携.................................................................................................................. 313
14.1.1. フォアグラウンドアプリの起動 ......................................................................... 313
14.1.2. バックグラウンドアプリの起動 ......................................................................... 323
15. アプリ間連携.................................................................................................................. 331
15.1. AppService.............................................................................................................. 331
15.2. 別アプリの起動 ...................................................................................................... 336
15.2.1. プロトコルによるアプリの起動 ......................................................................... 336
15.2.2. 結果を受け取るプロトコルによるアプリの起動................................................ 337
16. 複数デバイスに対応したアプリの作成.......................................................................... 339
16.1. アダプティブコード ............................................................................................... 339
16.2. アダプティブ UI..................................................................................................... 344
17. UserControl とテンプレートコントロール ................................................................... 349
17.1. UserControl............................................................................................................ 349
17.2. テンプレートコントロール .................................................................................... 353
18. UWP でのアプリの設計................................................................................................. 361
18.1. MVVM パターンとは............................................................................................. 361
18.2. Prism for Windows Runtime .................................................................................. 362
18.2.1. 足し算アプリの作成 ........................................................................................... 363
9
18.2.2. 基本的なクラスの使い方 .................................................................................... 378
19. まとめ ............................................................................................................................ 387
10
1. 本書について
本書は、Windows 10 で追加された Universal Windows Platform(以下 UWP)についての入門
書になります。以下の開発環境を前提としています。
1. Windows 10
2. Visual Studio 2015 Update 3
開発言語としては、XAML と C#を使用しています。本書では、C#の言語面での解説は行いま
せん。C#についての入門は別途書籍やサイトなどを参考にしてください。
また、UWP を実行する OS は以下のものを想定しています。
1. Windows 10
2. Windows 10 Mobile
2. Universal Windows Platform とは
UWP とは、Windows 10 で追加された、プラットフォームで以下の特徴を持ちます。
1. Windows 10 が動くすべてのデバイス上でワンバイナリでアプリが動く
(ア) Windows 10 の動くデスクトップ
(イ) Windows 10 の動くタブレット
(ウ) Windows 10 Mobile の動く電話
(エ) Surface Hub
(オ) HoloLens
(カ) Windows 10 IoT の動くラズベリーパイなどの IoT デバイス
2. Windows ストアで配布が可能
11
UWP 上で動くアプリのことを UWP アプリといいます。
2.1. UWP ア プ リ ま で の 歴史
ここで少し余談ですが、UWP アプリに至るまでの歴史を著者の主観が入った状態ですが少し
見ていきたいと思います。さかのぼれば何処までもさかのぼれますが、ここでは、.NET
Framework 3.0 で追加された WPF からの歴史を見ていきたいと思います。
2.1.1. .NET Framework 3.0
.NET Framework 3.0 で、Windows Presentation Foundation(以下 WPF)が追加されました。
これは、デスクトップアプリケーションを開発するためのプラットフォームで XAML(ザム
ル)と呼ばれる XML をベースとした言語で画面を構築して、C#でロジックを記述するという
開発スタイルが登場しました。この開発スタイルは、UWP でも受け継がれています。
2.1.2. Silverlight
次に、Rich Internet Application(以下 RIA)と呼ばれるキーワードが持てはやされた時代が来ま
す。この時は、現在のように HTML5 を中心とした開発ではなく Flash や Siliverlight と呼ばれ
るブラウザプラグイン上でアプリケーションを構築することが主流だったと私は感じていま
す。(HTML/CSS/JavaScript でも開発出来たが、今よりも凄く大変だった)
Silverlight は、勢いのあったころは WPF を駆逐するのではないかと錯覚させるほど、機能追加
が活発で、OutOfBrowser というブラウザプラグインなのに、サンドボックス内にありつつデ
スクトップアプリケーションのように動作するモードなども追加されました。UWP も大ざっ
ぱにみると、サンドボックスの中で動く XAML と C#によって開発されたアプリが動くという
ことで、とても似たような雰囲気があります。
2.1.3. Windows Phone 7.x
次に、Windows Phone です。これは、Silverlight がスマートフォンアプリとして動くという点
が特徴です。この時は、Silverlight がこのまま全プラットフォームにひろがっていくのではな
いかと感じていました。(現実はそうではありませんでしたが…)
12
2.1.4. Windows 8
Silverlight の波も去り、Microsoft がタッチファーストという考えで作り出し、世間的には
Vista 並みに失敗したと認識されている(私は好きですよ)Windows 8 が登場します。
Windows 8 では、ストアアプリと呼ばれる UWP の前身となるアプリケーションプラットフォ
ームが登場します。COM の上に構築された Windows Runtime 上で動くアプリケーションがこ
こで登場しました。Windows Runtime は、UWP でも使用されています。
2.1.5. Universal app
Windows 8.1 と Windows Phone 8.1 で 95%くらい API が共通化されて、ほぼ同一ソースで
Windows 8.1 上と Windows Phone 8.1 上で動くアプリケーションのバイナリを、それぞれ作成
することが出来るようになりました。ソースコードレベルとはいえ、同じコードが電話でもパ
ソコンでも動くという大きな衝撃を与えてくれたテクノロジです。
2.1.6. Universal Windows Platform
そして、UWP に繋がります。Universal app がソースコードの共有だったものを、UWP で
は、同一バイナリが Windows 10 の動く様々なデバイスで動くということを実現しました。開
発手法は、WPF が登場してから一貫して XAML と C#による開発です。
HoloLens への対応や Windows 10 への力の入れ具合などから、現在、そして今後も大きく
Microsoft が投資していくプラットフォームであることが伺えます。現に XAML などの開発言
語も WPF と比べて機能強化が積極的に行われています。本書では、この WPF から歴史を積み
上げて、現在の最新のプラットフォームである UWP についての開発について取り上げます。
2.2. 開 発 の前 に
UWP の開発の話しに入る前に、UWP のアプリの作法であるガイドラインを紹介しておきま
す。このガイドラインは、守らなければいけないというものではないですが、UWP のアプリ
を作る上で、よくあるナビゲーションパターンや画面パターンなど、多くの有益な情報が記載
されています。
13
是非、Windows ストアなどに提出するようなアプリを作る場合には一読しておくことをお勧め
しておきます。
Windows アプリ UX デザイン ガイドライン
https://msdn.microsoft.com/ja-jp/mt634411.aspx
上記ページの中にある、「Windows 10 アプリ UX デザイン ガイド」が、それになります。
2.3. デ バ イス フ ァ ミ リ
UWP を開発するうえで知っておいたほうがいい概念としてデバイスファミリというものがあ
ります。デバイスファミリとは、アプリが動作するプラットフォームのようなものです。
Universal app が Windows 8.1 と Windows Phone 8.1 などの OS を対象としていたのに対し
て、UWP ではデバイスファミリを対象とします。デスクトップパソコンでは、デスクトップ
デバイスファミリに基づいて実行し、モバイル端末ではモバイルデバイスファミリに基づいて
実行されます。ユニバーサルデバイスファミリと呼ばれる特別なデバイスファミリも存在し、
ユニバーサルデバイスファミリで提供される、API は、全てのデバイスファミリで動作するこ
とが保証されています。
デバイスファミリの関係をあらわした図を以下に示します。
各デバイスファミリには、プラットフォームに固有の API が提供されています。これらの API
は、実行時に動的に存在を確認して呼び出すアダプティブコードを記述することが出来ます。
デバイスファミリを選択するということは、呼び出せる API 群を決定するということです。先
ほども言った通り、アダプティブコードを記述することでデバイスファミリ固有の API を使用
しつつ、他のデバイスファミリ上でも動作させるといったことも出来るようになっています。
14
必要があれば、デスクトップデバイスファミリ上でしか動作させないといったことも可能で
す。
2.4. ア ダ プテ ィ ブ UI
UWP は、様々なデバイス上で動作するアプリケーションを、ワンバイナリで作ることが出来
ます。逆に言うと、ワンバイナリで様々な画面サイズで動作するアプリケーションを作らない
といけないということになります。このような要件に対応するため、アダプティブ UI を実現
しなければなりません。アダプティブ UI は、画面サイズに応じて最適な画面レイアウトを提
供する UI です。
以下のような小さなモバイル端末から、ホワイトボードサイズの Surface Hub まで様々なデバ
イスに対応する必要があります。
(https://msdn.microsoft.com/ja-jp/library/windows/apps/dn894631.aspx より引用)
アダプティブ UI のパターンについても、「開発の前に」で紹介したガイドラインに記載があ
りますので、併せて確認してみてください。
2.5. Hello world
最初の UWP アプリとして Hello world を作成してみましょう。ボタンを押すと、Hello world
というメッセージボックスが表示されます。
2.5.1. 前 準 備
UWP のアプリを開発するためには、Visual Studio 2015 のインストール時に UWP の開発環境
をインストールするように構成する必要があります。選択をせずに、インストールした場合は
15
コントロールパネルからプログラムの追加と削除を選んで、Visual Studio 2015 を選択して変更
を押してから、UWP の開発環境をインストールしてください。
また、最初にやる設定として、パソコンを開発者モードにする必要があります。設定(Win +
i)を表示して「更新とセキュリティ」を選んで、「開発者向け」を選択して「開発者モード」
にします。
2.5.2. プ ロ ジェ ク ト の 作 成
メニューの「ファイル」→「新規作成」→「プロジェクト」を選択して、「テンプレート」の
「Visual C#」の「Windows」の「ユニバーサル」にある「空白のアプリ(ユニバーサル
Windows)」を選択します。名前の項目に HelloWorld と入力して「OK」を選択してくださ
い。
16
動作対象とするターゲットプラットフォームと最小プラットフォームのバージョンの選択ダイ
アログが出てくるので、そのまま「OK」を選択してください。
作成が完了すると以下のようなプロジェクトが作成されます。
17
1. Assets フォルダ
インストール後のプログラムフォルダに表示されるアイコンや、タイルなどに表示される
アイコンが入っています。
2. App.xaml/App.xaml.cs
アプリケーションのエントリーポイントです。
3. ApplicationInsights.config
ApplicationInsights の構成ファイルです。プロジェクト新規作成時に ApplicationInsights
を使用しない構成にしていた場合は作成されません。無くても問題ありません。
4. HelloWorld_TemporaryKey.pfx
アプリケーションのインストールパッケージを作成するときに使用される鍵です。
5. MainPage.xaml/MainPage.xaml.cs
アプリケーション起動時に最初に表示される画面です。
6. Package.appxmanifest
アプリケーションのマニフェストファイルです。権限の設定などを行います。
7. project.json
NuGet のライブラリの依存関係が記載されています。
2.5.3. 画 面 の作 成
18
Hello world の画面を作成します。MainPage.xaml をダブルクリックして開くとデザイナが表示
されます。
デザイナの下部には、XAML と呼ばれる画面を記述する言語が表示されています。デザイナの
左側にツールボックスが表示されていて、そこにボタンなどの各種コントロールがあります。
19
ツールボックスから Button をデザイナにドラッグアンドドロップすることで、好きな場所に
ボタンを配置出来ます。
20
Button を選択した状態で、プロパティウィンドウを見ると Button の設定を変更できることが
わかります。Content プロパティに Say hello と入力すると Button のテキストが Say hello にな
ります。
21
Button をデザイナ上でダブルクリックすることで、Button がクリックされたときの処理が生
成されます。MainPage.xaml.cs が以下のようになります。
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
private void button_Click(object sender, RoutedEventArgs e)
{
}
}
このように XAML に紐づく C#のファイルをコードビハインドと言います。コードビハインド
に処理を書きましょう。button_Click メソッドを以下のように書き換えます。
private async void button_Click(object sender, RoutedEventArgs e)
{
var dialog = new MessageDialog("Hello world");
await dialog.ShowAsync();
}
MessageDialog は、名前空間がデフォルトで using されていないので、「Ctrl + .」を押して
using を追加してください。UWP の API は、非同期のものがほとんどです。少しでも処理に
時間がかかるものは全て非同期メソッドとして提供されています。async/await は頻繁に使うの
で、知らない方はマスターしておきましょう。
2.5.4. プ ロ グラ ム の 実 行
最後にプログラムの実行を行います。Visual Studio のツールバーを以下のように「x86」が選
択されていることを確認して「▶ローカルコンピューター」を選択します。
22
実行すると Button が置かれた Window が表示されます。Button をクリックすると以下のよう
にダイアログが表示されます。
続けて Windows 10 Mobile で動作させてみましょう。「▶ローカルコンピューター」の横の▼
をクリックすると以下のように動作対象のターゲットが選べます。
23
その中から、「Mobile Emulator 10.0.10586 WVGA 4 inch 512MB」(細かいバージョン番号
は異なっている可能性があります)を選択します。選択したあと、再度クリックすると
Windows 10 Mobile のエミュレータが起動して Hello world が実行されます。
24
Button をクリックすると、以下のようにダイアログが表示されます。
25
詳しい手順は紹介しませんが、CPU を「ARM」にして「▶Device」にすることで開発者モー
ドにした USB で接続された Windows 10 Mobile の実機にアプリを転送して動かすことが出来
ます。Windows 10 Mobile をお持ちの方は試してみてください。
2.5.5. ま と め
プロジェクトの作成から、アプリケーションの実行までを紹介しました。また、デザイナを使
って画面をデザイン出来ることや、C#を使って処理を書けることを示しました。そして、
UWP の醍醐味でもある、デスクトップとモバイルで同じアプリケーションが動くということ
も示しました。ちょっとした Hello world ですが、色々な物が詰まっています。
3. XAML
ここでは、UWP の画面構築に使用する XAML という言語についてみていきます。XAML は、
Hello world の章でデザイナの下に表示されていたもので、XML をベースにして作られた言語
になります。XAML は、画面構築専用の言語ではなくて、汎用的に使えるオブジェクトを組み
立てるための言語になります。ツリー構造を持ったオブジェクトの構築に必要な機能が色々詰
まっています。画面は、Page をルートとしたツリー構造のオブジェクトのため、XAML で記
述するのに、とても適している言語です。
XAML は、XML 名前空間を C#の名前空間に、タグをクラス名に、属性をプロパティ名に対応
させています。また、XML 名前空間には、いくつかの組み込みのものが定義されていて、それ
26
らには x や d や mc などの名前を付けることが一般的です。一般的な Page(UWP での画面を
あらわすクラス)の XAML での定義は以下のようになります。
<Page x:Class="XamlBasics.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
</Page>
4 つの XML 名前空間が定義されています。まずは、XAML で定義する名前空間と、様々な便
利機能が定義されている x 名前空間と、デザイナ向けの機能を提供する d 名前空間です。mc
名前空間は、mc:Ignorable で実行時には無視する名前空間を指定するために定義されていま
す。x:Class 属性は、コードビハインドクラスのクラス名をあらわしています。この、x:Class
属性で、XAML と裏のロジックのクラスの結び付けが行われています。この形が UWP で扱う
XAML の基本的な形になります。
この XAML に紐づくコードビハインドは、以下のようになっています。
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace XamlBasics
{
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
}
}
27
XAML のタグが Page タグなので、Page クラスを継承している点がポイントです。また、
XAML で定義された設定を有効化するために、コンストラクタで InitializeComponent メソッ
ドを呼び出している点もポイントになります。
以下に XAML の基本機能を使った XAML を示します。
<Page x:Class="XamlBasics.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:XamlBasics"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Page.Content>
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<Grid.Children>
<Button Content="Hello world"
Click="Button_Click" />
</Grid.Children>
</Grid>
</Page.Content>
</Page>
まず、Button タグに注目してみましょう。Button の Content 属性に Hello world を指定してい
ます。これは、Button クラスのインスタンスの Content プロパティに Hello world という文字
列を設定していることになります。このように、とても直感的に属性を使ってプロパティを設
定可能です。また、もう 1 つ Click 属性がありますが、こちらはイベントになります。イベン
トでは、コードビハインドで対応するメソッドの名前を定義することで、イベントに対してメ
ソッドを追加することが出来ます。
次に、Page と Grid の関係について注目してみましょう。先ほどの Button の例のように、単純
な文字列や数値の場合は属性を使ってプロパティの値を指定できますが、プロパティに設定し
たいものが Button や Grid といった他のクラスのインスタンスだった場合に、特別な命名規約
に沿ったタグを使うとプロパティを設定できます。命名規約は、「クラス名.プロパティ名」と
28
いうタグになります。このような命名規約のタグを使うことで、タグの子要素のオブジェクト
をプロパティに設定することができます。この構文のことを、「プロパティ要素の構文」とい
います。
次に、Grid の Background 属性で指定されている{}で囲まれた部分です。これは「マークアッ
プ拡張」といって単純な文字列では指定できないようなオブジェクトを設定するための構文に
なります。StaticResource は、後程説明しますが、UWP のリソースと呼ばれるところから、オ
ブジェクトを取得してきます。その他に{x:Null}などで null を渡すといったことも可能です。
次にコンテンツ構文です。コンテンツ構文は、オブジェクトに対して 1 つだけ指定可能なコン
テンツプロパティというものを、タグの直下に書くことでコンテンツプロパティに自動で設定
出来るものです。例えば、Page では Content プロパティがコンテンツプロパティに指定されて
います。また、Grid は Children プロパティがコンテンツプロパティに指定されています。そ
のため、先ほどの XAML は、以下のようにシンプルに記述できます。
<Page x:Class="XamlBasics.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:XamlBasics"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<Button Content="Hello world"
Click="Button_Click" />
</Grid>
</Page>
その他の構文として、コレクション構文というものがあります。例えば、Grid の Children
は、コレクション型なのですが、ここに複数のタグを追加するとコレクションに複数格納され
ます。例えば、Grid に Button を 2 つ以上置くことが出来ます。例えば以下のように書きま
す。
<Page x:Class="XamlBasics.MainPage"
29
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:XamlBasics"
xmlns:d=http://schemas.microsoft.com/expression/blend/2008tugini
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<Button Content="Hello world"
Click="Button_Click" />
<Button VerticalAlignment="Top"
Content="Button2" />
<Button VerticalAlignment="Bottom"
Content="Button3" />
</Grid>
</Page>
次に、任意の名前空間にあるオブジェクトを XAML に組み込む方法を紹介します。XAML
は、XML 名前空間を C#の名前空間と対応づけることができます。対応づけかたは、上記の
XAML 内の local という XML 名前空間にあるとおり、「using:名前空間」という形の書式にな
ります。例えば XamlBasics という名前空間に Person という名前のクラスがある場合、以下の
ように記述できます。
<local:Person />
次に、添付プロパティという機能を紹介します。添付プロパティは、名前の通りオブジェクト
自体には定義されていないプロパティを追加で設定できる機能になります。UWP 上では、主
にコントロールのレイアウトに必要な情報をコントロールに追加するために使用されていま
す。例えば、Grid コントロールは、行と列を指定してコントロールを何処に配置するのか指定
できるのですが、そこで、以下のように使用されています。
<Page x:Class="XamlBasics.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:XamlBasics"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
30
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<!-- 行の定義 -->
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<!-- Grid の 0 行目、1 行目に配置 -->
<Button Content="Layout sample"
Grid.Row="0" />
<Button Content="Hello world"
Grid.Row="1" />
</Grid>
</Page>
Button タグの Grid.Row という属性で指定している箇所が添付プロパティにあたります。
Button に Grid が持っている Row という添付プロパティの値を設定しています。このように、
他のクラスで定義されたプロパティの値を設定できる点が特徴になります。
最後に、マークアップ拡張について説明します。マークアップ拡張は、複雑なオブジェクトを
簡単に記述するための記法になります。{}で囲んで記述します。例えば{x:Null}とすることで、
null をあらわすことが出来ます。その他に、データバインディングの章で紹介しますが、
{Binding Path=Name}などのようなデータバインディングオブジェクトの生成や、リソースの
参照を行うための{StaticResource KeyName}のようなものがあります。マークアップ拡張のそ
れぞれの意味については、各章で後述します。
4. UWP のコントロールの基本クラス
ここでは、UWP のコントロールの基本クラスである、DependencyObject について説明を行い
ます。
4.1. DependencyObject
31
DependencyObject は、UWP のコントロールに必要な基本的な機能を提供します。提供する機
能は以下の通りです。
1. 依存関係プロパティ
2. 添付プロパティ
3. スレッド操作
順に説明していきます。
4.1.1. 依 存 関係 プ ロ パ テ ィ
依存関係プロパティは、Windows Runtime で使用される特殊なプロパティで、デフォルト値の
提供や、プロパティの値に変更があったときに別のプロパティへの値の伝搬や、アニメーショ
ンのサポートや、データバインディングのサポートなど様々な機能を持ったプロパティです。
具体的には、以下のように実装されます。
public class Range : Windows.UI.Xaml.DependencyObject
{
// プロパティのキー
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register("Value", typeof(int), typeof(Range), new PropertyMetadata(0,
ValueChanged));
// CLR のプロパティとしてラッピング
public int Value
{
get { return (int)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
private static void ValueChanged(Windows.UI.Xaml.DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
// 変更があったときの処理
32
}
}
まず、クラスが DependencyObject クラスを継承していることが必要となります。そして、
DependencyProperty クラスの Register メソッドで依存関係プロパティを登録します。引数
は、プロパティ名、プロパティの型、プロパティを所有する型、メタデータになります。メタ
データは、PropertyMetadata 型でコンストラクタの引数は、プロパティのデフォルト値と、プ
ロパティに変更があったときのコールバック(コールバックの指定はオプション)になりま
す。コールバックは、static なメソッドで、第一引数に値が変更されたオブジェクトと、プロ
パティの変更後の値と変更前の値を持ったイベント引数というシグネチャになります。依存関
係プロパティ自体には必須ではないのですが、CLR のプロパティの形(要は普通の C#のプロ
パティ)にラップするのが一般的です。こうすることで、コード上から自然にアクセスが可能
になります。CLR のプロパティの形式を使用しない場合と使用する場合のコードを以下に示し
ます。
var r = new Range();
// CLR のプロパティを使用しない場合
r.SetValue(Range.ValueProperty, 10);
var value = (int)r.GetValue(Range.ValueProperty);
// CLR のプロパティのラッパを使用する場合
r.Value = 100;
var value2 = r.Value;
依存関係プロパティの PropertyMetadata のコールバックを使うことで、プロパティの値に変更
があったときに、他のプロパティの値に状態を伝搬するなどの処理を書くことが出来ます。例
として Range クラスで、Min と Max プロパティを追加して、Value が必ず Min と Max の間に
あるように調整する処理を追加したコードを以下に示します。
public class Range : Windows.UI.Xaml.DependencyObject
{
// プロパティのキー
public static readonly DependencyProperty ValueProperty =
33
DependencyProperty.Register("Value", typeof(int), typeof(Range), new PropertyMetadata(0,
ValueChanged
public static readonly DependencyProperty MinProperty =
DependencyProperty.Register("Min", typeof(int), typeof(Range), new
PropertyMetadata(int.MinValue, Min
public static readonly DependencyProperty MaxProperty =
DependencyProperty.Register("Max", typeof(int), typeof(Range), new
PropertyMetadata(int.MaxValue, Max
// CLR のプロパティとしてラッピング
public int Value
{
get { return (int)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
public int Min
{
get { return (int)GetValue(MinProperty); }
set { SetValue(MinProperty, value); }
}
public int Max
{
get { return (int)GetValue(MaxProperty); }
set { SetValue(MaxProperty, value); }
}
// コールバック
private static void ValueChanged(Windows.UI.Xaml.DependencyObject d,
DependencyPropertyChangedEventArgs e
{
((Range)d).CourceValue();
}
34
private static void MinChanged(Windows.UI.Xaml.DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
((Range)d).CourceMin();
((Range)d).CourceValue();
}
private static void MaxChanged(Windows.UI.Xaml.DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
((Range)d).CourceMax();
((Range)d).CourceValue();
}
// 値を調整するメソッド
private void CourceMax()
{
if (this.Max < this.Min)
{
this.Max = this.Min;
}
}
private void CourceMin()
{
if (this.Min > this.Max)
{
this.Min = this.Max;
}
}
private void CourceValue()
{
if (this.Max < this.Value)
35
{
this.Value = this.Max;
}
if (this.Min > this.Value)
{
this.Value = this.Min;
}
}
}
このクラスを使って以下のようなコードを記述して動作を確認してみます。
var range = new Range();
Debug.WriteLine($"Min: {range.Min}, Max: {range.Max}, Value: {range.Value}");
range.Min = 0;
range.Max = 10;
range.Value = 100;
Debug.WriteLine($"Min: {range.Min}, Max: {range.Max}, Value: {range.Value}");
range.Max = -1;
Debug.WriteLine($"Min: {range.Min}, Max: {range.Max}, Value: {range.Value}");
実行するとデバッグ時の出力ウィンドウに以下の結果が表示されます。
Min: -2147483648, Max: 2147483647, Value: 0
Min: 0, Max: 10, Value: 10
Min: 0, Max: 0, Value: 0
4.1.2. 添 付 プロ パ テ ィ
次に、XAML でも紹介した添付プロパティについて説明します。添付プロパティは XAML で
説明した通り、オブジェクトに対して別のクラスで定義されたプロパティを取得または設定で
きる機能になります。DependencyObject では、以下のようにして添付プロパティを定義しま
す。
36
public class AttachedPropertySample
{
public static readonly DependencyProperty SampleValueProperty =
DependencyProperty.RegisterAttached("SampleValue", typeof(int),
typeof(AttachedPropertySample), new PropertyMetadata(0));
public static int GetSampleValue(Windows.UI.Xaml.DependencyObject obj)
{
return (int)obj.GetValue(SampleValueProperty);
}
public static void SetSampleValue(Windows.UI.Xaml.DependencyObject obj, int value)
{
obj.SetValue(SampleValueProperty, value);
}
}
DependencyProperty クラスの RegisterAttached メソッドで DependencyProperty クラスのイ
ンスタンスを作成する点と、添付プロパティは、CLR の形式のプロパティではなく、static な
SetXXX と GetXXX という名前でラッパーを作るという点が異なります。また、添付プロパテ
ィを定義するクラスは、必ずしも DependencyObject を継承する必要はありません。
先ほどの Range クラスに、SampleValue 添付プロパティの値を設定して取得するコードは以下
のようになります。
var range = new Range();
// 添付プロパティの値の設定と取得
AttachedPropertySample.SetSampleValue(range, 100);
var sampleValue = AttachedPropertySample.GetSampleValue(range);
添付プロパティも PropertyMetadata を使ってデフォルト値とコールバックが指定できます。コ
ールバックを使うことで依存関係プロパティと同じように、別のプロパティに対して変更を伝
搬することが出来ます。
4.1.3. ス レ ッド 操 作
37
DependencyObject は、生成されたスレッドに紐づくという特徴があります。別スレッドから
依存関係プロパティなどの操作を行うと例外が発生します。そのため、UWP のコントロール
は UI 用のスレッド(UI スレッド)に紐づけられていて、その他のスレッドから操作すること
が出来なくなっています。例えば、バックグラウンドでデータを読み込んで UI に反映すると
いった処理で、この特徴が問題になってきます。そのようなケースに対応するため、
DependencyObject には、自分が生成されたスレッドに紐づく CoreDispatcher というクラスを
保持しています。このオブジェクトには DependencyObject の Dispatcher プロパティからアク
セスが出来ます。CoreDispatcher クラスには、CoreDispatcher が紐づくスレッドで処理を行う
ための RunAsync メソッドが定義されていて、以下のように記述することでスレッドを切り替
えて処理をすることが出来ます。
await range.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
// DependencyObject の紐づけられたスレッドで処理を行える
});
第一引数の CoreDiapatcherPriority は処理の実行の優先度で以下の値を指定できます。
 Idle
一番優先度が低い。アイドル状態のときに実行される。
 Low
低い優先順位。自分より高い優先順位の処理がないと実行される。
 Normal
普通の優先順位。順番に実行されます。
 High
最高の優先順位。ユーザーアプリケーションでの使用はしない。
4.2. FrameworkElement
UWP のコントロールの多くがこのクラスを継承しています。このクラスは、レイアウトや
XAML を使ったプログラミングで重要になるデータバインディングや、見た目を共通化するた
めの Style や、リソースと呼ばれるデータを定義しておく場所の機能などを提供しています。
38
レイアウトに関するプロパティとして Margin というプロパティがあります。このプロパティ
を指定することで、コントロールの内側に余白を設けることが出来ます。例えば Button に余
白を設ける場合は以下のように XAML を記述します。
<Button Margin=”10,5,10,5”
Content=”Hello” />
マージンは、左、上、右、下の順番でカンマで区切って指定します。以下のように余白が設定
されます。(黒枠がマージンの外側)
リソースは、Resources プロパティとして定義され、そこにブラシや Style などの様々なオブジ
ェクトの名前を付けて登録することが出来ます。リソースに定義されたオブジェクトは、
StaticResource マークアップ拡張によって XAML から取得できます。例えば、SolidColorBrush
と言う単色塗りつぶしのブラシを定義して、ボタンから参照するコードは以下のようになりま
す。
<Page x:Class="XamlBasics.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:XamlBasics"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Page.Resources>
<SolidColorBrush x:Key="Brush"
Color="Red" />
</Page.Resources>
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<Button Content="Hello"
Background="{StaticResource Brush}" />
39
</Grid>
</Page>
赤色のブラシを Brush という名前(x:Key で指定)で定義して、それをボタンの背景色に
StaticResource マークアップ拡張を使って指定しています。StaticResource で参照できる値は、
StaticResource を使う場所よりも親のコントロールで定義されている必要があります。例え
ば、上記の Brush という名前のリソースを取得する場合は、Button よりも上の階層である
Page の Resources で定義されているため取得できています。また、StaticResource マークアッ
プ拡張は、親へ親へ Resources を探索していくので、同じ名前のリソースが定義されていた場
合は、より自分に近い場所のリソースを参照します。Page まで親へさかのぼって見つからない
場合は、App クラスの Resources で定義されたものを参照します。App クラスでも見つからな
い場合は、組み込みで定義されているリソースを参照します。
4.3. Control
FrameworkElement を拡張し、コントロールに必要な基本的な機能を提供します。自分でカス
タムコントロールを提供する場合に、このクラスを継承することがあります。主な提供機能は
コントロールの見た目を自由に変更することが出来る Template という機能になります。
4.4. ContentControl
単一の要素を表示するためのコントロールになります。Page や Button や UserControl など多
くのコントロールが、このコントロールを継承しています。ContentControl は、Content プロ
パティに設定されたデータを非常に柔軟に表示する能力を持っていて、文字列が設定されてい
れば文字列を表示し、コントロールが設定されていれば、コントロールを表示します。任意の
オブジェクトを表示することも可能で、その場合 ContentTemplate というテンプレートを使っ
て見た目を定義できます。また、ContentTemplateSelector などを使うことでオブジェクトを
どのように表示するかということをカスタマイズすることも可能です。
4.5. ItemsControl
ItemsControl は複数の要素を表示するためのコントロールになります。ItemsSource プロパテ
ィに設定された IEnumerable に対して要素を表示します。表示される 1 要素ずつは
ContentControl を継承したクラスにホストされ ContentControl で説明したように柔軟に要素
40
を表示することが出来ます。ListBox、ListView などの複数の要素を表示するコントロールは
基本的にこのコントロールを継承しています。
ItemsControl は、INotifyCollectionChanged を実装しているコレクション(厳密には IList も必
要)を ItemsSource に設定することで、コレクションの要素の追加や削除に表示を追随させる
ことが出来ます。この INotifyCollectionChanged のデフォルトの実装クラスとして
System.Collections.ObjectModel.ObservableCollection<T>クラスが提供されています。このク
ラスを ItemsSource に設定することで、コレクションの追加・削除に簡単に追随させることが
出来るようになります。
基本的には、要素は縦に並ぶように配置されますが、ItemsPanel を変更することで縦ならびを
横ならびに変更できます。具体的には以下のような XAML を記述します。
<ItemsControl>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<!-- 横並びにする -->
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
このように、ItemsControl は ContentControl のような柔軟な表示をしつつ、ItemsPanel を使
って並びを柔軟に対応できるような作りになっています。
4.6. Panel
Panel は、複数のコントロールをホストすることが出来るコントロールです。UWP のレイアウ
トシステムによって、ホストしたコントロールを柔軟に配置することが出来ます。Canvas(絶
対座標での要素の配置)、Grid(テーブルレイアウト)、StackPanel(縦や横に積み上げる形
で配置)、RelativePanel(相対位置による配置)などのコントロールがあります。これらのコ
ントロールは Children というプロパティにコントロールを格納して使います。Children プロパ
ティは XAML で説明したコンテンツコントロールになっているため、以下のようにタグの下に
直接別のコントロールを記述することが出来ます。
41
<StackPanel>
<Button Content=”Button1” />
<Button Content=”Button2” />
<Button Content=”Button3” />
</StackPanel>
5. データバインディング
著者が UWP(XAML を使った)アプリケーションで非常に重要な要素と考えるデータバイン
ディングについて説明します。この機能を使いこなすことで、見た目とロジックを綺麗に切り
離したアプリケーションを作ることが出来ます。
UWP のデータバインディングには 2 種類のものが存在します。WPF の頃から存在する実行時
データバインディングと、UWP に追加されたコンパイル時データバインディングになりま
す。順番に解説していきます。
5.1. 実 行 時デ ー タ バ イ ンデ ィ ン グ
実行時データバインディングは、FrameworkElement で実装されている機能になります。
DataContext というプロパティに格納されたオブジェクトと、コントロールのプロパティの値
の同期をとる機能になります。(厳密にいうと Binding の Source に設定されたオブジェクトの
プロパティと、コントロールのプロパティの同期をとる機能になります。何も指定しないとデ
フォルトの Binding の Source が DataContext になります。)同期の取り方には、以下の 3 種
類が存在します。
1. OneWay(デフォルト)
DataContext に設定されたオブジェクトのプロパティ(ソースと言います)からコントロ
ールのプロパティ(ターゲットと言います)に対する 1 方向の値の同期になります。ソー
スの値の変更を感知したらターゲットの値が更新されます。ソースの値の変更の感知は、
DependencyProperty の場合は自動的に、そうでない場合は INotifyPropertyChanged の
PropertyChanged イベントにより検知を行います。
42
2. TwoWay
ソースからターゲットの間を双方向に同期を取ります。ソースからターゲットへの同期の
タイミングは OneWay と同じです。
3. OneTime
初回の 1 度だけソースからターゲットに対して値の同期を取ります。
実行時データバインディングには Binding マークアップ拡張を使います。例えば以下のような
Person という名前のクラスがあるとします。
public class Person : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string name;
public string Name
{
get { return this.name; }
set
{
this.name = value;
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Name)));
}
}
private int age;
public int Age
{
get { return this.age; }
set
{
this.age = value;
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Age)));
43
}
}
}
Name と Age プロパティを持っていて、INotifyPropertyChanged インターフェースによる変更
通知を実装しています。これを Page の DataContext に以下のように設定します。
<Page x:Class="RuntimeDataBinding.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:RuntimeDataBinding"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Page.DataContext>
<local:Person />
</Page.DataContext>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
</Grid>
</Page>
Grid を StackPanel(子要素を縦や横に並べて表示するコントロール)に置き換えて、以下のよ
うに TextBox と TextBlock を置いてデータをバインドさせます。
<Page x:Class="RuntimeDataBinding.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:RuntimeDataBinding"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Page.DataContext>
<local:Person />
</Page.DataContext>
44
<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<TextBox Text="{Binding Path=Name, Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}" />
<TextBlock Text="{Binding Path=Name}" />
<TextBox Text="{Binding Path=Age, Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}" />
<TextBlock Text="{Binding Path=Age}" />
</StackPanel>
</Page>
最初の TextBox と TextBlock の組が Name プロパティへのデータバインディングで、2 つ目の
TextBox と TextBlock の組が Age プロパティへのデータバインディングになります。実行する
と TextBox と TextBlock の値が Person クラスを通して同期されていることが確認できます。
Binding マークアップ拡張には、以下のようなプロパティが設定出来ます。
 Path
ソースのプロパティを指定します。「プロパティ 1.プロパティ 2」のようにオブジェクト
45
を辿るように Path を記述することが出来ます。また、配列などの「プロパティ 1[0]」記
法にも対応しています。Path プロパティは、Binding マークアップ拡張の最初に書く場合
は、省略することが可能です。つまり先ほどのコードの例は「{Binding Name,
Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}」のように記述することが出来
ます。
 Mode
OneWay, TwoWay, OneTime を指定します。
 UpdateSourceTrigger
Default, PropertyChanged, Explicit を指定します。通常、Default は PropertyChanged と
同様の意味になります。TextBox の Text に Binding するときは、Default はフォーカスが
外れた時に値の同期をとります。テキストが変化する度に値の同期をとる場合は上記の例
のように明示的に PropertyChanged を指定します。Explicit を指定した場合は
BindingExpression の UpdateSource メソッドを呼び出したタイミングで同期が取られま
す。
 Converter
ソースからターゲットと、ターゲットからソースへ値が同期されるときに値の変換ロジッ
クをあらわす IValueConverter を実装したクラスを指定します。
 ConverterParameter
Converter に渡すパラメータを指定します。
 ElementName
データバインディングのソースに x:Name で名前を付けたコントロールを指定する場合に
使用します。
 FallbackValue
バインディングで値を返せない場合に返す値を指定します。
 TargetNullValue
ターゲットの値が null の時に返す値を指定します。
46
 RelativeSource
バインディングのソースを相対的に指定します。以下の 2 種類の指定方法があります。
{Binding …, RelativeSource={RelativeSource TemplatedParent}}
{Binding …, RelativeSource={RelativeSource Self}}
TemplatedParent は、ControlTemplate と呼ばれるコントロールの見た目を定義する場所
で使用します。コントロール自身がソースとなります。
Self は、ターゲットの要素をバインディングのソースに指定します。
 Source
バインディングのソースを指定します。何も指定しない場合はデフォルトで DataContext
プロパティの値が使われます。
ElementName などを使ったデータバインディングの例を以下に示します。まず、以下のよう
な IValueConverter インターフェースを実装したクラスを定義します。
public class SanConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
// ソースからターゲット
return $"{value}さん";
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
// ターゲットからソース方向
// ここでは未サポート
throw new NotSupportedException();
}
}
Converter は、FrameworkElement で紹介したリソースに定義して使用します。では、TextBox
に入力した値を使って「○○さん」と表示する TextBlock を作成してみます。
<Page x:Class="RuntimeDataBinding.MainPage"
47
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:RuntimeDataBinding"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Page.Resources>
<local:SanConverter x:Key="SanConverter" />
</Page.Resources>
<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<TextBox x:Name="TextBox" />
<TextBlock Text="{Binding Text, ElementName=TextBox, Converter={StaticResource
SanConverter}}" />
</StackPanel>
</Page>
実行すると、以下のように TextBox の入力に同期して、TextBlock の値が書き換わります。
あまりやる機会はないですが、実行時データバインディングは C#のコードからも設定するこ
とが出来ます。例えば、Name というプロパティと TextBox の Text をバインディングする場
合は以下のようなコードになります。
var binding = new Binding
{
Path = new PropertyPath("Name"),
Mode = BindingMode.TwoWay,
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
};
48
this.TextBox.SetBinding(TextBox.TextProperty, binding);
Binding クラスのインスタンスを生成して、Path や Mode などのプロパティを設定したあと
に、ターゲットとなるオブジェクトの SetBinding メソッドで、バインディングのターゲットと
なる依存関係プロパティ(添付プロパティも可)と、Binding オブジェクトを指定します。
5.2. コ ン パイ ル 時 デ ー タバ イ ン ディ ン グ
実行時データバインディングは、バインディングを実行時に解決しますが、コンパイル時デー
タバインディングは、コンパイル時にバインディングの解決を行います。コンパイル時データ
バインディングの特徴を以下に示します。
 実行時ではなくコンパイル時にバインディングの情報が確定するため実行時データバイン
ディングに比べて高速
 バインディングのソースが、DataContext ではなく Page になっている
 デフォルトの Mode が OneTime になっている
実行時データバインディングとの大きな違いは以上のようになります。コンパイル時データバ
インディングには、{x:Bind …}というマークアップ拡張を使います。TextBox と TextBlock を
バインドするコードの例を以下に示します。
<Page x:Class="CompileTimeDataBinding.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:CompileTimeDataBinding"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<TextBox x:Name="TextBox" />
<TextBlock Text="{x:Bind TextBox.Text, Mode=TwoWay}" />
</StackPanel>
</Page>
49
x:Name 属性を使って、TextBox を Page のメンバーとして定義しています。そのため、
TextBlock で定義している x:Bind から TextBox という名前で参照できます。実行すると、以下
のようになります。
コンパイル時データバインディングで指定可能なプロパティは以下の通りです。
 Path
 Mode
 TargetNullValue
 FallbackValue
 Converter
 ConverterParameter
各パラメータについては実行時データバインディングと、ほぼ同じになります。また、x:Bind
の特徴として、イベントハンドラをバインドできるという点があります。イベントハンドラの
バインドは、以下のシグネチャのメソッドに対して行えます。
void Foo();
void Foo(object sender, object eventArgs);
void Foo(object sender, XXXXEventArgs eventArgs); // 各イベントのイベント引数の型
例として、以下のようなクラスをバインドしてみたいと思います。
public class Person : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
50
private string name;
public string Name
{
get { return this.name; }
set
{
this.name = value;
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Name)));
}
}
public void ResetName()
{
this.Name = null;
}
}
XAML を以下に示します。
<Page x:Class="CompileTimeDataBinding.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:CompileTimeDataBinding"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Page.Resources>
<local:Person x:Name="Person" />
</Page.Resources>
<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<TextBox Text="{x:Bind Person.Name, Mode=TwoWay, TargetNullValue='未入力'}" />
<TextBlock Text="{x:Bind Person.Name, Mode=OneWay}" />
<Button Content="Reset"
51
Click="{x:Bind Person.ResetName}" />
</StackPanel>
</Page>
Page の Resources で x:Name を使って Page のメンバーとして Person を定義しています。コー
ドビハインドで以下のように定義するのと同じようなイメージになります。
public sealed partial class MainPage : Page
{
public Person Person { get; } = new Person();
}
そして、TextBox や TextBlock と Name プロパティをバインドしています。イベントのバイン
ドは Button の Click イベントで行っています。Person クラスに定義した ResetName メソッド
をバインドしています。実行すると以下のようになります。
TextBox に入力すると、Person クラスの Name プロパティを介して TextBlock に値が同期され
ます。(コンパイル時データバインディングの TextBox の Text プロパティへのバインディング
は特殊で、フォーカスが外れたときに値の同期が行われます)
52
ボタンをクリックすると、TextBox が未入力の状態に戻ります。
53
この他に、コンパイル時データバインディングは実行時にコードから設定できないという点が
実行時データバインディングと異なります。
6. アプリケーションライフサイクル
UWP アプリは、デスクトップアプリケーションよりスマートフォンアプリケーションのよう
なライフサイクルで動作します。具体的に言うと、デスクトップではアプリケーションは最小
化すると休止状態に移行して、メモリの使用状況によっては OS によってアプリケーションが
終了されることがあります。この終了はアプリケーションから検知することが出来ないため、
休止状態に入るときに終了されてもいいようにアプリケーションで備える必要があります。モ
バイルでは、バックグラウンドに回ったときに、休止状態に入ります。この UWP のライフサ
イクルを図にすると以下のようになります。
アプリケーションの起動は、プロジェクトの App クラスの OnLaunched メソッドがエントリ
ーポイントとなります。このとき、引数の LaunchActivatedEventArgs に直前のアプリの状態
(終了状態だったのかなど)が入っているので、それを見て必要に応じて復帰処理などを行い
ます。
6.1. ア プ リケ ー シ ョ ン の起 動 シ ーケ ン ス
54
アプリケーションは、LaunchActivatedEventArgs の PreviousExecutionState の値を見て起動時
の処理を適切に行う必要があります。PreviousExecutionState には、以下の値が格納されてい
ます。
 NotRunning
アプリケーションは実行されていなかった。
 Running
アプリケーションは実行中。
 Suspended
アプリケーションは中断状態だった。
 Terminated
アプリケーションは中断後に終了された。
 ClosedByUser
アプリケーションはユーザーによって終了された。
アプリケーションの起動時に行わないといけないことは、新規作成したひな形の App クラスに
定義されています。OnLaunched メソッドから不要な処理やコメントを除いたものを以下に示
します。
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
Frame rootFrame = Window.Current.Content as Frame;
if (rootFrame == null)
{
rootFrame = new Frame();
if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
//TODO: 以前中断したアプリケーションから状態を読み込みます
}
55
Window.Current.Content = rootFrame;
}
if (e.PrelaunchActivated == false)
{
if (rootFrame.Content == null)
{
rootFrame.Navigate(typeof(MainPage), e.Arguments);
}
Window.Current.Activate();
}
}
UWP アプリは、Window.Current を通じてアプリの Window にアクセスできます。この
Window の Content プロパティに Frame という画面遷移機能を持ったコントロールを配置し
て、その中で画面遷移を行います。Window.Current.Content に値が設定されていないという
ことは、終了状態からの起動ということなので、Frame を新規作成して設定します。さらに先
ほど説明した PreviousExecutionState を確認して Terminated の時に、直前の中断時に保存し
たデータを使って復元を行います。最後に PrelaunchActivated で直前のアクティブ化状態を確
認して、アクティブでない場合は、必要に応じて画面遷移(Frame の Navigate メソッド)を行
い、自分自身をアクティブ化します。
以上が、アプリケーションの基本的な起動シーケンスになります。
6.2. サ ス ペン ド 時 の 処 理
アプリケーションがサスペンドされるときには、App クラスで Suspending イベントが発生し
ます。デフォルトで作成されている App クラスではコンストラクタで Suspending イベントを
購読して、OnSuspending メソッドが呼ばれるようになっています。
public App()
{
this.InitializeComponent();
this.Suspending += OnSuspending;
56
}
private void OnSuspending(object sender, SuspendingEventArgs e)
{
var deferral = e.SuspendingOperation.GetDeferral();
//TODO: アプリケーションの状態を保存してバックグラウンドの動作があれば停止します
deferral.Complete();
}
e.SuspendingOperation.GetDeferral メソッドの呼び出しから Complete メソッドの間で保存処
理を行います。この GetDeferral で取得したオブジェクトの Complete メソッドを呼び出すと
中断時の状態保存が終わったということを通知したことになります。
6.3. サ ス ペン ド か ら の 復帰
あまり利用することはありませんが、サスペンド状態からアプリケーションが終了されないま
まフォアグラウンドに復帰したときに呼び出される処理があります。App クラスで Resuming
イベントを購読することで処理が出来ます。
6.4. ア プ リケ ー シ ョ ン ライ フ サ イク ル に 対 応 した サ ン プル
ここでは、簡単な中断処理に対応したアプリケーションを作成したみたいと思います。
LifecycleApp という名前でアプリケーションを作ります。そして、以下のようなクラスを作成
します。
using System.ComponentModel;
namespace LifecycleApp
{
public class LifecycleAppModel : INotifyPropertyChanged
{
public static LifecycleAppModel Instance { get; } = new LifecycleAppModel();
public event PropertyChangedEventHandler PropertyChanged;
private string value;
57
public string Value
{
get { return this.value; }
set
{
this.value = value;
this.PropertyChanged?.Invoke(this, new
PropertyChangedEventArgs(nameof(Value)));
}
}
}
}
このクラスを使って簡単なページを作成します。TextBox にデータを表示するだけの単純なペ
ージにします。MainPage.xaml.cs に以下のようなプロパティを定義します。
public sealed partial class MainPage : Page
{
public LifecycleAppModel Model { get; } = LifecycleAppModel.Instance;
public MainPage()
{
this.InitializeComponent();
}
}
MainPage.xaml を以下のように編集して LifecycleAppModel の Value と TextBox の Text をバ
インドします。
<Page x:Class="LifecycleApp.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:LifecycleApp"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
58
mc:Ignorable="d">
<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<TextBox Text="{x:Bind Model.Value, Mode=TwoWay}" />
</StackPanel>
</Page>
この状態でアプリケーションが中断されたときにどう動くか確認してみます。アプリケーショ
ンをデバッグ起動して、Visual Studio のツールバーで右クリックして「デバッグの場所」にチ
ェックを入れます。(チェックが入っている場合は、そのままで大丈夫です)
59
デバッグの場所にチェックを入れると「ライフサイクルイベント」というのが作成されます。
そこの「中断とシャットダウン」を選択することで、アプリケーションをサスペンドさせて終
了させることが出来ます。
60
MainPage の TextBox に任意の文字列を入力して「中断とシャットダウン」をします。そし
て、再度アプリケーションを起動すると、TextBox の文字が消えていることが確認できます。
ユーザーからしたら、最小化(モバイルの場合はバックグラウンドに回した)したアプリの入
力がクリアされてしまったという挙動になります。これを中断処理に対応して改善します。ま
ず、App クラスの OnSuspending メソッドで ApplicationData.Current.LocalSettings を使って
データの保存を行います。ApplicationData.Current.LocalSettings.Values(ローカルにデータを
保存するための Dictionary)に InputValue をキーにして LifecycleAppModel の Value プロパテ
ィの値を保存します。
private void OnSuspending(object sender, SuspendingEventArgs e)
{
var deferral = e.SuspendingOperation.GetDeferral();
ApplicationData.Current.LocalSettings.Values["InputValue"] = LifecycleAppModel.Instance.Value;
deferral.Complete();
}
次に、OnLaunched メソッドの Terminated の if 文に、この保存したデータを読み込む処理を
追加します。
if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
if (ApplicationData.Current.LocalSettings.Values.ContainsKey("InputValue"))
{
LifecycleAppModel.Instance.Value = (string)
ApplicationData.Current.LocalSettings.Values["InputValue"];
61
}
}
キーの存在を確認して、キーが存在した場合にデータの読み出しを行っています。この処理を
追加して、先ほどのように「中断とシャットダウン」をします。すると以下のように入力した
データが残っていることが確認できると思います。
中断前が以下のようになります。
中断からの復帰後は、以下のようになります。
7. ローカルデータとローミングデータ
UWP では、以下のデータの保存場所が提供されています。
 ローカルアプリデータ
 ローミングデータ
62
 一時アプリデータ
アプリデータの保存方法には、設定とファイルという 2 種類があります。設定は、int や string
などの基本的な型や DateTime 型や GUID 型などを保存することが出来るディクショナリのよ
うな形で提供されます。ファイルは、任意のファイル形式でデータを保存することが出来ま
す。
7.1. ロ ー カル ア プ リ デ ータ
ローカルアプリデータは、ApplicationData.Current.LocalSettings で設定にアクセスできます。
ApplicationData.Current.LocalFolder でファイルを保存するためのフォルダにアクセスできま
す。まず、設定についてみていきます。
設定の一番簡単な使い方は、Values プロパティにディクショナリのようにアクセスすることで
す。コード例を以下に示します。
var settings = ApplicationData.Current.LocalSettings;
settings.Values["Key"] = "Value";
var value = (string)settings.Values["Key"];
if (settings.Values.ContainsKey("Key"))
{
// Key が存在する場合
}
else
{
// Key が存在しない場合
}
// 削除
settings.Values.Remove(“Key”);
ApplicationDataCompositeValue というクラスを使うことで、値をまとめて管理することが出
来ます。以下のようなコードになります。
var settings = ApplicationData.Current.LocalSettings;
var composite = new ApplicationDataCompositeValue();
63
composite["Key1"] = "Value1";
composite["Key2"] = "Value2";
settings.Values["compositeValue"] = composite;
この他に、ApplicationDataContainer を使って、データを階層化して管理することが出来ま
す。この階層は 32 階層まで作成することが出来ます。
var settings = ApplicationData.Current.LocalSettings;
// 作成
var container = settings.CreateContainer("Container1", ApplicationDataCreateDisposition.Always);
// 値の設定
container.Values["Key1"] = "Value1";
// 存在確認
if (settings.Containers.ContainsKey("Container1"))
{
// 存在するとき
}
else
{
// 存在しないとき
}
// 削除
settings.DeleteContainer("Container1");
設定は手軽に使えますが、ファイルを使って任意の形式でローカルアプリデータにデータを保
存することもできます。ファイルにアクセスするコードは以下のようになります。
// フォルダを取得
var folder = ApplicationData.Current.LocalFolder;
// ファイルを作成する(存在する場合は置き換える)
var file = await folder.CreateFileAsync("sample.txt", CreationCollisionOption.ReplaceExisting);
// ファイルに出力する
await FileIO.WriteTextAsync(file, "Hello world");
// ファイルから読み込む
var data = FileIO.ReadTextAsync(file);
64
ApplicationData.Current.LocalFolder に対して、CreateFileAsync を呼び出すことでファイルを
作成できます。第一引数がファイル名で、第二引数でファイルが存在したときの挙動などを指
定します。上記コードでは、ReplaceExisting を指定して、ファイルが既に存在する場合は、新
しいもので置き換えるという指定をしています。
ファイルの読み書きは FileIO クラスの WriteTextAsync メソッドと ReadTextAsync を使いま
す。JSON.NET などの.NET のクラスライブラリと連携するためには System.IO.Stream が必要
になるケースがあります。これは、ファイルの拡張メソッドを使うことで取得が可能になって
います。
// 書き込み
using (var stream = await file.OpenStreamForWriteAsync())
{
// JSON.NET などを使う
}
// 読み込み
using (var stream = await file.OpenStreamForReadAsync())
{
// JSON.NET などを使う
}
アプリケーションのバージョンアップなどにより、設定やファイルに保存しているデータに非
互換が発生してしまった場合は、ApplicationData.Current.SetVersionAsync メソッドを使用し
てバージョン管理を行うことが出来ます。SetVersionAsync メソッドは、第一引数にバージョ
ン番号を指定し、第二引数にコールバックを指定します。コールバックでは、以下のように現
在のバージョンと要求されたバージョンが確認できます。
await ApplicationData.Current.SetVersionAsync(0, r =>
{
var d = r.GetDeferral();
Debug.WriteLine($"CurrentVersion: {r.CurrentVersion}, DesiredVersion: {r.DesiredVersion}");
// バージョンが違ってたら必要に応じて変換ロジックを走らせる
d.Complete();
65
});
SetVersionAsync を呼び出した場合は、バージョン番号が変わっていなくてもコールバックが
呼ばれるので、その点は注意する必要があります。
7.2. ロ ー ミン グ デ ー タ
ローカルアプリデータは、デバイスのローカルストレージに保存されます。ここで紹介するロ
ーミングデータは、同じアプリのデータを複数のデバイスで同期をとります。この機能を使う
ことで、例えばユーザーがデスクトップで途中まで呼んでいた書籍を、外出先で続きから読む
といったシナリオが実現可能になります。ローミングデータにも、設定とファイルが存在し
て、以下のようにアクセスを行います。
// 設定
var roamingSettings = ApplicationData.Current.RoamingSettings;
// ファイル
var roamingFolder = ApplicationData.Current.RoamingFolder;
RoamingSettings も RoamingFolder も、ローカルアプリデータと同じ方法で使用できます。ロ
ーミングデータは、ApplicationData.RoamingStorageQuota で指定されるサイズ(KB 単位)以
上のデータがある場合は、ローミングが実行されません。この値は、Windows 10 Version 1511
で確認したところ 100 という値が反ってきました。
RoamingData がアップデートされたことを検知するには、
ApplicationData.Current.DataChanged イベントを使用します。以下のようなコードになりま
す。
public MainPage()
{
this.InitializeComponent();
ApplicationData.Current.DataChanged += Current_DataChanged;
}
private void Current_DataChanged(ApplicationData sender, object args)
{
66
// RoamingData がアップデートされた
}
7.3. 一 時 アプ リ デ ー タ
一時アプリデータは、設定は存在せずにファイルのみになります。以下のようにして一時アプ
リデータのフォルダを取得します。
// 一時アプリフォルダを取得する
var folder = ApplicationData.Current.TemporaryFolder;
フォルダ取得後は、ローカルアプリデータで示した通りファイルへのアクセスが可能です。
8. Advanced XAML
ここでは、UWP を作るうえで必須となる XAML の高度な機能を紹介したいと思います。
8.1. Style
UWP には、Style と呼ばれるコントロールのプロパティの設定を外だしにして定義する仕組み
があります。これを使うことで HTML の CSS のように見た目の定義を別にすることが出来ま
す。HTML の CSS と異なる点は、XAML という統一された言語でコントロールのツリー構造
と見た目の定義ができるという点です。HTML の CSS を知っている方向けに説明すると、
HTML の CSS がセレクタによって適用対象を指定して、見た目を定義するのに対して、
XAML の Style は名前を付けてリソースに定義して、コントロールから、それを参照して設定
します。(コントロールのスタイルにインラインで書くことも出来ますが、それならコントロ
ールに直接プロパティを設定したほうがいいと思われます)
Style の定義は、以下のように Page や App クラスの Resources に Style タグを使って定義しま
す。
<Page x:Class="ControlsApp.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:ControlsApp"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
67
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Page.Resources>
<!-- MyTextBlock という名前で TextBlock のスタイルを定義 -->
<Style x:Key="MyTextBlock"
TargetType="TextBlock">
<!-- FontStyle プロパティに Italic を指定 -->
<Setter Property="FontStyle"
Value="Italic" />
<!-- FontWeight に Bold を指定 -->
<Setter Property="FontWeight"
Value="Bold" />
</Style>
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<!-- StaticResource を使って Style を設定 -->
<TextBlock Text="Hello world"
Style="{StaticResource MyTextBlock}"/>
</Grid>
</Page>
Style タグの TargetType で、何の型に対する Style なのか指定します。そして、Style タグの中
に Setter タグを使って何のプロパティに、どんな値を設定するのかを指定します。定義した
Style は、コントロールにある Style プロパティに StaticResource マークアップ拡張を使って指
定します。上記の XAML で、以下のように TextBlock が太字のイタリック体になります。
Style は、別のスタイルをベースに拡張して作ることも出来ます。Style の BaseOn にベースと
なる Style を StaticResource マークアップ拡張で指定します。先ほどの例の MyTextBlock スタ
68
イルを拡張して赤色の設定を追加した ExTextBlock という名前のスタイルを定義した XAML
を以下に示します。
<Page x:Class="ControlsApp.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:ControlsApp"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Page.Resources>
<!-- MyTextBlock という名前で TextBlock のスタイルを定義 -->
<Style x:Key="MyTextBlock"
TargetType="TextBlock">
<!-- FontStyle プロパティに Italic を指定 -->
<Setter Property="FontStyle"
Value="Italic" />
<!-- FontWeight に Bold を指定 -->
<Setter Property="FontWeight"
Value="Bold" />
</Style>
<!-- MyTextBlock を拡張して赤色にする -->
<Style x:Key="ExTextBlock"
TargetType="TextBlock"
BasedOn="{StaticResource MyTextBlock}">
<Setter Property="Foreground"
Value="Red" />
</Style>
</Page.Resources>
<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<!-- StaticResource を使って Style を設定 -->
<TextBlock Text="Hello world"
Style="{StaticResource MyTextBlock}" />
<TextBlock Text="Hello world2"
Style="{StaticResource ExTextBlock}" />
69
</StackPanel>
</Page>
この XAML を表示すると以下のようになります。ExTextBlock が、MyTextBlock に対して赤
色を追加したものになっていることが確認できます。
8.1.1. 定 義 済み の ス タ イ ル
UWP には、いくつかの Style が予め定義されています。この定義は「C:Program Files
(x86)Windows
Kits10DesignTimeCommonConfigurationNeutralUAP10.0.10586.0Generic」フォルダ
の generic.xaml でされています。よく使うものをいくつか紹介します。
 HeaderTextBlockStyle
ヘッダー用の大きな TextBlock 用 Style です。
 SubheaderTextBlockStyle
サブヘッダー用のヘッダーより一回り小さな TextBlock 用の Style です。
 TitleTextBlockStyle
タイトル用の TextBlock 用の Style です。
 SubtitleTextBlockStyle
サブタイトル用の TextBlock 用の Style です。
 BodyTextBlockStyle
本文用の TextBlock 用の Style です。
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門
かずきのUWP入門

Weitere ähnliche Inhalte

Was ist angesagt?

【Unity】 Behavior TreeでAIを作る
 【Unity】 Behavior TreeでAIを作る 【Unity】 Behavior TreeでAIを作る
【Unity】 Behavior TreeでAIを作るtorisoup
 
Windowsフォームで大丈夫か?一番良いのを頼む。
Windowsフォームで大丈夫か?一番良いのを頼む。Windowsフォームで大丈夫か?一番良いのを頼む。
Windowsフォームで大丈夫か?一番良いのを頼む。Yuya Yamaki
 
低レイヤー入門
低レイヤー入門低レイヤー入門
低レイヤー入門demuyan
 
ドメイン駆動設計 ( DDD ) をやってみよう
ドメイン駆動設計 ( DDD ) をやってみようドメイン駆動設計 ( DDD ) をやってみよう
ドメイン駆動設計 ( DDD ) をやってみよう増田 亨
 
コンテナの作り方「Dockerは裏方で何をしているのか?」
コンテナの作り方「Dockerは裏方で何をしているのか?」コンテナの作り方「Dockerは裏方で何をしているのか?」
コンテナの作り方「Dockerは裏方で何をしているのか?」Masahito Zembutsu
 
Observableで非同期処理
Observableで非同期処理Observableで非同期処理
Observableで非同期処理torisoup
 
未来のプログラミング技術をUnityで -UniRx-
未来のプログラミング技術をUnityで -UniRx-未来のプログラミング技術をUnityで -UniRx-
未来のプログラミング技術をUnityで -UniRx-torisoup
 
【BS3】Visual Studio 2022 と .NET 6 での Windows アプリ開発技術の紹介
【BS3】Visual Studio 2022 と .NET 6 での Windows アプリ開発技術の紹介 【BS3】Visual Studio 2022 と .NET 6 での Windows アプリ開発技術の紹介
【BS3】Visual Studio 2022 と .NET 6 での Windows アプリ開発技術の紹介 日本マイクロソフト株式会社
 
「スキルなし・実績なし」 32歳窓際エンジニアがシリコンバレーで働くようになるまで
「スキルなし・実績なし」 32歳窓際エンジニアがシリコンバレーで働くようになるまで「スキルなし・実績なし」 32歳窓際エンジニアがシリコンバレーで働くようになるまで
「スキルなし・実績なし」 32歳窓際エンジニアがシリコンバレーで働くようになるまでShuichi Tsutsumi
 
WebSocketのキホン
WebSocketのキホンWebSocketのキホン
WebSocketのキホンYou_Kinjoh
 
脱 Excel設計書
脱 Excel設計書脱 Excel設計書
脱 Excel設計書rai
 
インフラエンジニアの綺麗で優しい手順書の書き方
インフラエンジニアの綺麗で優しい手順書の書き方インフラエンジニアの綺麗で優しい手順書の書き方
インフラエンジニアの綺麗で優しい手順書の書き方Shohei Koyama
 
DockerとPodmanの比較
DockerとPodmanの比較DockerとPodmanの比較
DockerとPodmanの比較Akihiro Suda
 
エンジニアの個人ブランディングと技術組織
エンジニアの個人ブランディングと技術組織エンジニアの個人ブランディングと技術組織
エンジニアの個人ブランディングと技術組織Takafumi ONAKA
 
Unity開発で使える設計の話+Zenjectの紹介
Unity開発で使える設計の話+Zenjectの紹介Unity開発で使える設計の話+Zenjectの紹介
Unity開発で使える設計の話+Zenjectの紹介torisoup
 
コンテナ未経験新人が学ぶコンテナ技術入門
コンテナ未経験新人が学ぶコンテナ技術入門コンテナ未経験新人が学ぶコンテナ技術入門
コンテナ未経験新人が学ぶコンテナ技術入門Kohei Tokunaga
 
Slurmのジョブスケジューリングと実装
Slurmのジョブスケジューリングと実装Slurmのジョブスケジューリングと実装
Slurmのジョブスケジューリングと実装Ryuichi Sakamoto
 
40歳過ぎてもエンジニアでいるためにやっていること
40歳過ぎてもエンジニアでいるためにやっていること40歳過ぎてもエンジニアでいるためにやっていること
40歳過ぎてもエンジニアでいるためにやっていることonozaty
 

Was ist angesagt? (20)

MVVM入門
MVVM入門MVVM入門
MVVM入門
 
【Unity】 Behavior TreeでAIを作る
 【Unity】 Behavior TreeでAIを作る 【Unity】 Behavior TreeでAIを作る
【Unity】 Behavior TreeでAIを作る
 
Windowsフォームで大丈夫か?一番良いのを頼む。
Windowsフォームで大丈夫か?一番良いのを頼む。Windowsフォームで大丈夫か?一番良いのを頼む。
Windowsフォームで大丈夫か?一番良いのを頼む。
 
低レイヤー入門
低レイヤー入門低レイヤー入門
低レイヤー入門
 
ドメイン駆動設計 ( DDD ) をやってみよう
ドメイン駆動設計 ( DDD ) をやってみようドメイン駆動設計 ( DDD ) をやってみよう
ドメイン駆動設計 ( DDD ) をやってみよう
 
コンテナの作り方「Dockerは裏方で何をしているのか?」
コンテナの作り方「Dockerは裏方で何をしているのか?」コンテナの作り方「Dockerは裏方で何をしているのか?」
コンテナの作り方「Dockerは裏方で何をしているのか?」
 
Docker Compose 徹底解説
Docker Compose 徹底解説Docker Compose 徹底解説
Docker Compose 徹底解説
 
Observableで非同期処理
Observableで非同期処理Observableで非同期処理
Observableで非同期処理
 
未来のプログラミング技術をUnityで -UniRx-
未来のプログラミング技術をUnityで -UniRx-未来のプログラミング技術をUnityで -UniRx-
未来のプログラミング技術をUnityで -UniRx-
 
【BS3】Visual Studio 2022 と .NET 6 での Windows アプリ開発技術の紹介
【BS3】Visual Studio 2022 と .NET 6 での Windows アプリ開発技術の紹介 【BS3】Visual Studio 2022 と .NET 6 での Windows アプリ開発技術の紹介
【BS3】Visual Studio 2022 と .NET 6 での Windows アプリ開発技術の紹介
 
「スキルなし・実績なし」 32歳窓際エンジニアがシリコンバレーで働くようになるまで
「スキルなし・実績なし」 32歳窓際エンジニアがシリコンバレーで働くようになるまで「スキルなし・実績なし」 32歳窓際エンジニアがシリコンバレーで働くようになるまで
「スキルなし・実績なし」 32歳窓際エンジニアがシリコンバレーで働くようになるまで
 
WebSocketのキホン
WebSocketのキホンWebSocketのキホン
WebSocketのキホン
 
脱 Excel設計書
脱 Excel設計書脱 Excel設計書
脱 Excel設計書
 
インフラエンジニアの綺麗で優しい手順書の書き方
インフラエンジニアの綺麗で優しい手順書の書き方インフラエンジニアの綺麗で優しい手順書の書き方
インフラエンジニアの綺麗で優しい手順書の書き方
 
DockerとPodmanの比較
DockerとPodmanの比較DockerとPodmanの比較
DockerとPodmanの比較
 
エンジニアの個人ブランディングと技術組織
エンジニアの個人ブランディングと技術組織エンジニアの個人ブランディングと技術組織
エンジニアの個人ブランディングと技術組織
 
Unity開発で使える設計の話+Zenjectの紹介
Unity開発で使える設計の話+Zenjectの紹介Unity開発で使える設計の話+Zenjectの紹介
Unity開発で使える設計の話+Zenjectの紹介
 
コンテナ未経験新人が学ぶコンテナ技術入門
コンテナ未経験新人が学ぶコンテナ技術入門コンテナ未経験新人が学ぶコンテナ技術入門
コンテナ未経験新人が学ぶコンテナ技術入門
 
Slurmのジョブスケジューリングと実装
Slurmのジョブスケジューリングと実装Slurmのジョブスケジューリングと実装
Slurmのジョブスケジューリングと実装
 
40歳過ぎてもエンジニアでいるためにやっていること
40歳過ぎてもエンジニアでいるためにやっていること40歳過ぎてもエンジニアでいるためにやっていること
40歳過ぎてもエンジニアでいるためにやっていること
 

Ähnlich wie かずきのUWP入門

B 64014 ja-04
B 64014 ja-04B 64014 ja-04
B 64014 ja-04mt7038
 
Windows azure stepbystep_tutorialguide
Windows azure stepbystep_tutorialguideWindows azure stepbystep_tutorialguide
Windows azure stepbystep_tutorialguideYoshida Yuri
 
徹底検証!ホスティングサービスの比較 Googleとマイクロソフト
徹底検証!ホスティングサービスの比較 Googleとマイクロソフト徹底検証!ホスティングサービスの比較 Googleとマイクロソフト
徹底検証!ホスティングサービスの比較 GoogleとマイクロソフトCompare GW
 
Unspsc product classification process and samples
Unspsc product classification process and samples Unspsc product classification process and samples
Unspsc product classification process and samples Indra kumar
 
2..nakamura thesis(2)
2..nakamura thesis(2)2..nakamura thesis(2)
2..nakamura thesis(2)Ravi Teja
 
Geopaparazzi & OSMフィールド調査ハンズオン
Geopaparazzi & OSMフィールド調査ハンズオンGeopaparazzi & OSMフィールド調査ハンズオン
Geopaparazzi & OSMフィールド調査ハンズオンarctic_tern265
 
Linux+PHPを学んで日程調整アプリを作ろう①
Linux+PHPを学んで日程調整アプリを作ろう①Linux+PHPを学んで日程調整アプリを作ろう①
Linux+PHPを学んで日程調整アプリを作ろう①Aina Hara
 
Rの拡張を書く (R 2.15.2)
Rの拡張を書く (R 2.15.2)Rの拡張を書く (R 2.15.2)
Rの拡張を書く (R 2.15.2)itoyan110
 
土地家屋調査⼠のドローン利活用可能性(第一回)
土地家屋調査⼠のドローン利活用可能性(第一回)土地家屋調査⼠のドローン利活用可能性(第一回)
土地家屋調査⼠のドローン利活用可能性(第一回)Takumi Yamanaka
 
情報システムの基礎(教科書・サンプル)
情報システムの基礎(教科書・サンプル)情報システムの基礎(教科書・サンプル)
情報システムの基礎(教科書・サンプル)Masanori Saito
 
ツールプラネット ADASキャリブレーションツール取扱説明書 2022年1月
ツールプラネット ADASキャリブレーションツール取扱説明書 2022年1月ツールプラネット ADASキャリブレーションツール取扱説明書 2022年1月
ツールプラネット ADASキャリブレーションツール取扱説明書 2022年1月FINE PIECE
 
OpenStack環境構築手順書 Havana版 バージョン2.2
OpenStack環境構築手順書 Havana版 バージョン2.2OpenStack環境構築手順書 Havana版 バージョン2.2
OpenStack環境構築手順書 Havana版 バージョン2.2VirtualTech Japan Inc.
 
LEGO Mindstorms ev3 ハンズオン資料 (2014年3月版)
LEGO Mindstorms ev3 ハンズオン資料 (2014年3月版)LEGO Mindstorms ev3 ハンズオン資料 (2014年3月版)
LEGO Mindstorms ev3 ハンズオン資料 (2014年3月版)Yoshitaka Seo
 
Zertoプラットフォーム アーキテクチャ ガイド紹介版
Zertoプラットフォーム アーキテクチャ ガイド紹介版Zertoプラットフォーム アーキテクチャ ガイド紹介版
Zertoプラットフォーム アーキテクチャ ガイド紹介版株式会社クライム
 
PostgreSQL 12 Beta 1 New Features with Examples (Japanese)
PostgreSQL 12 Beta 1 New Features  with Examples (Japanese)PostgreSQL 12 Beta 1 New Features  with Examples (Japanese)
PostgreSQL 12 Beta 1 New Features with Examples (Japanese)Noriyoshi Shinoda
 

Ähnlich wie かずきのUWP入門 (20)

Tour
TourTour
Tour
 
Tour
TourTour
Tour
 
B 64014 ja-04
B 64014 ja-04B 64014 ja-04
B 64014 ja-04
 
Windows azure stepbystep_tutorialguide
Windows azure stepbystep_tutorialguideWindows azure stepbystep_tutorialguide
Windows azure stepbystep_tutorialguide
 
徹底検証!ホスティングサービスの比較 Googleとマイクロソフト
徹底検証!ホスティングサービスの比較 Googleとマイクロソフト徹底検証!ホスティングサービスの比較 Googleとマイクロソフト
徹底検証!ホスティングサービスの比較 Googleとマイクロソフト
 
Unspsc product classification process and samples
Unspsc product classification process and samples Unspsc product classification process and samples
Unspsc product classification process and samples
 
2..nakamura thesis(2)
2..nakamura thesis(2)2..nakamura thesis(2)
2..nakamura thesis(2)
 
Agatha操作ガイド 基本編
Agatha操作ガイド 基本編Agatha操作ガイド 基本編
Agatha操作ガイド 基本編
 
Geopaparazzi & OSMフィールド調査ハンズオン
Geopaparazzi & OSMフィールド調査ハンズオンGeopaparazzi & OSMフィールド調査ハンズオン
Geopaparazzi & OSMフィールド調査ハンズオン
 
Manual audio
Manual audioManual audio
Manual audio
 
Linux+PHPを学んで日程調整アプリを作ろう①
Linux+PHPを学んで日程調整アプリを作ろう①Linux+PHPを学んで日程調整アプリを作ろう①
Linux+PHPを学んで日程調整アプリを作ろう①
 
Hi1
Hi1Hi1
Hi1
 
Rの拡張を書く (R 2.15.2)
Rの拡張を書く (R 2.15.2)Rの拡張を書く (R 2.15.2)
Rの拡張を書く (R 2.15.2)
 
土地家屋調査⼠のドローン利活用可能性(第一回)
土地家屋調査⼠のドローン利活用可能性(第一回)土地家屋調査⼠のドローン利活用可能性(第一回)
土地家屋調査⼠のドローン利活用可能性(第一回)
 
情報システムの基礎(教科書・サンプル)
情報システムの基礎(教科書・サンプル)情報システムの基礎(教科書・サンプル)
情報システムの基礎(教科書・サンプル)
 
ツールプラネット ADASキャリブレーションツール取扱説明書 2022年1月
ツールプラネット ADASキャリブレーションツール取扱説明書 2022年1月ツールプラネット ADASキャリブレーションツール取扱説明書 2022年1月
ツールプラネット ADASキャリブレーションツール取扱説明書 2022年1月
 
OpenStack環境構築手順書 Havana版 バージョン2.2
OpenStack環境構築手順書 Havana版 バージョン2.2OpenStack環境構築手順書 Havana版 バージョン2.2
OpenStack環境構築手順書 Havana版 バージョン2.2
 
LEGO Mindstorms ev3 ハンズオン資料 (2014年3月版)
LEGO Mindstorms ev3 ハンズオン資料 (2014年3月版)LEGO Mindstorms ev3 ハンズオン資料 (2014年3月版)
LEGO Mindstorms ev3 ハンズオン資料 (2014年3月版)
 
Zertoプラットフォーム アーキテクチャ ガイド紹介版
Zertoプラットフォーム アーキテクチャ ガイド紹介版Zertoプラットフォーム アーキテクチャ ガイド紹介版
Zertoプラットフォーム アーキテクチャ ガイド紹介版
 
PostgreSQL 12 Beta 1 New Features with Examples (Japanese)
PostgreSQL 12 Beta 1 New Features  with Examples (Japanese)PostgreSQL 12 Beta 1 New Features  with Examples (Japanese)
PostgreSQL 12 Beta 1 New Features with Examples (Japanese)
 

Mehr von 一希 大田

.NET 7 での ASP.NET Core Blazor の新機能ピックアップ
.NET 7 での ASP.NET Core Blazor の新機能ピックアップ.NET 7 での ASP.NET Core Blazor の新機能ピックアップ
.NET 7 での ASP.NET Core Blazor の新機能ピックアップ一希 大田
 
Azure Static Web Apps を試してみた!
Azure Static Web Apps を試してみた!Azure Static Web Apps を試してみた!
Azure Static Web Apps を試してみた!一希 大田
 
Visual studio 2019 updates pickup!
Visual studio 2019 updates pickup!Visual studio 2019 updates pickup!
Visual studio 2019 updates pickup!一希 大田
 
.NET 5 and Windows app dev
.NET 5 and Windows app dev.NET 5 and Windows app dev
.NET 5 and Windows app dev一希 大田
 
Uno Platform 触ってみた
Uno Platform 触ってみたUno Platform 触ってみた
Uno Platform 触ってみた一希 大田
 
WPF on .NET Core 3.1 で Windows 10 アプリ開発
WPF on .NET Core 3.1 で Windows 10 アプリ開発WPF on .NET Core 3.1 で Windows 10 アプリ開発
WPF on .NET Core 3.1 で Windows 10 アプリ開発一希 大田
 
.NET Core 3.0 + Windows 10 で WPF 開発
.NET Core 3.0 + Windows 10 で WPF 開発.NET Core 3.0 + Windows 10 で WPF 開発
.NET Core 3.0 + Windows 10 で WPF 開発一希 大田
 
はじめよう Azure Functions
はじめよう Azure Functionsはじめよう Azure Functions
はじめよう Azure Functions一希 大田
 
Windows 10 対応のデスクトップアプリを作る技術(事前公開版v2)
Windows 10 対応のデスクトップアプリを作る技術(事前公開版v2)Windows 10 対応のデスクトップアプリを作る技術(事前公開版v2)
Windows 10 対応のデスクトップアプリを作る技術(事前公開版v2)一希 大田
 
Xamarin.Forms アプリケーション 設計パターン
Xamarin.Forms アプリケーション 設計パターンXamarin.Forms アプリケーション 設計パターン
Xamarin.Forms アプリケーション 設計パターン一希 大田
 
Windows 10 対応のデスクトップアプリを 作る技術(事前公開版)
Windows 10 対応のデスクトップアプリを 作る技術(事前公開版)Windows 10 対応のデスクトップアプリを 作る技術(事前公開版)
Windows 10 対応のデスクトップアプリを 作る技術(事前公開版)一希 大田
 
WPF on .NET Core 3.0
WPF on .NET Core 3.0WPF on .NET Core 3.0
WPF on .NET Core 3.0一希 大田
 
Visual Studio 2019 の個人的なお勧め機能(発表時点)
Visual Studio 2019 の個人的なお勧め機能(発表時点)Visual Studio 2019 の個人的なお勧め機能(発表時点)
Visual Studio 2019 の個人的なお勧め機能(発表時点)一希 大田
 
Visual Studio 2019 の個人的なお勧め機能
Visual Studio 2019 の個人的なお勧め機能Visual Studio 2019 の個人的なお勧め機能
Visual Studio 2019 の個人的なお勧め機能一希 大田
 
Windows 10 に対応した デスクトップ アプリを作る技術(事前公開版 v2)
Windows 10 に対応した デスクトップ アプリを作る技術(事前公開版 v2)Windows 10 に対応した デスクトップ アプリを作る技術(事前公開版 v2)
Windows 10 に対応した デスクトップ アプリを作る技術(事前公開版 v2)一希 大田
 
事前公開版 Windows 10 に対応したデスクトップ アプリを作る技術 v1
事前公開版 Windows 10 に対応したデスクトップ アプリを作る技術 v1事前公開版 Windows 10 に対応したデスクトップ アプリを作る技術 v1
事前公開版 Windows 10 に対応したデスクトップ アプリを作る技術 v1一希 大田
 
スマートスピーカーのバックエンドで Azure を使う方法
スマートスピーカーのバックエンドでAzure を使う方法スマートスピーカーのバックエンドでAzure を使う方法
スマートスピーカーのバックエンドで Azure を使う方法一希 大田
 
Visual Studio App center 概要
Visual Studio App center 概要Visual Studio App center 概要
Visual Studio App center 概要一希 大田
 
はじめての HoloLens セッションの集大成お見せします!
はじめての HoloLens セッションの集大成お見せします!はじめての HoloLens セッションの集大成お見せします!
はじめての HoloLens セッションの集大成お見せします!一希 大田
 

Mehr von 一希 大田 (20)

.NET 7 での ASP.NET Core Blazor の新機能ピックアップ
.NET 7 での ASP.NET Core Blazor の新機能ピックアップ.NET 7 での ASP.NET Core Blazor の新機能ピックアップ
.NET 7 での ASP.NET Core Blazor の新機能ピックアップ
 
Power Apps + C#
Power Apps + C#Power Apps + C#
Power Apps + C#
 
Azure Static Web Apps を試してみた!
Azure Static Web Apps を試してみた!Azure Static Web Apps を試してみた!
Azure Static Web Apps を試してみた!
 
Visual studio 2019 updates pickup!
Visual studio 2019 updates pickup!Visual studio 2019 updates pickup!
Visual studio 2019 updates pickup!
 
.NET 5 and Windows app dev
.NET 5 and Windows app dev.NET 5 and Windows app dev
.NET 5 and Windows app dev
 
Uno Platform 触ってみた
Uno Platform 触ってみたUno Platform 触ってみた
Uno Platform 触ってみた
 
WPF on .NET Core 3.1 で Windows 10 アプリ開発
WPF on .NET Core 3.1 で Windows 10 アプリ開発WPF on .NET Core 3.1 で Windows 10 アプリ開発
WPF on .NET Core 3.1 で Windows 10 アプリ開発
 
.NET Core 3.0 + Windows 10 で WPF 開発
.NET Core 3.0 + Windows 10 で WPF 開発.NET Core 3.0 + Windows 10 で WPF 開発
.NET Core 3.0 + Windows 10 で WPF 開発
 
はじめよう Azure Functions
はじめよう Azure Functionsはじめよう Azure Functions
はじめよう Azure Functions
 
Windows 10 対応のデスクトップアプリを作る技術(事前公開版v2)
Windows 10 対応のデスクトップアプリを作る技術(事前公開版v2)Windows 10 対応のデスクトップアプリを作る技術(事前公開版v2)
Windows 10 対応のデスクトップアプリを作る技術(事前公開版v2)
 
Xamarin.Forms アプリケーション 設計パターン
Xamarin.Forms アプリケーション 設計パターンXamarin.Forms アプリケーション 設計パターン
Xamarin.Forms アプリケーション 設計パターン
 
Windows 10 対応のデスクトップアプリを 作る技術(事前公開版)
Windows 10 対応のデスクトップアプリを 作る技術(事前公開版)Windows 10 対応のデスクトップアプリを 作る技術(事前公開版)
Windows 10 対応のデスクトップアプリを 作る技術(事前公開版)
 
WPF on .NET Core 3.0
WPF on .NET Core 3.0WPF on .NET Core 3.0
WPF on .NET Core 3.0
 
Visual Studio 2019 の個人的なお勧め機能(発表時点)
Visual Studio 2019 の個人的なお勧め機能(発表時点)Visual Studio 2019 の個人的なお勧め機能(発表時点)
Visual Studio 2019 の個人的なお勧め機能(発表時点)
 
Visual Studio 2019 の個人的なお勧め機能
Visual Studio 2019 の個人的なお勧め機能Visual Studio 2019 の個人的なお勧め機能
Visual Studio 2019 の個人的なお勧め機能
 
Windows 10 に対応した デスクトップ アプリを作る技術(事前公開版 v2)
Windows 10 に対応した デスクトップ アプリを作る技術(事前公開版 v2)Windows 10 に対応した デスクトップ アプリを作る技術(事前公開版 v2)
Windows 10 に対応した デスクトップ アプリを作る技術(事前公開版 v2)
 
事前公開版 Windows 10 に対応したデスクトップ アプリを作る技術 v1
事前公開版 Windows 10 に対応したデスクトップ アプリを作る技術 v1事前公開版 Windows 10 に対応したデスクトップ アプリを作る技術 v1
事前公開版 Windows 10 に対応したデスクトップ アプリを作る技術 v1
 
スマートスピーカーのバックエンドで Azure を使う方法
スマートスピーカーのバックエンドでAzure を使う方法スマートスピーカーのバックエンドでAzure を使う方法
スマートスピーカーのバックエンドで Azure を使う方法
 
Visual Studio App center 概要
Visual Studio App center 概要Visual Studio App center 概要
Visual Studio App center 概要
 
はじめての HoloLens セッションの集大成お見せします!
はじめての HoloLens セッションの集大成お見せします!はじめての HoloLens セッションの集大成お見せします!
はじめての HoloLens セッションの集大成お見せします!
 

かずきのUWP入門

  • 2. 2 目次 1. 本書について........................................................................................................................ 10 2. Universal Windows Platform とは ....................................................................................... 10 2.1. UWP アプリまでの歴史............................................................................................... 11 2.1.1. .NET Framework 3.0 ............................................................................................ 11 2.1.2. Silverlight.............................................................................................................. 11 2.1.3. Windows Phone 7.x .............................................................................................. 11 2.1.4. Windows 8 ............................................................................................................ 12 2.1.5. Universal app........................................................................................................ 12 2.1.6. Universal Windows Platform ................................................................................ 12 2.2. 開発の前に ................................................................................................................... 12 2.3. デバイスファミリ ........................................................................................................ 13 2.4. アダプティブ UI........................................................................................................... 14 2.5. Hello world................................................................................................................... 14 2.5.1. 前準備................................................................................................................... 14 2.5.2. プロジェクトの作成 ............................................................................................. 15 2.5.3. 画面の作成............................................................................................................ 17 2.5.4. プログラムの実行................................................................................................. 21 2.5.5. まとめ................................................................................................................... 25 3. XAML................................................................................................................................... 25
  • 3. 3 4. UWP のコントロールの基本クラス..................................................................................... 30 4.1. DependencyObject....................................................................................................... 30 4.1.1. 依存関係プロパティ ............................................................................................. 31 4.1.2. 添付プロパティ..................................................................................................... 35 4.1.3. スレッド操作 ........................................................................................................ 36 4.2. FrameworkElement ...................................................................................................... 37 4.3. Control ......................................................................................................................... 39 4.4. ContentControl ............................................................................................................ 39 4.5. ItemsControl ................................................................................................................ 39 4.6. Panel ............................................................................................................................ 40 5. データバインディング ......................................................................................................... 41 5.1. 実行時データバインディング ...................................................................................... 41 5.2. コンパイル時データバインディング............................................................................ 48 6. アプリケーションライフサイクル ....................................................................................... 53 6.1. アプリケーションの起動シーケンス............................................................................ 53 6.2. サスペンド時の処理..................................................................................................... 55 6.3. サスペンドからの復帰 ................................................................................................. 56 6.4. アプリケーションライフサイクルに対応したサンプル............................................... 56 7. ローカルデータとローミングデータ ................................................................................... 61 7.1. ローカルアプリデータ ................................................................................................. 62
  • 4. 4 7.2. ローミングデータ ........................................................................................................ 65 7.3. 一時アプリデータ ........................................................................................................ 66 8. Advanced XAML .................................................................................................................. 66 8.1. Style.............................................................................................................................. 66 8.1.1. 定義済みのスタイル ............................................................................................. 69 8.2. アニメーション ............................................................................................................ 70 8.2.1. キーフレームを使ったアニメーション ................................................................ 75 8.2.2. ThemeAnimation.................................................................................................. 76 8.2.3. ThemaTransition.................................................................................................. 79 8.3. Visual State Manager.................................................................................................... 82 8.4. Behavior ....................................................................................................................... 90 8.4.1. インストール ........................................................................................................ 90 8.4.2. 組み込み Behavior ................................................................................................ 91 8.4.3. Behavior の使い方 ................................................................................................ 92 8.4.4. Behavior の作成.................................................................................................... 95 8.4.5. Behavior の細かい使い方 ................................................................................... 103 8.5. DataTemplate ............................................................................................................ 103 8.5.1. ContentControl 系での使用................................................................................ 103 8.5.2. ItemsControl 系での使用.................................................................................... 110 8.6. ControlTemplate........................................................................................................ 114
  • 5. 5 8.6.1. クリック可能なテキストの作成 ......................................................................... 114 8.6.2. コントロールの Visual State............................................................................... 116 9. 代表的なコントロール ....................................................................................................... 120 9.1. レイアウトパネル ...................................................................................................... 120 9.1.1. StackPanel .......................................................................................................... 120 9.1.2. Grid .................................................................................................................... 122 9.1.3. Canvas ................................................................................................................ 126 9.1.4. RelativePanel ...................................................................................................... 128 9.2. Border ........................................................................................................................ 131 9.3. TextBlock ................................................................................................................... 133 9.4. Button ........................................................................................................................ 135 9.5. TextBox...................................................................................................................... 138 9.6. CheckBox ................................................................................................................... 140 9.7. RadioButton ............................................................................................................... 141 9.8. RepeatButton ............................................................................................................. 145 9.9. ToggleSwitch.............................................................................................................. 147 9.10. ToggleButton ......................................................................................................... 149 9.11. ComboBox.............................................................................................................. 150 9.12. CalendarDatePicker ............................................................................................... 153 9.13. CalendarView ......................................................................................................... 156
  • 6. 6 9.14. DatePicker.............................................................................................................. 158 9.15. TimePicker............................................................................................................. 160 9.16. FlipView ................................................................................................................. 162 9.17. Frame ..................................................................................................................... 168 9.18. CommandBar ......................................................................................................... 170 9.19. ListView と GridView............................................................................................. 175 9.19.1. 選択項目の操作................................................................................................... 180 9.20. Image...................................................................................................................... 191 9.20.1. XAML 内での URL............................................................................................. 191 9.20.2. 画像の表示例 ...................................................................................................... 192 9.20.3. ユーザーの指定したファイルの表示.................................................................. 194 9.20.4. 画像の表示時の拡大方法方法............................................................................. 198 9.21. InkCanvas............................................................................................................... 200 9.21.1. ペン以外での入力の受け付け............................................................................. 201 9.21.2. ペンの色・太さを変える .................................................................................... 202 9.21.3. 文字認識 ............................................................................................................. 204 9.22. MapControl ............................................................................................................ 206 9.23. MediaElement ........................................................................................................ 215 9.24. Povot ...................................................................................................................... 217 9.25. PasswordBox .......................................................................................................... 221
  • 7. 7 9.26. ProgressBar ............................................................................................................ 223 9.27. ProgressRing .......................................................................................................... 225 9.28. ScrollViewer ........................................................................................................... 226 9.29. Slider ...................................................................................................................... 231 9.30. WebView ................................................................................................................ 232 9.31. AugoSuggestBox..................................................................................................... 237 9.32. SplitView ................................................................................................................ 248 9.32.1. ハンバーガーメニューの実装............................................................................. 249 10. 共有................................................................................................................................ 253 10.1.1. 共有の送信側の作成 ........................................................................................... 253 10.1.2. 共有の受信側の作成 ........................................................................................... 260 11. バックグラウンドタスク ............................................................................................... 265 11.1.1. バックグラウンドタスクの作成と登録 .............................................................. 265 11.1.2. バックグラウンドタスクとフォアグランドの連携 ............................................ 269 11.1.3. バックグラウンドタスクの追加情報.................................................................. 275 11.1.4. システムイベントへの応答 ................................................................................ 275 12. タイルとトースト .......................................................................................................... 276 12.1.1. タイルやトーストを作成するための補助ツール................................................ 276 12.1.2. ライブタイル ...................................................................................................... 278 12.1.3. セカンダリタイル............................................................................................... 281
  • 8. 8 12.1.4. トースト ............................................................................................................. 284 13. プッシュ通知.................................................................................................................. 293 14. コルタナ連携.................................................................................................................. 313 14.1.1. フォアグラウンドアプリの起動 ......................................................................... 313 14.1.2. バックグラウンドアプリの起動 ......................................................................... 323 15. アプリ間連携.................................................................................................................. 331 15.1. AppService.............................................................................................................. 331 15.2. 別アプリの起動 ...................................................................................................... 336 15.2.1. プロトコルによるアプリの起動 ......................................................................... 336 15.2.2. 結果を受け取るプロトコルによるアプリの起動................................................ 337 16. 複数デバイスに対応したアプリの作成.......................................................................... 339 16.1. アダプティブコード ............................................................................................... 339 16.2. アダプティブ UI..................................................................................................... 344 17. UserControl とテンプレートコントロール ................................................................... 349 17.1. UserControl............................................................................................................ 349 17.2. テンプレートコントロール .................................................................................... 353 18. UWP でのアプリの設計................................................................................................. 361 18.1. MVVM パターンとは............................................................................................. 361 18.2. Prism for Windows Runtime .................................................................................. 362 18.2.1. 足し算アプリの作成 ........................................................................................... 363
  • 9. 9 18.2.2. 基本的なクラスの使い方 .................................................................................... 378 19. まとめ ............................................................................................................................ 387
  • 10. 10 1. 本書について 本書は、Windows 10 で追加された Universal Windows Platform(以下 UWP)についての入門 書になります。以下の開発環境を前提としています。 1. Windows 10 2. Visual Studio 2015 Update 3 開発言語としては、XAML と C#を使用しています。本書では、C#の言語面での解説は行いま せん。C#についての入門は別途書籍やサイトなどを参考にしてください。 また、UWP を実行する OS は以下のものを想定しています。 1. Windows 10 2. Windows 10 Mobile 2. Universal Windows Platform とは UWP とは、Windows 10 で追加された、プラットフォームで以下の特徴を持ちます。 1. Windows 10 が動くすべてのデバイス上でワンバイナリでアプリが動く (ア) Windows 10 の動くデスクトップ (イ) Windows 10 の動くタブレット (ウ) Windows 10 Mobile の動く電話 (エ) Surface Hub (オ) HoloLens (カ) Windows 10 IoT の動くラズベリーパイなどの IoT デバイス 2. Windows ストアで配布が可能
  • 11. 11 UWP 上で動くアプリのことを UWP アプリといいます。 2.1. UWP ア プ リ ま で の 歴史 ここで少し余談ですが、UWP アプリに至るまでの歴史を著者の主観が入った状態ですが少し 見ていきたいと思います。さかのぼれば何処までもさかのぼれますが、ここでは、.NET Framework 3.0 で追加された WPF からの歴史を見ていきたいと思います。 2.1.1. .NET Framework 3.0 .NET Framework 3.0 で、Windows Presentation Foundation(以下 WPF)が追加されました。 これは、デスクトップアプリケーションを開発するためのプラットフォームで XAML(ザム ル)と呼ばれる XML をベースとした言語で画面を構築して、C#でロジックを記述するという 開発スタイルが登場しました。この開発スタイルは、UWP でも受け継がれています。 2.1.2. Silverlight 次に、Rich Internet Application(以下 RIA)と呼ばれるキーワードが持てはやされた時代が来ま す。この時は、現在のように HTML5 を中心とした開発ではなく Flash や Siliverlight と呼ばれ るブラウザプラグイン上でアプリケーションを構築することが主流だったと私は感じていま す。(HTML/CSS/JavaScript でも開発出来たが、今よりも凄く大変だった) Silverlight は、勢いのあったころは WPF を駆逐するのではないかと錯覚させるほど、機能追加 が活発で、OutOfBrowser というブラウザプラグインなのに、サンドボックス内にありつつデ スクトップアプリケーションのように動作するモードなども追加されました。UWP も大ざっ ぱにみると、サンドボックスの中で動く XAML と C#によって開発されたアプリが動くという ことで、とても似たような雰囲気があります。 2.1.3. Windows Phone 7.x 次に、Windows Phone です。これは、Silverlight がスマートフォンアプリとして動くという点 が特徴です。この時は、Silverlight がこのまま全プラットフォームにひろがっていくのではな いかと感じていました。(現実はそうではありませんでしたが…)
  • 12. 12 2.1.4. Windows 8 Silverlight の波も去り、Microsoft がタッチファーストという考えで作り出し、世間的には Vista 並みに失敗したと認識されている(私は好きですよ)Windows 8 が登場します。 Windows 8 では、ストアアプリと呼ばれる UWP の前身となるアプリケーションプラットフォ ームが登場します。COM の上に構築された Windows Runtime 上で動くアプリケーションがこ こで登場しました。Windows Runtime は、UWP でも使用されています。 2.1.5. Universal app Windows 8.1 と Windows Phone 8.1 で 95%くらい API が共通化されて、ほぼ同一ソースで Windows 8.1 上と Windows Phone 8.1 上で動くアプリケーションのバイナリを、それぞれ作成 することが出来るようになりました。ソースコードレベルとはいえ、同じコードが電話でもパ ソコンでも動くという大きな衝撃を与えてくれたテクノロジです。 2.1.6. Universal Windows Platform そして、UWP に繋がります。Universal app がソースコードの共有だったものを、UWP で は、同一バイナリが Windows 10 の動く様々なデバイスで動くということを実現しました。開 発手法は、WPF が登場してから一貫して XAML と C#による開発です。 HoloLens への対応や Windows 10 への力の入れ具合などから、現在、そして今後も大きく Microsoft が投資していくプラットフォームであることが伺えます。現に XAML などの開発言 語も WPF と比べて機能強化が積極的に行われています。本書では、この WPF から歴史を積み 上げて、現在の最新のプラットフォームである UWP についての開発について取り上げます。 2.2. 開 発 の前 に UWP の開発の話しに入る前に、UWP のアプリの作法であるガイドラインを紹介しておきま す。このガイドラインは、守らなければいけないというものではないですが、UWP のアプリ を作る上で、よくあるナビゲーションパターンや画面パターンなど、多くの有益な情報が記載 されています。
  • 13. 13 是非、Windows ストアなどに提出するようなアプリを作る場合には一読しておくことをお勧め しておきます。 Windows アプリ UX デザイン ガイドライン https://msdn.microsoft.com/ja-jp/mt634411.aspx 上記ページの中にある、「Windows 10 アプリ UX デザイン ガイド」が、それになります。 2.3. デ バ イス フ ァ ミ リ UWP を開発するうえで知っておいたほうがいい概念としてデバイスファミリというものがあ ります。デバイスファミリとは、アプリが動作するプラットフォームのようなものです。 Universal app が Windows 8.1 と Windows Phone 8.1 などの OS を対象としていたのに対し て、UWP ではデバイスファミリを対象とします。デスクトップパソコンでは、デスクトップ デバイスファミリに基づいて実行し、モバイル端末ではモバイルデバイスファミリに基づいて 実行されます。ユニバーサルデバイスファミリと呼ばれる特別なデバイスファミリも存在し、 ユニバーサルデバイスファミリで提供される、API は、全てのデバイスファミリで動作するこ とが保証されています。 デバイスファミリの関係をあらわした図を以下に示します。 各デバイスファミリには、プラットフォームに固有の API が提供されています。これらの API は、実行時に動的に存在を確認して呼び出すアダプティブコードを記述することが出来ます。 デバイスファミリを選択するということは、呼び出せる API 群を決定するということです。先 ほども言った通り、アダプティブコードを記述することでデバイスファミリ固有の API を使用 しつつ、他のデバイスファミリ上でも動作させるといったことも出来るようになっています。
  • 14. 14 必要があれば、デスクトップデバイスファミリ上でしか動作させないといったことも可能で す。 2.4. ア ダ プテ ィ ブ UI UWP は、様々なデバイス上で動作するアプリケーションを、ワンバイナリで作ることが出来 ます。逆に言うと、ワンバイナリで様々な画面サイズで動作するアプリケーションを作らない といけないということになります。このような要件に対応するため、アダプティブ UI を実現 しなければなりません。アダプティブ UI は、画面サイズに応じて最適な画面レイアウトを提 供する UI です。 以下のような小さなモバイル端末から、ホワイトボードサイズの Surface Hub まで様々なデバ イスに対応する必要があります。 (https://msdn.microsoft.com/ja-jp/library/windows/apps/dn894631.aspx より引用) アダプティブ UI のパターンについても、「開発の前に」で紹介したガイドラインに記載があ りますので、併せて確認してみてください。 2.5. Hello world 最初の UWP アプリとして Hello world を作成してみましょう。ボタンを押すと、Hello world というメッセージボックスが表示されます。 2.5.1. 前 準 備 UWP のアプリを開発するためには、Visual Studio 2015 のインストール時に UWP の開発環境 をインストールするように構成する必要があります。選択をせずに、インストールした場合は
  • 15. 15 コントロールパネルからプログラムの追加と削除を選んで、Visual Studio 2015 を選択して変更 を押してから、UWP の開発環境をインストールしてください。 また、最初にやる設定として、パソコンを開発者モードにする必要があります。設定(Win + i)を表示して「更新とセキュリティ」を選んで、「開発者向け」を選択して「開発者モード」 にします。 2.5.2. プ ロ ジェ ク ト の 作 成 メニューの「ファイル」→「新規作成」→「プロジェクト」を選択して、「テンプレート」の 「Visual C#」の「Windows」の「ユニバーサル」にある「空白のアプリ(ユニバーサル Windows)」を選択します。名前の項目に HelloWorld と入力して「OK」を選択してくださ い。
  • 17. 17 1. Assets フォルダ インストール後のプログラムフォルダに表示されるアイコンや、タイルなどに表示される アイコンが入っています。 2. App.xaml/App.xaml.cs アプリケーションのエントリーポイントです。 3. ApplicationInsights.config ApplicationInsights の構成ファイルです。プロジェクト新規作成時に ApplicationInsights を使用しない構成にしていた場合は作成されません。無くても問題ありません。 4. HelloWorld_TemporaryKey.pfx アプリケーションのインストールパッケージを作成するときに使用される鍵です。 5. MainPage.xaml/MainPage.xaml.cs アプリケーション起動時に最初に表示される画面です。 6. Package.appxmanifest アプリケーションのマニフェストファイルです。権限の設定などを行います。 7. project.json NuGet のライブラリの依存関係が記載されています。 2.5.3. 画 面 の作 成
  • 18. 18 Hello world の画面を作成します。MainPage.xaml をダブルクリックして開くとデザイナが表示 されます。 デザイナの下部には、XAML と呼ばれる画面を記述する言語が表示されています。デザイナの 左側にツールボックスが表示されていて、そこにボタンなどの各種コントロールがあります。
  • 20. 20 Button を選択した状態で、プロパティウィンドウを見ると Button の設定を変更できることが わかります。Content プロパティに Say hello と入力すると Button のテキストが Say hello にな ります。
  • 21. 21 Button をデザイナ上でダブルクリックすることで、Button がクリックされたときの処理が生 成されます。MainPage.xaml.cs が以下のようになります。 public sealed partial class MainPage : Page { public MainPage() { this.InitializeComponent(); } private void button_Click(object sender, RoutedEventArgs e) { } } このように XAML に紐づく C#のファイルをコードビハインドと言います。コードビハインド に処理を書きましょう。button_Click メソッドを以下のように書き換えます。 private async void button_Click(object sender, RoutedEventArgs e) { var dialog = new MessageDialog("Hello world"); await dialog.ShowAsync(); } MessageDialog は、名前空間がデフォルトで using されていないので、「Ctrl + .」を押して using を追加してください。UWP の API は、非同期のものがほとんどです。少しでも処理に 時間がかかるものは全て非同期メソッドとして提供されています。async/await は頻繁に使うの で、知らない方はマスターしておきましょう。 2.5.4. プ ロ グラ ム の 実 行 最後にプログラムの実行を行います。Visual Studio のツールバーを以下のように「x86」が選 択されていることを確認して「▶ローカルコンピューター」を選択します。
  • 22. 22 実行すると Button が置かれた Window が表示されます。Button をクリックすると以下のよう にダイアログが表示されます。 続けて Windows 10 Mobile で動作させてみましょう。「▶ローカルコンピューター」の横の▼ をクリックすると以下のように動作対象のターゲットが選べます。
  • 23. 23 その中から、「Mobile Emulator 10.0.10586 WVGA 4 inch 512MB」(細かいバージョン番号 は異なっている可能性があります)を選択します。選択したあと、再度クリックすると Windows 10 Mobile のエミュレータが起動して Hello world が実行されます。
  • 25. 25 詳しい手順は紹介しませんが、CPU を「ARM」にして「▶Device」にすることで開発者モー ドにした USB で接続された Windows 10 Mobile の実機にアプリを転送して動かすことが出来 ます。Windows 10 Mobile をお持ちの方は試してみてください。 2.5.5. ま と め プロジェクトの作成から、アプリケーションの実行までを紹介しました。また、デザイナを使 って画面をデザイン出来ることや、C#を使って処理を書けることを示しました。そして、 UWP の醍醐味でもある、デスクトップとモバイルで同じアプリケーションが動くということ も示しました。ちょっとした Hello world ですが、色々な物が詰まっています。 3. XAML ここでは、UWP の画面構築に使用する XAML という言語についてみていきます。XAML は、 Hello world の章でデザイナの下に表示されていたもので、XML をベースにして作られた言語 になります。XAML は、画面構築専用の言語ではなくて、汎用的に使えるオブジェクトを組み 立てるための言語になります。ツリー構造を持ったオブジェクトの構築に必要な機能が色々詰 まっています。画面は、Page をルートとしたツリー構造のオブジェクトのため、XAML で記 述するのに、とても適している言語です。 XAML は、XML 名前空間を C#の名前空間に、タグをクラス名に、属性をプロパティ名に対応 させています。また、XML 名前空間には、いくつかの組み込みのものが定義されていて、それ
  • 26. 26 らには x や d や mc などの名前を付けることが一般的です。一般的な Page(UWP での画面を あらわすクラス)の XAML での定義は以下のようになります。 <Page x:Class="XamlBasics.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> </Page> 4 つの XML 名前空間が定義されています。まずは、XAML で定義する名前空間と、様々な便 利機能が定義されている x 名前空間と、デザイナ向けの機能を提供する d 名前空間です。mc 名前空間は、mc:Ignorable で実行時には無視する名前空間を指定するために定義されていま す。x:Class 属性は、コードビハインドクラスのクラス名をあらわしています。この、x:Class 属性で、XAML と裏のロジックのクラスの結び付けが行われています。この形が UWP で扱う XAML の基本的な形になります。 この XAML に紐づくコードビハインドは、以下のようになっています。 using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; namespace XamlBasics { public sealed partial class MainPage : Page { public MainPage() { this.InitializeComponent(); } } }
  • 27. 27 XAML のタグが Page タグなので、Page クラスを継承している点がポイントです。また、 XAML で定義された設定を有効化するために、コンストラクタで InitializeComponent メソッ ドを呼び出している点もポイントになります。 以下に XAML の基本機能を使った XAML を示します。 <Page x:Class="XamlBasics.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:XamlBasics" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Page.Content> <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}"> <Grid.Children> <Button Content="Hello world" Click="Button_Click" /> </Grid.Children> </Grid> </Page.Content> </Page> まず、Button タグに注目してみましょう。Button の Content 属性に Hello world を指定してい ます。これは、Button クラスのインスタンスの Content プロパティに Hello world という文字 列を設定していることになります。このように、とても直感的に属性を使ってプロパティを設 定可能です。また、もう 1 つ Click 属性がありますが、こちらはイベントになります。イベン トでは、コードビハインドで対応するメソッドの名前を定義することで、イベントに対してメ ソッドを追加することが出来ます。 次に、Page と Grid の関係について注目してみましょう。先ほどの Button の例のように、単純 な文字列や数値の場合は属性を使ってプロパティの値を指定できますが、プロパティに設定し たいものが Button や Grid といった他のクラスのインスタンスだった場合に、特別な命名規約 に沿ったタグを使うとプロパティを設定できます。命名規約は、「クラス名.プロパティ名」と
  • 28. 28 いうタグになります。このような命名規約のタグを使うことで、タグの子要素のオブジェクト をプロパティに設定することができます。この構文のことを、「プロパティ要素の構文」とい います。 次に、Grid の Background 属性で指定されている{}で囲まれた部分です。これは「マークアッ プ拡張」といって単純な文字列では指定できないようなオブジェクトを設定するための構文に なります。StaticResource は、後程説明しますが、UWP のリソースと呼ばれるところから、オ ブジェクトを取得してきます。その他に{x:Null}などで null を渡すといったことも可能です。 次にコンテンツ構文です。コンテンツ構文は、オブジェクトに対して 1 つだけ指定可能なコン テンツプロパティというものを、タグの直下に書くことでコンテンツプロパティに自動で設定 出来るものです。例えば、Page では Content プロパティがコンテンツプロパティに指定されて います。また、Grid は Children プロパティがコンテンツプロパティに指定されています。そ のため、先ほどの XAML は、以下のようにシンプルに記述できます。 <Page x:Class="XamlBasics.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:XamlBasics" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}"> <Button Content="Hello world" Click="Button_Click" /> </Grid> </Page> その他の構文として、コレクション構文というものがあります。例えば、Grid の Children は、コレクション型なのですが、ここに複数のタグを追加するとコレクションに複数格納され ます。例えば、Grid に Button を 2 つ以上置くことが出来ます。例えば以下のように書きま す。 <Page x:Class="XamlBasics.MainPage"
  • 29. 29 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:XamlBasics" xmlns:d=http://schemas.microsoft.com/expression/blend/2008tugini xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}"> <Button Content="Hello world" Click="Button_Click" /> <Button VerticalAlignment="Top" Content="Button2" /> <Button VerticalAlignment="Bottom" Content="Button3" /> </Grid> </Page> 次に、任意の名前空間にあるオブジェクトを XAML に組み込む方法を紹介します。XAML は、XML 名前空間を C#の名前空間と対応づけることができます。対応づけかたは、上記の XAML 内の local という XML 名前空間にあるとおり、「using:名前空間」という形の書式にな ります。例えば XamlBasics という名前空間に Person という名前のクラスがある場合、以下の ように記述できます。 <local:Person /> 次に、添付プロパティという機能を紹介します。添付プロパティは、名前の通りオブジェクト 自体には定義されていないプロパティを追加で設定できる機能になります。UWP 上では、主 にコントロールのレイアウトに必要な情報をコントロールに追加するために使用されていま す。例えば、Grid コントロールは、行と列を指定してコントロールを何処に配置するのか指定 できるのですが、そこで、以下のように使用されています。 <Page x:Class="XamlBasics.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:XamlBasics" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  • 30. 30 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}"> <Grid.RowDefinitions> <!-- 行の定義 --> <RowDefinition /> <RowDefinition /> </Grid.RowDefinitions> <!-- Grid の 0 行目、1 行目に配置 --> <Button Content="Layout sample" Grid.Row="0" /> <Button Content="Hello world" Grid.Row="1" /> </Grid> </Page> Button タグの Grid.Row という属性で指定している箇所が添付プロパティにあたります。 Button に Grid が持っている Row という添付プロパティの値を設定しています。このように、 他のクラスで定義されたプロパティの値を設定できる点が特徴になります。 最後に、マークアップ拡張について説明します。マークアップ拡張は、複雑なオブジェクトを 簡単に記述するための記法になります。{}で囲んで記述します。例えば{x:Null}とすることで、 null をあらわすことが出来ます。その他に、データバインディングの章で紹介しますが、 {Binding Path=Name}などのようなデータバインディングオブジェクトの生成や、リソースの 参照を行うための{StaticResource KeyName}のようなものがあります。マークアップ拡張のそ れぞれの意味については、各章で後述します。 4. UWP のコントロールの基本クラス ここでは、UWP のコントロールの基本クラスである、DependencyObject について説明を行い ます。 4.1. DependencyObject
  • 31. 31 DependencyObject は、UWP のコントロールに必要な基本的な機能を提供します。提供する機 能は以下の通りです。 1. 依存関係プロパティ 2. 添付プロパティ 3. スレッド操作 順に説明していきます。 4.1.1. 依 存 関係 プ ロ パ テ ィ 依存関係プロパティは、Windows Runtime で使用される特殊なプロパティで、デフォルト値の 提供や、プロパティの値に変更があったときに別のプロパティへの値の伝搬や、アニメーショ ンのサポートや、データバインディングのサポートなど様々な機能を持ったプロパティです。 具体的には、以下のように実装されます。 public class Range : Windows.UI.Xaml.DependencyObject { // プロパティのキー public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(int), typeof(Range), new PropertyMetadata(0, ValueChanged)); // CLR のプロパティとしてラッピング public int Value { get { return (int)GetValue(ValueProperty); } set { SetValue(ValueProperty, value); } } private static void ValueChanged(Windows.UI.Xaml.DependencyObject d, DependencyPropertyChangedEventArgs e) { // 変更があったときの処理
  • 32. 32 } } まず、クラスが DependencyObject クラスを継承していることが必要となります。そして、 DependencyProperty クラスの Register メソッドで依存関係プロパティを登録します。引数 は、プロパティ名、プロパティの型、プロパティを所有する型、メタデータになります。メタ データは、PropertyMetadata 型でコンストラクタの引数は、プロパティのデフォルト値と、プ ロパティに変更があったときのコールバック(コールバックの指定はオプション)になりま す。コールバックは、static なメソッドで、第一引数に値が変更されたオブジェクトと、プロ パティの変更後の値と変更前の値を持ったイベント引数というシグネチャになります。依存関 係プロパティ自体には必須ではないのですが、CLR のプロパティの形(要は普通の C#のプロ パティ)にラップするのが一般的です。こうすることで、コード上から自然にアクセスが可能 になります。CLR のプロパティの形式を使用しない場合と使用する場合のコードを以下に示し ます。 var r = new Range(); // CLR のプロパティを使用しない場合 r.SetValue(Range.ValueProperty, 10); var value = (int)r.GetValue(Range.ValueProperty); // CLR のプロパティのラッパを使用する場合 r.Value = 100; var value2 = r.Value; 依存関係プロパティの PropertyMetadata のコールバックを使うことで、プロパティの値に変更 があったときに、他のプロパティの値に状態を伝搬するなどの処理を書くことが出来ます。例 として Range クラスで、Min と Max プロパティを追加して、Value が必ず Min と Max の間に あるように調整する処理を追加したコードを以下に示します。 public class Range : Windows.UI.Xaml.DependencyObject { // プロパティのキー public static readonly DependencyProperty ValueProperty =
  • 33. 33 DependencyProperty.Register("Value", typeof(int), typeof(Range), new PropertyMetadata(0, ValueChanged public static readonly DependencyProperty MinProperty = DependencyProperty.Register("Min", typeof(int), typeof(Range), new PropertyMetadata(int.MinValue, Min public static readonly DependencyProperty MaxProperty = DependencyProperty.Register("Max", typeof(int), typeof(Range), new PropertyMetadata(int.MaxValue, Max // CLR のプロパティとしてラッピング public int Value { get { return (int)GetValue(ValueProperty); } set { SetValue(ValueProperty, value); } } public int Min { get { return (int)GetValue(MinProperty); } set { SetValue(MinProperty, value); } } public int Max { get { return (int)GetValue(MaxProperty); } set { SetValue(MaxProperty, value); } } // コールバック private static void ValueChanged(Windows.UI.Xaml.DependencyObject d, DependencyPropertyChangedEventArgs e { ((Range)d).CourceValue(); }
  • 34. 34 private static void MinChanged(Windows.UI.Xaml.DependencyObject d, DependencyPropertyChangedEventArgs e) { ((Range)d).CourceMin(); ((Range)d).CourceValue(); } private static void MaxChanged(Windows.UI.Xaml.DependencyObject d, DependencyPropertyChangedEventArgs e) { ((Range)d).CourceMax(); ((Range)d).CourceValue(); } // 値を調整するメソッド private void CourceMax() { if (this.Max < this.Min) { this.Max = this.Min; } } private void CourceMin() { if (this.Min > this.Max) { this.Min = this.Max; } } private void CourceValue() { if (this.Max < this.Value)
  • 35. 35 { this.Value = this.Max; } if (this.Min > this.Value) { this.Value = this.Min; } } } このクラスを使って以下のようなコードを記述して動作を確認してみます。 var range = new Range(); Debug.WriteLine($"Min: {range.Min}, Max: {range.Max}, Value: {range.Value}"); range.Min = 0; range.Max = 10; range.Value = 100; Debug.WriteLine($"Min: {range.Min}, Max: {range.Max}, Value: {range.Value}"); range.Max = -1; Debug.WriteLine($"Min: {range.Min}, Max: {range.Max}, Value: {range.Value}"); 実行するとデバッグ時の出力ウィンドウに以下の結果が表示されます。 Min: -2147483648, Max: 2147483647, Value: 0 Min: 0, Max: 10, Value: 10 Min: 0, Max: 0, Value: 0 4.1.2. 添 付 プロ パ テ ィ 次に、XAML でも紹介した添付プロパティについて説明します。添付プロパティは XAML で 説明した通り、オブジェクトに対して別のクラスで定義されたプロパティを取得または設定で きる機能になります。DependencyObject では、以下のようにして添付プロパティを定義しま す。
  • 36. 36 public class AttachedPropertySample { public static readonly DependencyProperty SampleValueProperty = DependencyProperty.RegisterAttached("SampleValue", typeof(int), typeof(AttachedPropertySample), new PropertyMetadata(0)); public static int GetSampleValue(Windows.UI.Xaml.DependencyObject obj) { return (int)obj.GetValue(SampleValueProperty); } public static void SetSampleValue(Windows.UI.Xaml.DependencyObject obj, int value) { obj.SetValue(SampleValueProperty, value); } } DependencyProperty クラスの RegisterAttached メソッドで DependencyProperty クラスのイ ンスタンスを作成する点と、添付プロパティは、CLR の形式のプロパティではなく、static な SetXXX と GetXXX という名前でラッパーを作るという点が異なります。また、添付プロパテ ィを定義するクラスは、必ずしも DependencyObject を継承する必要はありません。 先ほどの Range クラスに、SampleValue 添付プロパティの値を設定して取得するコードは以下 のようになります。 var range = new Range(); // 添付プロパティの値の設定と取得 AttachedPropertySample.SetSampleValue(range, 100); var sampleValue = AttachedPropertySample.GetSampleValue(range); 添付プロパティも PropertyMetadata を使ってデフォルト値とコールバックが指定できます。コ ールバックを使うことで依存関係プロパティと同じように、別のプロパティに対して変更を伝 搬することが出来ます。 4.1.3. ス レ ッド 操 作
  • 37. 37 DependencyObject は、生成されたスレッドに紐づくという特徴があります。別スレッドから 依存関係プロパティなどの操作を行うと例外が発生します。そのため、UWP のコントロール は UI 用のスレッド(UI スレッド)に紐づけられていて、その他のスレッドから操作すること が出来なくなっています。例えば、バックグラウンドでデータを読み込んで UI に反映すると いった処理で、この特徴が問題になってきます。そのようなケースに対応するため、 DependencyObject には、自分が生成されたスレッドに紐づく CoreDispatcher というクラスを 保持しています。このオブジェクトには DependencyObject の Dispatcher プロパティからアク セスが出来ます。CoreDispatcher クラスには、CoreDispatcher が紐づくスレッドで処理を行う ための RunAsync メソッドが定義されていて、以下のように記述することでスレッドを切り替 えて処理をすることが出来ます。 await range.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => { // DependencyObject の紐づけられたスレッドで処理を行える }); 第一引数の CoreDiapatcherPriority は処理の実行の優先度で以下の値を指定できます。  Idle 一番優先度が低い。アイドル状態のときに実行される。  Low 低い優先順位。自分より高い優先順位の処理がないと実行される。  Normal 普通の優先順位。順番に実行されます。  High 最高の優先順位。ユーザーアプリケーションでの使用はしない。 4.2. FrameworkElement UWP のコントロールの多くがこのクラスを継承しています。このクラスは、レイアウトや XAML を使ったプログラミングで重要になるデータバインディングや、見た目を共通化するた めの Style や、リソースと呼ばれるデータを定義しておく場所の機能などを提供しています。
  • 38. 38 レイアウトに関するプロパティとして Margin というプロパティがあります。このプロパティ を指定することで、コントロールの内側に余白を設けることが出来ます。例えば Button に余 白を設ける場合は以下のように XAML を記述します。 <Button Margin=”10,5,10,5” Content=”Hello” /> マージンは、左、上、右、下の順番でカンマで区切って指定します。以下のように余白が設定 されます。(黒枠がマージンの外側) リソースは、Resources プロパティとして定義され、そこにブラシや Style などの様々なオブジ ェクトの名前を付けて登録することが出来ます。リソースに定義されたオブジェクトは、 StaticResource マークアップ拡張によって XAML から取得できます。例えば、SolidColorBrush と言う単色塗りつぶしのブラシを定義して、ボタンから参照するコードは以下のようになりま す。 <Page x:Class="XamlBasics.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:XamlBasics" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Page.Resources> <SolidColorBrush x:Key="Brush" Color="Red" /> </Page.Resources> <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}"> <Button Content="Hello" Background="{StaticResource Brush}" />
  • 39. 39 </Grid> </Page> 赤色のブラシを Brush という名前(x:Key で指定)で定義して、それをボタンの背景色に StaticResource マークアップ拡張を使って指定しています。StaticResource で参照できる値は、 StaticResource を使う場所よりも親のコントロールで定義されている必要があります。例え ば、上記の Brush という名前のリソースを取得する場合は、Button よりも上の階層である Page の Resources で定義されているため取得できています。また、StaticResource マークアッ プ拡張は、親へ親へ Resources を探索していくので、同じ名前のリソースが定義されていた場 合は、より自分に近い場所のリソースを参照します。Page まで親へさかのぼって見つからない 場合は、App クラスの Resources で定義されたものを参照します。App クラスでも見つからな い場合は、組み込みで定義されているリソースを参照します。 4.3. Control FrameworkElement を拡張し、コントロールに必要な基本的な機能を提供します。自分でカス タムコントロールを提供する場合に、このクラスを継承することがあります。主な提供機能は コントロールの見た目を自由に変更することが出来る Template という機能になります。 4.4. ContentControl 単一の要素を表示するためのコントロールになります。Page や Button や UserControl など多 くのコントロールが、このコントロールを継承しています。ContentControl は、Content プロ パティに設定されたデータを非常に柔軟に表示する能力を持っていて、文字列が設定されてい れば文字列を表示し、コントロールが設定されていれば、コントロールを表示します。任意の オブジェクトを表示することも可能で、その場合 ContentTemplate というテンプレートを使っ て見た目を定義できます。また、ContentTemplateSelector などを使うことでオブジェクトを どのように表示するかということをカスタマイズすることも可能です。 4.5. ItemsControl ItemsControl は複数の要素を表示するためのコントロールになります。ItemsSource プロパテ ィに設定された IEnumerable に対して要素を表示します。表示される 1 要素ずつは ContentControl を継承したクラスにホストされ ContentControl で説明したように柔軟に要素
  • 40. 40 を表示することが出来ます。ListBox、ListView などの複数の要素を表示するコントロールは 基本的にこのコントロールを継承しています。 ItemsControl は、INotifyCollectionChanged を実装しているコレクション(厳密には IList も必 要)を ItemsSource に設定することで、コレクションの要素の追加や削除に表示を追随させる ことが出来ます。この INotifyCollectionChanged のデフォルトの実装クラスとして System.Collections.ObjectModel.ObservableCollection<T>クラスが提供されています。このク ラスを ItemsSource に設定することで、コレクションの追加・削除に簡単に追随させることが 出来るようになります。 基本的には、要素は縦に並ぶように配置されますが、ItemsPanel を変更することで縦ならびを 横ならびに変更できます。具体的には以下のような XAML を記述します。 <ItemsControl> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <!-- 横並びにする --> <StackPanel Orientation="Horizontal" /> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> </ItemsControl> このように、ItemsControl は ContentControl のような柔軟な表示をしつつ、ItemsPanel を使 って並びを柔軟に対応できるような作りになっています。 4.6. Panel Panel は、複数のコントロールをホストすることが出来るコントロールです。UWP のレイアウ トシステムによって、ホストしたコントロールを柔軟に配置することが出来ます。Canvas(絶 対座標での要素の配置)、Grid(テーブルレイアウト)、StackPanel(縦や横に積み上げる形 で配置)、RelativePanel(相対位置による配置)などのコントロールがあります。これらのコ ントロールは Children というプロパティにコントロールを格納して使います。Children プロパ ティは XAML で説明したコンテンツコントロールになっているため、以下のようにタグの下に 直接別のコントロールを記述することが出来ます。
  • 41. 41 <StackPanel> <Button Content=”Button1” /> <Button Content=”Button2” /> <Button Content=”Button3” /> </StackPanel> 5. データバインディング 著者が UWP(XAML を使った)アプリケーションで非常に重要な要素と考えるデータバイン ディングについて説明します。この機能を使いこなすことで、見た目とロジックを綺麗に切り 離したアプリケーションを作ることが出来ます。 UWP のデータバインディングには 2 種類のものが存在します。WPF の頃から存在する実行時 データバインディングと、UWP に追加されたコンパイル時データバインディングになりま す。順番に解説していきます。 5.1. 実 行 時デ ー タ バ イ ンデ ィ ン グ 実行時データバインディングは、FrameworkElement で実装されている機能になります。 DataContext というプロパティに格納されたオブジェクトと、コントロールのプロパティの値 の同期をとる機能になります。(厳密にいうと Binding の Source に設定されたオブジェクトの プロパティと、コントロールのプロパティの同期をとる機能になります。何も指定しないとデ フォルトの Binding の Source が DataContext になります。)同期の取り方には、以下の 3 種 類が存在します。 1. OneWay(デフォルト) DataContext に設定されたオブジェクトのプロパティ(ソースと言います)からコントロ ールのプロパティ(ターゲットと言います)に対する 1 方向の値の同期になります。ソー スの値の変更を感知したらターゲットの値が更新されます。ソースの値の変更の感知は、 DependencyProperty の場合は自動的に、そうでない場合は INotifyPropertyChanged の PropertyChanged イベントにより検知を行います。
  • 42. 42 2. TwoWay ソースからターゲットの間を双方向に同期を取ります。ソースからターゲットへの同期の タイミングは OneWay と同じです。 3. OneTime 初回の 1 度だけソースからターゲットに対して値の同期を取ります。 実行時データバインディングには Binding マークアップ拡張を使います。例えば以下のような Person という名前のクラスがあるとします。 public class Person : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private string name; public string Name { get { return this.name; } set { this.name = value; this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Name))); } } private int age; public int Age { get { return this.age; } set { this.age = value; this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Age)));
  • 43. 43 } } } Name と Age プロパティを持っていて、INotifyPropertyChanged インターフェースによる変更 通知を実装しています。これを Page の DataContext に以下のように設定します。 <Page x:Class="RuntimeDataBinding.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:RuntimeDataBinding" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Page.DataContext> <local:Person /> </Page.DataContext> <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> </Grid> </Page> Grid を StackPanel(子要素を縦や横に並べて表示するコントロール)に置き換えて、以下のよ うに TextBox と TextBlock を置いてデータをバインドさせます。 <Page x:Class="RuntimeDataBinding.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:RuntimeDataBinding" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Page.DataContext> <local:Person /> </Page.DataContext>
  • 44. 44 <StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <TextBox Text="{Binding Path=Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> <TextBlock Text="{Binding Path=Name}" /> <TextBox Text="{Binding Path=Age, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> <TextBlock Text="{Binding Path=Age}" /> </StackPanel> </Page> 最初の TextBox と TextBlock の組が Name プロパティへのデータバインディングで、2 つ目の TextBox と TextBlock の組が Age プロパティへのデータバインディングになります。実行する と TextBox と TextBlock の値が Person クラスを通して同期されていることが確認できます。 Binding マークアップ拡張には、以下のようなプロパティが設定出来ます。  Path ソースのプロパティを指定します。「プロパティ 1.プロパティ 2」のようにオブジェクト
  • 45. 45 を辿るように Path を記述することが出来ます。また、配列などの「プロパティ 1[0]」記 法にも対応しています。Path プロパティは、Binding マークアップ拡張の最初に書く場合 は、省略することが可能です。つまり先ほどのコードの例は「{Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}」のように記述することが出来 ます。  Mode OneWay, TwoWay, OneTime を指定します。  UpdateSourceTrigger Default, PropertyChanged, Explicit を指定します。通常、Default は PropertyChanged と 同様の意味になります。TextBox の Text に Binding するときは、Default はフォーカスが 外れた時に値の同期をとります。テキストが変化する度に値の同期をとる場合は上記の例 のように明示的に PropertyChanged を指定します。Explicit を指定した場合は BindingExpression の UpdateSource メソッドを呼び出したタイミングで同期が取られま す。  Converter ソースからターゲットと、ターゲットからソースへ値が同期されるときに値の変換ロジッ クをあらわす IValueConverter を実装したクラスを指定します。  ConverterParameter Converter に渡すパラメータを指定します。  ElementName データバインディングのソースに x:Name で名前を付けたコントロールを指定する場合に 使用します。  FallbackValue バインディングで値を返せない場合に返す値を指定します。  TargetNullValue ターゲットの値が null の時に返す値を指定します。
  • 46. 46  RelativeSource バインディングのソースを相対的に指定します。以下の 2 種類の指定方法があります。 {Binding …, RelativeSource={RelativeSource TemplatedParent}} {Binding …, RelativeSource={RelativeSource Self}} TemplatedParent は、ControlTemplate と呼ばれるコントロールの見た目を定義する場所 で使用します。コントロール自身がソースとなります。 Self は、ターゲットの要素をバインディングのソースに指定します。  Source バインディングのソースを指定します。何も指定しない場合はデフォルトで DataContext プロパティの値が使われます。 ElementName などを使ったデータバインディングの例を以下に示します。まず、以下のよう な IValueConverter インターフェースを実装したクラスを定義します。 public class SanConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, string language) { // ソースからターゲット return $"{value}さん"; } public object ConvertBack(object value, Type targetType, object parameter, string language) { // ターゲットからソース方向 // ここでは未サポート throw new NotSupportedException(); } } Converter は、FrameworkElement で紹介したリソースに定義して使用します。では、TextBox に入力した値を使って「○○さん」と表示する TextBlock を作成してみます。 <Page x:Class="RuntimeDataBinding.MainPage"
  • 47. 47 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:RuntimeDataBinding" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Page.Resources> <local:SanConverter x:Key="SanConverter" /> </Page.Resources> <StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <TextBox x:Name="TextBox" /> <TextBlock Text="{Binding Text, ElementName=TextBox, Converter={StaticResource SanConverter}}" /> </StackPanel> </Page> 実行すると、以下のように TextBox の入力に同期して、TextBlock の値が書き換わります。 あまりやる機会はないですが、実行時データバインディングは C#のコードからも設定するこ とが出来ます。例えば、Name というプロパティと TextBox の Text をバインディングする場 合は以下のようなコードになります。 var binding = new Binding { Path = new PropertyPath("Name"), Mode = BindingMode.TwoWay, UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged };
  • 48. 48 this.TextBox.SetBinding(TextBox.TextProperty, binding); Binding クラスのインスタンスを生成して、Path や Mode などのプロパティを設定したあと に、ターゲットとなるオブジェクトの SetBinding メソッドで、バインディングのターゲットと なる依存関係プロパティ(添付プロパティも可)と、Binding オブジェクトを指定します。 5.2. コ ン パイ ル 時 デ ー タバ イ ン ディ ン グ 実行時データバインディングは、バインディングを実行時に解決しますが、コンパイル時デー タバインディングは、コンパイル時にバインディングの解決を行います。コンパイル時データ バインディングの特徴を以下に示します。  実行時ではなくコンパイル時にバインディングの情報が確定するため実行時データバイン ディングに比べて高速  バインディングのソースが、DataContext ではなく Page になっている  デフォルトの Mode が OneTime になっている 実行時データバインディングとの大きな違いは以上のようになります。コンパイル時データバ インディングには、{x:Bind …}というマークアップ拡張を使います。TextBox と TextBlock を バインドするコードの例を以下に示します。 <Page x:Class="CompileTimeDataBinding.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:CompileTimeDataBinding" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <TextBox x:Name="TextBox" /> <TextBlock Text="{x:Bind TextBox.Text, Mode=TwoWay}" /> </StackPanel> </Page>
  • 49. 49 x:Name 属性を使って、TextBox を Page のメンバーとして定義しています。そのため、 TextBlock で定義している x:Bind から TextBox という名前で参照できます。実行すると、以下 のようになります。 コンパイル時データバインディングで指定可能なプロパティは以下の通りです。  Path  Mode  TargetNullValue  FallbackValue  Converter  ConverterParameter 各パラメータについては実行時データバインディングと、ほぼ同じになります。また、x:Bind の特徴として、イベントハンドラをバインドできるという点があります。イベントハンドラの バインドは、以下のシグネチャのメソッドに対して行えます。 void Foo(); void Foo(object sender, object eventArgs); void Foo(object sender, XXXXEventArgs eventArgs); // 各イベントのイベント引数の型 例として、以下のようなクラスをバインドしてみたいと思います。 public class Person : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged;
  • 50. 50 private string name; public string Name { get { return this.name; } set { this.name = value; this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Name))); } } public void ResetName() { this.Name = null; } } XAML を以下に示します。 <Page x:Class="CompileTimeDataBinding.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:CompileTimeDataBinding" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Page.Resources> <local:Person x:Name="Person" /> </Page.Resources> <StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <TextBox Text="{x:Bind Person.Name, Mode=TwoWay, TargetNullValue='未入力'}" /> <TextBlock Text="{x:Bind Person.Name, Mode=OneWay}" /> <Button Content="Reset"
  • 51. 51 Click="{x:Bind Person.ResetName}" /> </StackPanel> </Page> Page の Resources で x:Name を使って Page のメンバーとして Person を定義しています。コー ドビハインドで以下のように定義するのと同じようなイメージになります。 public sealed partial class MainPage : Page { public Person Person { get; } = new Person(); } そして、TextBox や TextBlock と Name プロパティをバインドしています。イベントのバイン ドは Button の Click イベントで行っています。Person クラスに定義した ResetName メソッド をバインドしています。実行すると以下のようになります。 TextBox に入力すると、Person クラスの Name プロパティを介して TextBlock に値が同期され ます。(コンパイル時データバインディングの TextBox の Text プロパティへのバインディング は特殊で、フォーカスが外れたときに値の同期が行われます)
  • 53. 53 この他に、コンパイル時データバインディングは実行時にコードから設定できないという点が 実行時データバインディングと異なります。 6. アプリケーションライフサイクル UWP アプリは、デスクトップアプリケーションよりスマートフォンアプリケーションのよう なライフサイクルで動作します。具体的に言うと、デスクトップではアプリケーションは最小 化すると休止状態に移行して、メモリの使用状況によっては OS によってアプリケーションが 終了されることがあります。この終了はアプリケーションから検知することが出来ないため、 休止状態に入るときに終了されてもいいようにアプリケーションで備える必要があります。モ バイルでは、バックグラウンドに回ったときに、休止状態に入ります。この UWP のライフサ イクルを図にすると以下のようになります。 アプリケーションの起動は、プロジェクトの App クラスの OnLaunched メソッドがエントリ ーポイントとなります。このとき、引数の LaunchActivatedEventArgs に直前のアプリの状態 (終了状態だったのかなど)が入っているので、それを見て必要に応じて復帰処理などを行い ます。 6.1. ア プ リケ ー シ ョ ン の起 動 シ ーケ ン ス
  • 54. 54 アプリケーションは、LaunchActivatedEventArgs の PreviousExecutionState の値を見て起動時 の処理を適切に行う必要があります。PreviousExecutionState には、以下の値が格納されてい ます。  NotRunning アプリケーションは実行されていなかった。  Running アプリケーションは実行中。  Suspended アプリケーションは中断状態だった。  Terminated アプリケーションは中断後に終了された。  ClosedByUser アプリケーションはユーザーによって終了された。 アプリケーションの起動時に行わないといけないことは、新規作成したひな形の App クラスに 定義されています。OnLaunched メソッドから不要な処理やコメントを除いたものを以下に示 します。 protected override void OnLaunched(LaunchActivatedEventArgs e) { Frame rootFrame = Window.Current.Content as Frame; if (rootFrame == null) { rootFrame = new Frame(); if (e.PreviousExecutionState == ApplicationExecutionState.Terminated) { //TODO: 以前中断したアプリケーションから状態を読み込みます }
  • 55. 55 Window.Current.Content = rootFrame; } if (e.PrelaunchActivated == false) { if (rootFrame.Content == null) { rootFrame.Navigate(typeof(MainPage), e.Arguments); } Window.Current.Activate(); } } UWP アプリは、Window.Current を通じてアプリの Window にアクセスできます。この Window の Content プロパティに Frame という画面遷移機能を持ったコントロールを配置し て、その中で画面遷移を行います。Window.Current.Content に値が設定されていないという ことは、終了状態からの起動ということなので、Frame を新規作成して設定します。さらに先 ほど説明した PreviousExecutionState を確認して Terminated の時に、直前の中断時に保存し たデータを使って復元を行います。最後に PrelaunchActivated で直前のアクティブ化状態を確 認して、アクティブでない場合は、必要に応じて画面遷移(Frame の Navigate メソッド)を行 い、自分自身をアクティブ化します。 以上が、アプリケーションの基本的な起動シーケンスになります。 6.2. サ ス ペン ド 時 の 処 理 アプリケーションがサスペンドされるときには、App クラスで Suspending イベントが発生し ます。デフォルトで作成されている App クラスではコンストラクタで Suspending イベントを 購読して、OnSuspending メソッドが呼ばれるようになっています。 public App() { this.InitializeComponent(); this.Suspending += OnSuspending;
  • 56. 56 } private void OnSuspending(object sender, SuspendingEventArgs e) { var deferral = e.SuspendingOperation.GetDeferral(); //TODO: アプリケーションの状態を保存してバックグラウンドの動作があれば停止します deferral.Complete(); } e.SuspendingOperation.GetDeferral メソッドの呼び出しから Complete メソッドの間で保存処 理を行います。この GetDeferral で取得したオブジェクトの Complete メソッドを呼び出すと 中断時の状態保存が終わったということを通知したことになります。 6.3. サ ス ペン ド か ら の 復帰 あまり利用することはありませんが、サスペンド状態からアプリケーションが終了されないま まフォアグラウンドに復帰したときに呼び出される処理があります。App クラスで Resuming イベントを購読することで処理が出来ます。 6.4. ア プ リケ ー シ ョ ン ライ フ サ イク ル に 対 応 した サ ン プル ここでは、簡単な中断処理に対応したアプリケーションを作成したみたいと思います。 LifecycleApp という名前でアプリケーションを作ります。そして、以下のようなクラスを作成 します。 using System.ComponentModel; namespace LifecycleApp { public class LifecycleAppModel : INotifyPropertyChanged { public static LifecycleAppModel Instance { get; } = new LifecycleAppModel(); public event PropertyChangedEventHandler PropertyChanged; private string value;
  • 57. 57 public string Value { get { return this.value; } set { this.value = value; this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Value))); } } } } このクラスを使って簡単なページを作成します。TextBox にデータを表示するだけの単純なペ ージにします。MainPage.xaml.cs に以下のようなプロパティを定義します。 public sealed partial class MainPage : Page { public LifecycleAppModel Model { get; } = LifecycleAppModel.Instance; public MainPage() { this.InitializeComponent(); } } MainPage.xaml を以下のように編集して LifecycleAppModel の Value と TextBox の Text をバ インドします。 <Page x:Class="LifecycleApp.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:LifecycleApp" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  • 58. 58 mc:Ignorable="d"> <StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <TextBox Text="{x:Bind Model.Value, Mode=TwoWay}" /> </StackPanel> </Page> この状態でアプリケーションが中断されたときにどう動くか確認してみます。アプリケーショ ンをデバッグ起動して、Visual Studio のツールバーで右クリックして「デバッグの場所」にチ ェックを入れます。(チェックが入っている場合は、そのままで大丈夫です)
  • 60. 60 MainPage の TextBox に任意の文字列を入力して「中断とシャットダウン」をします。そし て、再度アプリケーションを起動すると、TextBox の文字が消えていることが確認できます。 ユーザーからしたら、最小化(モバイルの場合はバックグラウンドに回した)したアプリの入 力がクリアされてしまったという挙動になります。これを中断処理に対応して改善します。ま ず、App クラスの OnSuspending メソッドで ApplicationData.Current.LocalSettings を使って データの保存を行います。ApplicationData.Current.LocalSettings.Values(ローカルにデータを 保存するための Dictionary)に InputValue をキーにして LifecycleAppModel の Value プロパテ ィの値を保存します。 private void OnSuspending(object sender, SuspendingEventArgs e) { var deferral = e.SuspendingOperation.GetDeferral(); ApplicationData.Current.LocalSettings.Values["InputValue"] = LifecycleAppModel.Instance.Value; deferral.Complete(); } 次に、OnLaunched メソッドの Terminated の if 文に、この保存したデータを読み込む処理を 追加します。 if (e.PreviousExecutionState == ApplicationExecutionState.Terminated) { if (ApplicationData.Current.LocalSettings.Values.ContainsKey("InputValue")) { LifecycleAppModel.Instance.Value = (string) ApplicationData.Current.LocalSettings.Values["InputValue"];
  • 62. 62  一時アプリデータ アプリデータの保存方法には、設定とファイルという 2 種類があります。設定は、int や string などの基本的な型や DateTime 型や GUID 型などを保存することが出来るディクショナリのよ うな形で提供されます。ファイルは、任意のファイル形式でデータを保存することが出来ま す。 7.1. ロ ー カル ア プ リ デ ータ ローカルアプリデータは、ApplicationData.Current.LocalSettings で設定にアクセスできます。 ApplicationData.Current.LocalFolder でファイルを保存するためのフォルダにアクセスできま す。まず、設定についてみていきます。 設定の一番簡単な使い方は、Values プロパティにディクショナリのようにアクセスすることで す。コード例を以下に示します。 var settings = ApplicationData.Current.LocalSettings; settings.Values["Key"] = "Value"; var value = (string)settings.Values["Key"]; if (settings.Values.ContainsKey("Key")) { // Key が存在する場合 } else { // Key が存在しない場合 } // 削除 settings.Values.Remove(“Key”); ApplicationDataCompositeValue というクラスを使うことで、値をまとめて管理することが出 来ます。以下のようなコードになります。 var settings = ApplicationData.Current.LocalSettings; var composite = new ApplicationDataCompositeValue();
  • 63. 63 composite["Key1"] = "Value1"; composite["Key2"] = "Value2"; settings.Values["compositeValue"] = composite; この他に、ApplicationDataContainer を使って、データを階層化して管理することが出来ま す。この階層は 32 階層まで作成することが出来ます。 var settings = ApplicationData.Current.LocalSettings; // 作成 var container = settings.CreateContainer("Container1", ApplicationDataCreateDisposition.Always); // 値の設定 container.Values["Key1"] = "Value1"; // 存在確認 if (settings.Containers.ContainsKey("Container1")) { // 存在するとき } else { // 存在しないとき } // 削除 settings.DeleteContainer("Container1"); 設定は手軽に使えますが、ファイルを使って任意の形式でローカルアプリデータにデータを保 存することもできます。ファイルにアクセスするコードは以下のようになります。 // フォルダを取得 var folder = ApplicationData.Current.LocalFolder; // ファイルを作成する(存在する場合は置き換える) var file = await folder.CreateFileAsync("sample.txt", CreationCollisionOption.ReplaceExisting); // ファイルに出力する await FileIO.WriteTextAsync(file, "Hello world"); // ファイルから読み込む var data = FileIO.ReadTextAsync(file);
  • 64. 64 ApplicationData.Current.LocalFolder に対して、CreateFileAsync を呼び出すことでファイルを 作成できます。第一引数がファイル名で、第二引数でファイルが存在したときの挙動などを指 定します。上記コードでは、ReplaceExisting を指定して、ファイルが既に存在する場合は、新 しいもので置き換えるという指定をしています。 ファイルの読み書きは FileIO クラスの WriteTextAsync メソッドと ReadTextAsync を使いま す。JSON.NET などの.NET のクラスライブラリと連携するためには System.IO.Stream が必要 になるケースがあります。これは、ファイルの拡張メソッドを使うことで取得が可能になって います。 // 書き込み using (var stream = await file.OpenStreamForWriteAsync()) { // JSON.NET などを使う } // 読み込み using (var stream = await file.OpenStreamForReadAsync()) { // JSON.NET などを使う } アプリケーションのバージョンアップなどにより、設定やファイルに保存しているデータに非 互換が発生してしまった場合は、ApplicationData.Current.SetVersionAsync メソッドを使用し てバージョン管理を行うことが出来ます。SetVersionAsync メソッドは、第一引数にバージョ ン番号を指定し、第二引数にコールバックを指定します。コールバックでは、以下のように現 在のバージョンと要求されたバージョンが確認できます。 await ApplicationData.Current.SetVersionAsync(0, r => { var d = r.GetDeferral(); Debug.WriteLine($"CurrentVersion: {r.CurrentVersion}, DesiredVersion: {r.DesiredVersion}"); // バージョンが違ってたら必要に応じて変換ロジックを走らせる d.Complete();
  • 65. 65 }); SetVersionAsync を呼び出した場合は、バージョン番号が変わっていなくてもコールバックが 呼ばれるので、その点は注意する必要があります。 7.2. ロ ー ミン グ デ ー タ ローカルアプリデータは、デバイスのローカルストレージに保存されます。ここで紹介するロ ーミングデータは、同じアプリのデータを複数のデバイスで同期をとります。この機能を使う ことで、例えばユーザーがデスクトップで途中まで呼んでいた書籍を、外出先で続きから読む といったシナリオが実現可能になります。ローミングデータにも、設定とファイルが存在し て、以下のようにアクセスを行います。 // 設定 var roamingSettings = ApplicationData.Current.RoamingSettings; // ファイル var roamingFolder = ApplicationData.Current.RoamingFolder; RoamingSettings も RoamingFolder も、ローカルアプリデータと同じ方法で使用できます。ロ ーミングデータは、ApplicationData.RoamingStorageQuota で指定されるサイズ(KB 単位)以 上のデータがある場合は、ローミングが実行されません。この値は、Windows 10 Version 1511 で確認したところ 100 という値が反ってきました。 RoamingData がアップデートされたことを検知するには、 ApplicationData.Current.DataChanged イベントを使用します。以下のようなコードになりま す。 public MainPage() { this.InitializeComponent(); ApplicationData.Current.DataChanged += Current_DataChanged; } private void Current_DataChanged(ApplicationData sender, object args) {
  • 66. 66 // RoamingData がアップデートされた } 7.3. 一 時 アプ リ デ ー タ 一時アプリデータは、設定は存在せずにファイルのみになります。以下のようにして一時アプ リデータのフォルダを取得します。 // 一時アプリフォルダを取得する var folder = ApplicationData.Current.TemporaryFolder; フォルダ取得後は、ローカルアプリデータで示した通りファイルへのアクセスが可能です。 8. Advanced XAML ここでは、UWP を作るうえで必須となる XAML の高度な機能を紹介したいと思います。 8.1. Style UWP には、Style と呼ばれるコントロールのプロパティの設定を外だしにして定義する仕組み があります。これを使うことで HTML の CSS のように見た目の定義を別にすることが出来ま す。HTML の CSS と異なる点は、XAML という統一された言語でコントロールのツリー構造 と見た目の定義ができるという点です。HTML の CSS を知っている方向けに説明すると、 HTML の CSS がセレクタによって適用対象を指定して、見た目を定義するのに対して、 XAML の Style は名前を付けてリソースに定義して、コントロールから、それを参照して設定 します。(コントロールのスタイルにインラインで書くことも出来ますが、それならコントロ ールに直接プロパティを設定したほうがいいと思われます) Style の定義は、以下のように Page や App クラスの Resources に Style タグを使って定義しま す。 <Page x:Class="ControlsApp.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:ControlsApp" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  • 67. 67 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Page.Resources> <!-- MyTextBlock という名前で TextBlock のスタイルを定義 --> <Style x:Key="MyTextBlock" TargetType="TextBlock"> <!-- FontStyle プロパティに Italic を指定 --> <Setter Property="FontStyle" Value="Italic" /> <!-- FontWeight に Bold を指定 --> <Setter Property="FontWeight" Value="Bold" /> </Style> </Page.Resources> <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <!-- StaticResource を使って Style を設定 --> <TextBlock Text="Hello world" Style="{StaticResource MyTextBlock}"/> </Grid> </Page> Style タグの TargetType で、何の型に対する Style なのか指定します。そして、Style タグの中 に Setter タグを使って何のプロパティに、どんな値を設定するのかを指定します。定義した Style は、コントロールにある Style プロパティに StaticResource マークアップ拡張を使って指 定します。上記の XAML で、以下のように TextBlock が太字のイタリック体になります。 Style は、別のスタイルをベースに拡張して作ることも出来ます。Style の BaseOn にベースと なる Style を StaticResource マークアップ拡張で指定します。先ほどの例の MyTextBlock スタ
  • 68. 68 イルを拡張して赤色の設定を追加した ExTextBlock という名前のスタイルを定義した XAML を以下に示します。 <Page x:Class="ControlsApp.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:ControlsApp" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Page.Resources> <!-- MyTextBlock という名前で TextBlock のスタイルを定義 --> <Style x:Key="MyTextBlock" TargetType="TextBlock"> <!-- FontStyle プロパティに Italic を指定 --> <Setter Property="FontStyle" Value="Italic" /> <!-- FontWeight に Bold を指定 --> <Setter Property="FontWeight" Value="Bold" /> </Style> <!-- MyTextBlock を拡張して赤色にする --> <Style x:Key="ExTextBlock" TargetType="TextBlock" BasedOn="{StaticResource MyTextBlock}"> <Setter Property="Foreground" Value="Red" /> </Style> </Page.Resources> <StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <!-- StaticResource を使って Style を設定 --> <TextBlock Text="Hello world" Style="{StaticResource MyTextBlock}" /> <TextBlock Text="Hello world2" Style="{StaticResource ExTextBlock}" />
  • 69. 69 </StackPanel> </Page> この XAML を表示すると以下のようになります。ExTextBlock が、MyTextBlock に対して赤 色を追加したものになっていることが確認できます。 8.1.1. 定 義 済み の ス タ イ ル UWP には、いくつかの Style が予め定義されています。この定義は「C:Program Files (x86)Windows Kits10DesignTimeCommonConfigurationNeutralUAP10.0.10586.0Generic」フォルダ の generic.xaml でされています。よく使うものをいくつか紹介します。  HeaderTextBlockStyle ヘッダー用の大きな TextBlock 用 Style です。  SubheaderTextBlockStyle サブヘッダー用のヘッダーより一回り小さな TextBlock 用の Style です。  TitleTextBlockStyle タイトル用の TextBlock 用の Style です。  SubtitleTextBlockStyle サブタイトル用の TextBlock 用の Style です。  BodyTextBlockStyle 本文用の TextBlock 用の Style です。