かずきのBlog@hatena

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

WPF4.5入門 その7 「XAMLのオブジェクト要素と名前空間」

XAML

ここまで何度か登場してきたXAMLについて詳しく見て行こうと思います。XAMLは、Extensible Application Markup Languageの略で、MSDNによると「宣言的アプリケーション プログラミングで使用するマークアップ言語」と定義されています。XAMLで主に使用する構文として以下のものがあります。

  • オブジェクト要素
  • XAML名前空間
  • オブジェクト要素のプロパティ
    • 属性構文
    • プロパティ要素の構文
  • コレクション構文

1つずつ順番に見ていきます。

オブジェクト要素とXAML名前空間

オブジェクト要素とは、名前の通りクラス名に対応するものです。XMLのタグに対応します。Hello worldアプリケーションでは<Window />といったタグや<Grid />といったタグがこれにあたります。XAML名前空間はCLRの名前空間のようなもので、そのタグに紐づくクラスがどの名前空間にいるのかを定義します。WPFでは規定の名前空間としてxmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”が割り当てられています。その他にxmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”という名前空間も割り当てられています。前者がWPFの基本的なクラスが所属するの名前空間にマッピングされていて、後者がXAML言語組み込みの機能を提供します。
XAML名前空間は、規定の名前空間の他に自分で作成したクラスに割り当てることができます。そのときの名前空間の書式はxmlns:プレフィックス=”clr-namespace:名前空間;assembly=アセンブリ名”になります。例として、CustomXamlという名前のコンソールアプリケーションを作成して、WPFに必要なアセンブリを追加したプロジェクトに以下のようなPersonという名前のクラスを作成します。

namespace CustomXaml
{
    using System;
 
    public class Person
    {
        public Person()
        {
            this.Birthday = DateTime.Now;
        }
 
        public DateTime Birthday { get; private set; }
    }
}

このクラスをXAML名前空間とオブジェクト要素を使って定義したXAMLは以下のようになります。

<p:Person xmlns:p="clr-namespace:CustomXaml;assembly=CustomXaml" />

このXAMLをPerson.xamlという名前で作成して、埋め込まれたリソースに設定して読み込んでPersonクラスのインスタンスを取得してみます。XAMLを読み込むには、System.Windows.Markup.XamlReaderクラスを使います。LoadメソッドにStreamを渡すとXAMLをパースした結果のオブジェクトを返します。今回のPerson.xamlは、Personクラスを定義しているので、Personクラスのインスタンスが返ってくるはずです。読み込むコードを以下に示します。

namespace CustomXaml
{
    using System;
    using System.Windows.Markup;
 
    class Program
    {
        public static void Main(string[] args)
        {
            // アセンブリから対象のXAMLのストリームを取得
            var s = typeof(Program).Assembly.GetManifestResourceStream("CustomXaml.Person.xaml");
            // パース
            var p = XamlReader.Load(s) as Person;
            // プロパティを表示してみる
            Console.WriteLine("p.Birthday = {0}", p.Birthday);
        }
    }
}

このプログラムを実行すると以下のように表示されます。(表示結果は実行した時間によってかわります)

p.Birthday = 2013/01/03 13:23:04

XAMLをパースすることで、Personクラスのインスタンスが作られていることがわかります。このことから、XAMLのオブジェクト要素がクラス名に、XAML名前空間がクラスの名前空間に対応するということがわかると思います。