WPF
WPF(Windows Presentation Foundation)は、Windowsデスクトップ専用のUIフレームワークであり、.NET Framework/Coreの一部です。
WPFの描画は、DirectXを使ったベクターグラフィックスです(次の図)。画面の解像度に依存しないシャープで、アニメーションを併用した滑らかなUIが実現されています。
※デスクトップウィンドウマネージャー(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がたくさん働いているのです(次の画像)。
タスクマネージャーを見ると、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#のどちらで書いたのかは、出来上がったアプリを見ただけでは区別できません。
2つめのボタン(C#で書いた方)をクリックしたところ。
水色になっているのは、クリックしたときのハイライト効果です
どうしてもXAMLに馴染めない方は、C#のコードだけでWPFアプリを作ることも可能ではあります。ですが、XAMLには次のようなメリットがあるので、ぜひ学んでください。
- UIを簡潔に分かりやすく記述できます
- 前回紹介したように、XAMLエディターのプレビューやデバッグ実行時のホットリロード機能によって、実際の状態を見ながらUIを記述できます
- いくかのUIフレームワークがXAML(あるいはよく似たXML)を採用しています。Windows系では、Windows 10用のUWPと、クロスプラットフォーム開発用のXamarin.FormsがXAMLです
