[Xamarin.Forms] Commandプロパティが無いViewに対してCommandプロパティを実装する

## Commandが標準で対応しているView
Xamarin.Formsで標準でCommandプロパティが用意されているのは下記の3種類だけです。
他のViewでCommandを使いたい場合は自前で実装する必要があります。

 - Button
 - ToolbarItem
 - TextCell

公式：[Part 5. From Data Bindings to MVVM](https://developer.xamarin.com/guides/cross-platform/xamarin-forms/user-interface/xaml-basics/data_bindings_to_mvvm/)

## Commandプロパティの実装方法
必要なのは下記の3種類だけです。

1. object CommandParameterプロパティを実装
2. Command Commandプロパティを実装
3. Commandの呼び出し処理を実装

## ViewCellの実装例
例えばViewCellなら下記のようにします。

```lang:C#
using Xamarin.Forms;

namespace MyProject.Controls
{
    public class CustomViewCell : ViewCell
    {
        public static readonly BindableProperty CommandParameterProperty = BindableProperty.Create<CustomViewCell, object>(i => i.CommandParameter, default(object), BindingMode.OneWay);

        public object CommandParameter
        {
            get
            {
                return this.GetValue(CommandParameterProperty);
            }
            set
            {
                this.SetValue(CommandParameterProperty, value);
            }
        }

        public static readonly BindableProperty CommandProperty = BindableProperty.Create<CustomViewCell, Command>(i => i.Command, null, BindingMode.OneWay);

        public Command Command
        {
            get
            {
                return (Command)this.GetValue(CommandProperty);
            }
            set
            {
                this.SetValue(CommandProperty, value);
            }
        }
       
        protected override void OnTapped()
        {
            base.OnTapped();

            if (this.Command != null)
            {
                this.Command.Execute(this.CommandParameter ?? this);
            }
        }
    }
}
```

## StackLayoutの実装例
StackLayoutなら下記のようにします。
ViewCellのようにOnTappedイベントがもともとないので、
TapGestureRecognizerを使ってタップイベントをGestureRecognizersに登録します。

```lang:C#
using Xamarin.Forms;

namespace MyProject.Controls
{
    public class CustomStackLayout : StackLayout
    {
        public static readonly BindableProperty CommandParameterProperty = BindableProperty.Create<CustomStackLayout, object>(i => i.CommandParameter, default(object), BindingMode.OneWay);

        public object CommandParameter
        {
            get
            {
                return this.GetValue(CommandParameterProperty);
            }
            set
            {
                this.SetValue(CommandParameterProperty, value);
            }
        }

        public static readonly BindableProperty CommandProperty = BindableProperty.Create<CustomStackLayout, Command>(i => i.Command, null, BindingMode.OneWay);

        public Command Command
        {
            get
            {
                return (Command)this.GetValue(CommandProperty);
            }
            set
            {
                this.SetValue(CommandProperty, value);
            }
        }

        public CustomStackLayout()
        {
            var tgr = new TapGestureRecognizer();
            tgr.Tapped += (s, e) => OnTapped();
            this.GestureRecognizers.Add(tgr);
        }

        protected void OnTapped()
        {
            if (this.Command != null)
            {
                this.Command.Execute(this.CommandParameter ?? this);
            }
        }
    }
}
```