Xamarin.Forms DatePicker

ユーザーが日付を選択できる Xamarin.Forms ビュー。

Xamarin.FormsDatePicker はプラットフォームの日付ピッカー コントロールを呼び出し、ユーザーが日付を選択できるようにします。 DatePicker では、次の 8 つのプロパティが定義されます。

ユーザーが日付を選択すると、DatePicker により DateSelected イベントが発生します。

警告

MinimumDateMaximumDate を設定する場合は、常に MinimumDate が、MaximumDate 以下であることを確認します。 それ以外の場合は、DatePicker で例外が発生します。

内部的には、DatePicker では DateMinimumDateMaximumDate の間にあることが保証されます。 Date がそれらの間にはなく、MinimumDate または MaximumDate が設定されている場合、DatePickerDate の値を調整します。

これらのプロパティはすべて、BindableProperty オブジェクトを基盤としています。つまり、スタイルを指定でき、プロパティがデータ バインディングの対象になる場合があります。 Date プロパティの既定のバインド モードは BindingMode.TwoWay で、Model-View-ViewModel (MVVM) アーキテクチャを使用するアプリケーションのデータ バインドのターゲットである可能性があることを意味します。

DateTime プロパティの初期化

コードで、MinimumDateMaximumDateDate のプロパティを DateTime 型の値に初期化できます。

DatePicker datePicker = new DatePicker
{
    MinimumDate = new DateTime(2018, 1, 1),
    MaximumDate = new DateTime(2018, 12, 31),
    Date = new DateTime(2018, 6, 21)
};

XAML で DateTime 値を指定すると、XAML パーサーは CultureInfo.InvariantCulture 引数を持つ DateTime.Parse メソッドを使用して文字列を DateTime 値に変換します。 日付は、2 桁の月、2 桁の日、およびスラッシュで区切られた 4 桁の年という正確な形式で指定する必要があります。

<DatePicker MinimumDate="01/01/2018"
            MaximumDate="12/31/2018"
            Date="06/21/2018" />

DatePickerBindingContext プロパティが (例として) 名前付きの MinDateMaxDateSelectedDateDateTime 型のプロパティを含むビューモデルのインスタンスに設定されている場合は、DatePicker を次のようにインスタンス化できます。

<DatePicker MinimumDate="{Binding MinDate}"
            MaximumDate="{Binding MaxDate}"
            Date="{Binding SelectedDate}" />

この例では、3 つのプロパティはすべて、ビューモデル内の対応するプロパティに初期化されます。 Date プロパティには TwoWay のバインド モードがあるため、ユーザーが選択した新しい日付がビューモデルに自動的に反映されます。

DatePicker がその Date プロパティにバインドを含まない場合、アプリケーションは DateSelected イベントにハンドラーをアタッチして、ユーザーが新しい日付を選択したときに通知されるようにする必要があります。

フォント プロパティの設定については、「フォント」をご覧ください。

DatePicker とレイアウト

DatePicker と共に CenterStart または End のような制約のない水平レイアウト オプションを使用できます。

<DatePicker ···
            HorizontalOptions="Center"
            ··· />

ただし、これは推奨されません。 Format プロパティの設定によっては、選択した日付に異なる表示幅が必要になる場合があります。 たとえば、"D" 書式指定文字列では DateTime に日付が長い形式で表示され、"2018 年 12 月 12 日、水曜日" には "2018 年 5 月 4 日、金曜日" より大きな表示幅が必要です。 プラットフォームによっては、この違いにより、DateTime ビューの レイアウトの幅が変更されたり、表示が切り捨てられたりする可能性があります。

ヒント

既定の HorizontalOptions 設定の FillDatePicker と共に使用し、Grid セルに DatePicker を入力するときに Auto の幅を使用しないことをお勧めします。

アプリケーションの DatePicker

