かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

Windows FormsからWPFへ乗り換えるときの最初の障壁

Twitterでも呟いたのですが、とりあえずブログのエントリとしてまとめておきます。因みに、ここでの障壁はプログラマさんが感じるであろう最初の障壁を自分の場合を思い出して書いています。

何がなんだかわからない

まず、最初に躓くのが慣れ親しんだWindows Formsとクラス名とプロパティ名が違う。でも、それでも!最初は頑張ってみようと思うんですが、WPFはそんなに優しくありません。最初誰もが躓くであろうことがあります(あくまで主観ですが)。

とりあえずボタンだよね

とりあえず、わけがわからなくてもツールボックスからデザイナに何かしらボタンとか置いて、ダブルクリックして、イベントハンドラできたー!じゃぁテキストの表示を変えて・・・

// 画面にbutton1を置いてクリックイベントを作るところまでは出来た
// クリックされたのがわかるようにボタンに表示されてるテキストを
// 変更してみよう
void button1_Click(object sender, RoutedEventArgs e)
{
    button1.Text = "おしたよ";
}

コンパイルエラー\(^o^)/

何でTextじゃないの?

WPFは、コンテンツモデルという初見の人にとってはよくわからないものが採用されています。何か表示するものを1つだけ持つものはContentというプロパティで、それを指定します。このContentはobject型なのでなんでも入ったりするという、Windows Formsから見たら考えられない状態になっていますが、とりあえず文字列を入れれば大丈夫です。

ちょっと凄いのが、このContentの中にボタンとか色々入れるとボタンの中にボタンとかというカオスな状態が出来ることです。ボタンにボタンは意味が無さすぎますが、綺麗な画像を表示させるボタンとかも簡単に作れるっていう寸法です。

ContentControlというものを継承してるコントロールが、ボタンのようにContentプロパティを持っています。覚えておきましょう。これさえ覚えておけば、とりあえずbutton1.Textと書くことは無くなります。


因みに、文字列しか持たないことが確定してるようなコントロールはTextプロパティを持っていたりするのでちょっと慣れるまでややこしいと感じるかもしれません。

謎の言語XAML

慣れ親しんだクラスやプロパティが、ほとんど役に立たない上に謎のXMLベースの言語のXAMLという敵が待ち構えています。この敵は、味方につけると頼もしいことは確かなのですが、HTMLでもないしC#のコードでもないし、ちょっときもいわ〜と私は感じました。

XAMLの正体

XAMLは、踏み込むとマークアップ拡張だとかあったりしますが、基本的にタグ名がクラス名、属性がプロパティ、XML名前空間C#名前空間に対応しているだけです。名前空間の定義の仕方がちょっと複雑な感じがしますが、色々細工が出来てURLに対して複数のC#名前空間に紐づけることが出来るようになっています。

そういう視点で見てみるとWindowのXAMLは、以下のような意味になります。
XML名前空間は以下のように定義されています。これは、WPFの基本的なコントロールが入ってる名前空間に対応しています。

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

なのでルート要素の

<Window .....>
</Window>

は、ただのWindowクラスを表しています。

<Window x:Class="Sample.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1" Height="300" Width="300">

WindowのXAMLの頭の部分だけひっぱってきましたが、WindowクラスのTitleプロパティにWindow1を設定してHeightプロパティに300を設定してWidthプロパティに300を設定するという意味です。わかってしまえば楽勝ですね。C#で書くと以下のような感じですね。

Window w = new Window()
w.Title = "Window1";
w.Height = 300;
w.Width = 300;

そして、Contentプロパティを持ってる人達はタグの中に書かれたものがContentに入るような仕掛けになっています。これを覚えておけば、デフォルトのWindowを新規作成したときのXAMLは読み解けます。

<Window x:Class="Sample.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1" Height="300" Width="300">
    <Grid>
        
    </Grid>
</Window>

WindowのContentプロパティにGridクラスを設定するということです。Gridクラスは表形式にコントロールを配置してくれるコントロールです。Gridの上に色々部品を置いて画面を作っていくイメージです。

まとめ

とりあえず、最初の最初の最初に気持ち悪い。わけわからないと思いそうな部分だけを超短くですが書いてみました。Windows FormsからWPFへの1つの足掛かりになればと思います。