Xamarin.Forms入門 キホンのキ - XAML とは


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 のシミュレーターで表示すると以下のようになります。

f:id:fnyablog:20180925082910p:plain

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 が書き換えられています。

f:id:fnyablog:20180925083043p:plain

(発展)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 を説明すると混乱するので、別の回に改めて解説します。

連載目次