サンプルには、そのページの 2 つの DatePicker ビューが含まれています。 これらは 2 つの日付を選択するために使用でき、プログラムはそれらの日付の間の日数を計算します。 プログラムでは、MinimumDate プロパティと MaximumDate プロパティの設定は変更されないため、2 つの日付は 1900 から 2100 の間である必要があります。

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:DaysBetweenDates"
             x:Class="DaysBetweenDates.MainPage">
    <ContentPage.Padding>
        <OnPlatform x:TypeArguments="Thickness">
            <On Platform="iOS" Value="0, 20, 0, 0" />
        </OnPlatform>
    </ContentPage.Padding>

    <StackLayout Margin="10">
        <Label Text="Days Between Dates"
               Style="{DynamicResource TitleStyle}"
               Margin="0, 20"
               HorizontalTextAlignment="Center" />

        <Label Text="Start Date:" />

        <DatePicker x:Name="startDatePicker"
                    Format="D"
                    Margin="30, 0, 0, 30"
                    DateSelected="OnDateSelected" />

        <Label Text="End Date:" />

        <DatePicker x:Name="endDatePicker"
                    MinimumDate="{Binding Source={x:Reference startDatePicker},
                                          Path=Date}"
                    Format="D"
                    Margin="30, 0, 0, 30"
                    DateSelected="OnDateSelected" />

        <StackLayout Orientation="Horizontal"
                     Margin="0, 0, 0, 30">
            <Label Text="Include both days in total: "
                   VerticalOptions="Center" />
            <Switch x:Name="includeSwitch"
                    Toggled="OnSwitchToggled" />
        </StackLayout>

        <Label x:Name="resultLabel"
               FontAttributes="Bold"
               HorizontalTextAlignment="Center" />

    </StackLayout>
</ContentPage>

それぞれの DatePicker には、長い日付形式の "D" の Format プロパティが割り当てられます。 また、endDatePicker オブジェクトには、その MinimumDate プロパティを対象とするバインドがあることにも注意してください。 バインディング ソースは、startDatePicker オブジェクトの選択された Date プロパティです。 これにより、終了日は常に開始日以降になります。 2 つの DatePicker オブジェクトに加えて、Switch には "両日を合計して含める" というラベルが付いています。

2 つの DatePicker ビューには、DateSelected イベントにアタッチされたハンドラーがあり、その Toggled イベントに Switch ハンドラーがアタッチされています。 これらのイベント ハンドラーは分離コード ファイルにあり、2 つの日付の間の日数の新しい計算をトリガーします。

public partial class MainPage : ContentPage
{
    public MainPage()
    {
        InitializeComponent();
    }

    void OnDateSelected(object sender, DateChangedEventArgs args)
    {
        Recalculate();
    }

    void OnSwitchToggled(object sender, ToggledEventArgs args)
    {
        Recalculate();
    }

    void Recalculate()
    {
        TimeSpan timeSpan = endDatePicker.Date - startDatePicker.Date +
            (includeSwitch.IsToggled ? TimeSpan.FromDays(1) : TimeSpan.Zero);

        resultLabel.Text = String.Format("{0} day{1} between dates",
                                            timeSpan.Days, timeSpan.Days == 1 ? "" : "s");
    }
}

サンプルを最初に実行すると、両方の DatePicker ビューが今日の日付に初期化されます。 次のスクリーンショットは、iOS と Android 上で実行されるプログラムを示しています。

日付間の日数の開始

DatePicker ディスプレイのいずれかをタップすると、プラットフォーム日付ピッカーが呼び出されます。 プラットフォームでは、この日付ピッカーは非常に異なる方法で実装されていますが、各アプローチは、そのプラットフォームのユーザーにはなじみのあるものです。

日付間の日数の選択

ヒント

Android では、カスタム レンダラーで CreateDatePickerDialog メソッドをオーバーライドすることで、DatePicker ダイアログをカスタマイズできます。 これにより、たとえば、ボタンをダイアログに追加できます。

2 つの日付を選択すると、アプリケーションにそれらの日付の間の日数が表示されます。

日付間の日数の結果