Xamarin.Formsで基本的なデータバインディング

Qiita初投稿です。間違いやスペルミスがありましたらご指摘ください。
# 概要
Xamarinのページの[Part 5. From Data Bindings to MVVM](https://developer.xamarin.com/guides/xamarin-forms/user-interface/xaml-basics/data_bindings_to_mvvm/)　のシンプルなViewModelについて実際にやってみようと思います。
内容は現在の時刻をLabelで表示し、毎秒更新するという内容です。

## 変更点
原文ではプロパティがDateTimeとなっていましたが、クラス名と紛らわしかったのでMyDateTimeという名前にしてあります。

# ViewModelを作る
まずはViewModelの基礎を作ります。

~~~ C#
using System;
using System.ComponentModel;
using Xamarin.Forms;

namespace XamarinSample2
{
    class ClockViewModel
    {
        DateTime myDateTime;

        public ClockViewModel()
        {
            this.MyDateTime = DateTime.Now;
            Device.StartTimer(TimeSpan.FromSeconds(1), () =>
            {
                
                MyDateTime = DateTime.Now;
                return true;
            });
        }

        public DateTime MyDateTime
        {
            set
            {
                if (myDateTime != value)
                {
                    myDateTime = value;
                }
            }
            get { return myDateTime; }
        }

    }
}

~~~

クラスを見ていきます
DateTime型のプロパティMyDateTimeを持ち、コンストラクタで現在時刻に設定しています。
セッターで、代入された値が同じ時は更新しない理由は、ここに後述するイベント処理を挟むからです。
そしてコンストラクタで毎秒ごとにMyDateTimeを更新するようなタイマーを設定しています。

# Viewを作る
まずはこのままバインディングしてみましょう

~~~ XML
<?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:XamarinSample2;assembly=XamarinSample2"
             x:Class="XamarinSample2.View.StartPage">

  <StackLayout>

    <Label x:Name="label"
           Text="{Binding MyDateTime, StringFormat='{0:T}'}"
           FontSize="Large"
           HorizontalOptions="Center"
           VerticalOptions="CenterAndExpand">
      <Label.BindingContext>
        <local:ClockViewModel />
      </Label.BindingContext>
    </Label>
  
   </StackLayout>
</ContentPage>
~~~

まず注意したいのはContentPageの属性にXML名前空間：xmlns:localとして先ほどのViewModelがある名前空間を宣言していることです。
そしてLabelのLabel.BindingContextで、localのClockViewModelクラスを指定しています。
これでプロパティにバインドできるので、LabelのTextをMyDateTimeとバインドします。

実行すると実行時の時間は表示されますが、更新はされないと思います。
これはViewModelにINotifyPropertyChangedが実装されていないためです。
では実際に実装してみましょう

# ViewModelにINotifyPropertyChangedを実装する
ClockViewModelにINotifyPropertyChangedを実装してみます。

~~~ C#
namespace XamarinSample2
{
    class ClockViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged = delegate { };

        DateTime myDateTime;

        public ClockViewModel()
        {
            this.MyDateTime = DateTime.Now;
            Device.StartTimer(TimeSpan.FromSeconds(1), () =>
            {
                
                MyDateTime = DateTime.Now;
                return true;
            });
        }

        public DateTime MyDateTime
        {
            set
            {
                if (myDateTime != value)
                {
                    myDateTime = value;
                    PropertyChanged(this, new PropertyChangedEventArgs("MyDateTime"));
                }
            }
            get { return myDateTime; }
        }

    }
}
~~~

DateTimeのセッターに注目してください。MyDateTimeが変わった時、INotifyPropertyChangedを実装して作ったPropertyChangedイベントを発火させています。これによりViewが変化するはずです。
PropertyChangedの2番めの引数にPropertyChangedEventArgsを渡していますが、このときプロパティ名を間違えないよう気をつけてください。

これで実行すると、毎秒更新される時計が出来るはずです。

# まとめ
- ViewModelにINotifyPropertyChangedを実装し、PropertyChangedイベントを発火させる
- Viewで名前空間を宣言し、BindingContextでViewModelをバインドする

# 参考記事
[Xamarinのxamlのデータバインディングのpart4について訳してみた。](https://junk-code.blogspot.jp/2016/04/xamarinxamlpart4.html)