しっぽを追いかけて

ぐるぐるしながら考えています

Unity と猫の話題が中心   掲載内容は個人の私見であり、所属組織の見解ではありません

Xamarin.Forms で文字列で DateTime を XAML に指定できるようにする

前回XAML で DateTime を指定しましたが

  <DatePicker>
    <DatePicker.Date>
      <sys:DateTime x:FactoryMethod="Parse">
        <x:Arguments>
          <x:String>2015/02/27</x:String>
        </x:Arguments>
      </sys:DateTime>
    </DatePicker.Date>
  </DatePicker>

こんな回りくどい指定の仕方は面倒なのでやっぱり WPF のように直接文字列で指定できるようにしてみます

やることは Converter の追加と DatePicker コントロールの拡張です

namespace Xamarin.Forms
{
    /// <summary>
    /// Date を文字列で指定できる DatePicker
    /// </summary>
    public class SimpleDatePicker : DatePicker
    {
        /// <summary>
        /// 文字列の日付
        /// </summary>
        [TypeConverter(typeof(DateTimeConverter))]
        public DateTime DateString
        {
            get { return this.Date; }
            set { this.Date = value; }
        }
    }

    /// <summary>
    /// DateTime の Converter
    /// </summary>
    public class DateTimeConverter : TypeConverter
    {
        /// <summary>
        /// DateTime に変換できるか判定します
        /// </summary>
        /// <param name="sourceType">変換元の型</param>
        /// <returns>変換できる場合は<code>true</codem>, それ以外は<code>false</code></returns>
        public override bool CanConvertFrom(Type sourceType)
        {
            return sourceType is DateTime || sourceType is string;
        }

        /// <summary>
        /// DateTime に変換します
        /// </summary>
        /// <param name="culture">カルチャ</param>
        /// <param name="value">変換元の値</param>
        /// <returns>変換後の DateTime</returns>
        public override object ConvertFrom(CultureInfo culture, object value)
        {
            var date = DateTime.Now;

            if (value == null)
            {
                return date;
            }

            switch (value.GetType().Name.ToLower())
            {
                case "datetime":
                    date = (DateTime)value;
                    break;

                case "string":
                    DateTime.TryParse((string) value, out date);
                    break;
            }

            return date;
        }
    }
}

といってもこれだけ

TypeConverter の属性をプロパティに指定すると 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:c="clr-namespace:Xamarin.Forms;assembly=XamarinControl"
             x:Class="XamarinControl.Views.TopPage">
  
  <c:SimpleDatePicker DateString="2015/02/27"/>

</ContentPage>

実にすっきり

f:id:matatabi_ux:20150222171431g:plain

動作も問題なし