WPF
WPF(Windows Presentation Foundation)は、Windowsデスクトップ専用のUIフレームワークであり、.NET Framework/Coreの一部です。
WPFの描画は、DirectXを使ったベクターグラフィックスです(次の図)。画面の解像度に依存しないシャープで、アニメーションを併用した滑らかなUIが実現されています。
![WPFアプリが画面に表示されるまでの流れ](https://cz-cdn.shoeisha.jp/static/images/article/11854/fig12s.png)
※デスクトップウィンドウマネージャー(DWM)については"Aero Glass"を参照
WPFのUIを構成するコントロール(UI部品)は、その内部の描画を自由に置き換えられる構造になっていて、コントロールの見た目を自由にデザインできます。これはWindows FormsやXamarinにはない、WPFの大きな特徴です。
WPFは、UIとロジックを分離するための基本的な仕組みも持っています。ロジックが持つデータをUIに結び付けるデータバインディングと、UIのイベントをロジックに伝達するコマンドです。それらを利用してUIとロジックを分離するいくつものフレームワークがサードパーティーから提供されています。また、データバインディングはコントロール同士にも使えるので、例えば本稿の冒頭で示した四面体の3Dアニメーションのようにスライダーの動きと立体の回転角度を結び付けるようなことも可能です。
これらWPFの特徴について、詳しくは「WPF の概要」をご覧ください。以降では、いくつかのトピックについて少し掘り下げて解説します。
ベクターグラフィックス
DirectXを使ったベクターグラフィックスは、解像度に依存しない2D/3Dのレンダリングが可能です。しかも、DirectXは可能な限りGPUを使ってくれますから、CPUへの負担が減るのも特徴です。
例えば、本稿の冒頭で示した四面体の3DアニメーションはCPUに大きな負荷が掛かっていると思われるかもしれません。実際にはDirectXが3Dモデルの処理を行っているので、CPUの負荷は大したことはなくて、GPUがたくさん働いているのです(次の画像)。
![XAMLだけで記述した動的コンテンツの例](https://cz-cdn.shoeisha.jp/static/images/article/11854/fig02s.png)
タスクマネージャーを見ると、CPUよりもGPUをたくさん使っていることが分かります。
同時に、先の図に示したデスクトップウィンドウマネージャー(DWM)も働いています。
XAMLの意義
前回で実際に見ていただいたように、WPFではUIの定義を基本的にXAMLで記述します。しかしながらXAMLはUIの記述を簡潔かつ分かりやすくするためのものであって、XAMLを使わずにWPFのアプリを書くことも可能です。
例えば、次のXAMLコードを見てください。2つめのボタンをコメントアウトしてあります。
<Grid x:Name="Grid1" HorizontalAlignment="Center" VerticalAlignment="Center"> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition /> <RowDefinition /> </Grid.RowDefinitions> <Button Grid.Row="0" Margin="0,0,0,5" Padding="10,5" Click="Button1_Click" >XAMLで定義したボタン</Button> <!--<Button Grid.Row="1" Margin="0,0,0,5" Padding="10,5" Click="Button2_Click" >C#で組み立てたボタン</Button>--> <TextBlock x:Name="Text1" Grid.Row="2" FontSize="18" HorizontalAlignment="Center" Height="30" /> </Grid>
このコメントアウトした2つめのボタンは、次のコードのようにしてC#で記述できます。上のXAMLでコメントにした部分と、下のC#で太字にした部分とは、同じことなのです。見比べてみると、ボタンの記述がたった2行で済んでいるXAMLの方が、ずいぶん簡潔ですね。
public MainWindow() { InitializeComponent(); var button2 = new Button // ボタンのインスタンス化 { // プロパティを設定 Content = "C#で組み立てたボタン", Margin = new Thickness( 0.0, 0.0, 0.0, 5.0), Padding = new Thickness(10.0, 5.0, 10.0, 5.0), }; button2.Click += Button2_Click; // イベントハンドラーを設定 Grid1.Children.Add(button2); // Gridの中に配置 Grid.SetRow(button2, 1); // Grid内で配置するRowを指定 } private void Button1_Click(object sender, RoutedEventArgs e) => Text1.Text = "XAML"; private void Button2_Click(object sender, RoutedEventArgs e) => Text1.Text = "C#";
なお、上のコードで「=>」に続けて「Text1.Text = "XAML"」といった式が書いてありますが、これはC# 3.0で導入されたラムダ式です。C# 6.0からは、メソッドの本体もラムダ式で書けるようになりました。また、「new Button」に続けて中かっこ「{}」で囲ってプロパティへの代入が書いてありますが、これもC# 3.0で導入された機能でオブジェクト初期化子という書き方です。
実行してみると、次の画像のようになります。XAMLかC#のどちらで書いたのかは、出来上がったアプリを見ただけでは区別できません。
![XAMLとC#で書いたボタン](https://cz-cdn.shoeisha.jp/static/images/article/11854/fig10.png)
2つめのボタン(C#で書いた方)をクリックしたところ。
水色になっているのは、クリックしたときのハイライト効果です
どうしてもXAMLに馴染めない方は、C#のコードだけでWPFアプリを作ることも可能ではあります。ですが、XAMLには次のようなメリットがあるので、ぜひ学んでください。
- UIを簡潔に分かりやすく記述できます
- 前回紹介したように、XAMLエディターのプレビューやデバッグ実行時のホットリロード機能によって、実際の状態を見ながらUIを記述できます
- いくかのUIフレームワークがXAML(あるいはよく似たXML)を採用しています。Windows系では、Windows 10用のUWPと、クロスプラットフォーム開発用のXamarin.FormsがXAMLです