Xamarin.Forms入門 キホンのキ - XAML とは
XAML とは
XAML(Extensible Application Markup Language,「ざむる」と読む)は、XMLベースのマークアップ言語です。
Windows の開発者であれば WPF や UWP で馴染みのあるもので、それを Xamarin.Forms でも使用することができます。
XAML を使用することで、UI とコードを分離することが可能になり、XAML で UI 定義を、C# でロジックのコードを記述できます。
これにより UI とコードが疎結合になります。
XAML の具体例
以下は XAML の簡単な例です。
<?xml version="1.0" encoding="utf-8"?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:HelloWorld2" x:Class="HelloWorld.MainPage"> <Label Text="Welcome to Xamarin Form" VerticalOptions="Center" HorizontalOptions="Center" /> </ContentPage>
ContentPage で名前空間の宣言がされています。
xmlns="http://xamarin.com/schemas/2014/forms"
により、プリフィックスのついていない要素は Xamarin.Forms のものになります。
また、xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
により、x のプリフィックスがついた要素は Microsoft の定義によるものになります。
そして、Label で表示文字列を定義し、表示位置を画面中央と定義しています。
この XAML iPhone のシミュレーターで表示すると以下のようになります。
Label 要素が、画面の中央に意図通り表示されましたね。
コードビハインド
この XAML コードは MainPage.xaml に記述されたものなのですが、ContentPage にx:Class="HelloWorld.MainPage"
の定義があることで、MainPage.xaml.cs のクラスに紐付いています。
そして、この XAML コードに x:Name を指定することで、C# から Label を制御することができます。
この仕組みをコードビハインドといいます。
具体的に見ていきましょう。
<?xml version="1.0" encoding="utf-8"?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:HelloWorld" x:Class="HelloWorld.MainPage"> <Label x:Name="label" Text="Welcome to Xamarin Form" VerticalOptions="Center" HorizontalOptions="Center" /> </ContentPage>
Label に x:Name として "label" が割り当てられました。
これで、MainPage.xaml.cs のクラスで、C# から以下のように Label の内容を書き換えることができます。
public partial class MainPage : ContentPage { public MainPage() { InitializeComponent(); label.Text = "label changed !"; } }
このコードの実行結果は以下のようになり、正しく Label が書き換えられています。
(発展)XAML はクラスの定義
ここからは、少し発展的な内容になります。
もし分からなくても、Visual Studio がよろしく行ってくれるので問題ありません。
さて、先ほどの C# のコードですが、クラス宣言時にpartial
を使用しています。
なんで partial
なのでしょうか。
それは、XAML で定義した内容はコンパイル時に C# のクラスとして自動生成されるためです。この自動生成されたクラスとコードビハインドのクラスをまとめて1つのクラスとするためにpartial
と宣言しています。
自動生成されたクラスを見てみましょう。Finder で 自動生成された MainPage.xaml.g.cs を開くと以下のようになっています。
[global::Xamarin.Forms.Xaml.XamlFilePathAttribute("MainPage.xaml")] public partial class MainPage : global::Xamarin.Forms.ContentPage { [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Forms.Build.Tasks.XamlG", "2.0.0.0")] private global::Xamarin.Forms.Label label; [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Forms.Build.Tasks.XamlG", "2.0.0.0")] private void InitializeComponent() { global::Xamarin.Forms.Xaml.Extensions.LoadFromXaml(this, typeof(MainPage)); label = global::Xamarin.Forms.NameScopeExtensions.FindByName<global::Xamarin.Forms.Label>(this, "label"); } }
注目して欲しいのは以下の部分です(抜粋)。
//(省略) public partial class MainPage : global::Xamarin.Forms.ContentPage { //(省略) private global::Xamarin.Forms.Label label; //(省略) private void InitializeComponent() { //(省略) label = global::Xamarin.Forms.NameScopeExtensions.FindByName<global::Xamarin.Forms.Label>(this, "label"); } }
まず、クラスは 'partial' と宣言されている MainPage クラスになります。
先ほどのコードビハインドのクラスも'partial' と宣言されている MainPage クラスのため、これで1つのクラスになることが分かります。
また、label フィールドに着目すると、XAML で Label の "label"と定義されているものを読み込んでいることが分かります。
これにより、コードビハインドで label = ...
と書ける訳ですね。
XAML がクラス定義というのはコンパイル時に C# のクラスが自動生成されるためです。
1点、注意事項があります。
コードビハインドの MainPage コンストラクタに、InitializeComponent();
という記述がありますが、この命令で XAML から C# のコードを自動生成しているので、InitializeComponent();
の前にlabel = ...
と記述すると実行時エラーになってしまいます。
おわりに
以上で、XAML についての解説は終了となります。
おいおい、データバインディングの解説とかがないじゃないか?というご指摘があると思いますが、一度に XAML を説明すると混乱するので、別の回に改めて解説します。