Bindingって?(BindingContext,Label,Button)


はじめに

最近、Xamarinを使うようになったのですが、Bindingの考え方について理解するのに時間がかかってしまったので、忘れないように書いておこうと思います。
今回使用するプロジェクトの名前はXamarinPracticeです。
内容としては、ボタンを押すと数字を1つずつカウントし、表示するものです。

コード(共有プロジェクト)

MainPage.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:XamarinPractice"
             x:Class="XamarinPractice.MainPage">
    <ContentPage.BindingContext>
        <local:Test/>
    </ContentPage.BindingContext>

    <StackLayout>
        <Label Text="{Binding Counter}"
               HorizontalOptions="CenterAndExpand"
               VerticalOptions="CenterAndExpand"/>
        <Button Command="{Binding CounterCommand}"
                Text="+1"/>
    </StackLayout>

</ContentPage>
Test.cs
namespace XamarinPractice
{
    using System.ComponentModel;
    using Xamarin.Forms;

    internal class Test : INotifyPropertyChanged
    {
        private int counter;

        public Test()
        {
            this.CounterCommand = new Command(() =>
            {
                this.Counter += 1;
            });
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public Command CounterCommand { get; set; }

        public int Counter
        {
            get
            {
                return this.counter;
            }

            set
            {
                this.counter = value;
                this.PropertyChanged(this, new PropertyChangedEventArgs("Counter"));
            }
        }
    }
}

解説

BindingContextについて

    <ContentPage.BindingContext>
        <local:Test/>
    </ContentPage.BindingContext>

MainPage.xamlに使われているBindingContextはContentPageにクラスをバインドします。
(今回はContentPageを使用しているので、ContentPage.BindingContextとなります。ほかにもMasterDetailPageなどあります。)
どのクラスをバインドするかは2行目で指定しています。ちなみに、

<local:Test/>

とは、localという変数の中のTestというクラスを指しています。このlocalという変数は

<?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:XamarinPractice" <--- ここ
             x:Class="XamarinPractice.MainPage">

で宣言されており、中にはXamarinPractice名前空間が格納されています。
つまり、

<local:Test/>

は、XamarinPractice名前空間の中のTestというクラスを指定していることになります。
イメージとしてはこのようになります。

(画像粗くて申し訳ありません・・・。)

Label,ButtonのBindingについて

今回の例では、

  • LabelのText
  • ButtonのCommand

の2つにプロパティをバインドしています。バインドしている場所は

    <StackLayout>
        <Label Text="{Binding Counter}" <--- ここ
               HorizontalOptions="CenterAndExpand"
               VerticalOptions="CenterAndExpand"/>
        <Button Command="{Binding CounterCommand}" <--- ここ
                Text="+1"/>
    </StackLayout>

バインドされるものは


    public Command CounterCommand { get; set; } <--- これ

    public int Counter <--- これ
    {
        get
        {
            return this.counter;
        }

        set
        {
            this.counter = value;
            this.PropertyChanged(this, new PropertyChangedEventArgs("Counter"));
        }
    }

です。
イメージとしてはこうなります。

(雑で申し訳ありません・・・。)

MainPageクラス に Testクラスをバインド
MainPageクラスの中のLabet Text に Testクラスの中のCounterをバインド
MainPageクラスの中のButton Command に Testクラスの中のCounterCommandをバインド

ここで、重要なのは、プロパティをバインドするということです。

さいごに

不明な点やご指摘などあればぜひコメントをお寄せいただけるとうれしいです。よろしくお願いいたします。