Xamarin.Forms DatePicker

Download Sample下载示例

允许用户选择日期的 Xamarin.Forms 视图。

Xamarin.FormsDatePicker 调用平台的日期选取器控件,并允许用户选择日期。 DatePicker 定义了八个属性:

当用户选择一个日期时,DatePicker 将触发 DateSelected 事件。

警告

设置 MinimumDateMaximumDate 时,请确保 MinimumDate 始终小于或等于 MaximumDate。 否则,DatePicker 将引发异常。

在内部,DatePicker 确保 Date 介于 MinimumDateMaximumDate之间(含)。 如果 MinimumDateMaximumDate 设置为 Date 不在它们之间,则 DatePicker 将调整 Date 的值。

所有八个属性都由 BindableProperty 对象支持,这意味着它们可以设置样式,并且属性可以作为数据绑定的目标。 Date 属性的默认绑定模式为 BindingMode.TwoWay,这意味着它可以是应用程序中使用模型-视图-视图模型 (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 分析程序使用 DateTime.Parse 方法和 CultureInfo.InvariantCulture 参数将字符串转换为 DateTime 值。 必须以精确的格式指定日期:两位数的月、两位数的日和四位数的年,以斜线分隔:

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

如果将 DatePickerBindingContext 属性设置为包含比如名为 MinDateMaxDateSelectedDate,类型为 DateTime 的属性的 viewmodel 实例,则可以按如下所示 DatePicker 进行实例化:

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

在此示例中,所有三个属性都初始化为 viewmodel 中相应的属性。 由于 Date 属性的绑定模式为 TwoWay,因此用户选择的任何新日期都会自动反映在 viewmodel 中。

如果 DatePicker 在其 Date 属性上不包含绑定,应用程序应将处理程序附加到用户选择新日期时要通知的 DateSelected 事件。

有关设置字体属性的信息,请参阅字体

DatePicker 和布局

可以使用不受约束的水平布局选项,例如 CenterStartEndDatePicker

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

但是不建议这样做。 根据 Format 属性的设置,所选日期可能需要不同的显示宽度。 例如,“D”格式字符串导致 DateTime 以长格式显示日期,并且“Wednesday, September 12, 2018”需要比“Friday, May 4, 2018”更大的显示宽度。 根据平台的不同,这种差异可能会导致 DateTime 视图更改布局宽度,或导致显示被截断。

提示

在将 DatePicker 放入 Grid 单元格时,最好将 Fill 的默认 HorizontalOptions 设置与 DatePicker 一同使用,并不使用 Auto 的宽度。

应用程序中的 DatePicker

DaysBetweenDates 示例在其页面上包括两个 DatePicker 视图。 这些日期可用于选择两个日期,程序计算这些日期之间的天数。 程序不会更改 MinimumDateMaximumDate 属性的设置,因此两个日期必须介于 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 属性。 这可确保结束日期始终晚于或等于开始日期。 除了两个 DatePicker 对象之外,Switch 还标记为“总计包含两天”。

这两个 DatePicker 视图具有附加到 DateSelected 事件的处理程序,Switch 具有附加到其 Toggled 事件的处理程序。 这些事件处理程序位于代码隐藏文件中,并触发两个日期之间的天数的新计算:

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 上运行的程序:

Days Between Dates Start

点击任一 DatePicker 显示将调用平台日期选取器。 这些平台以非常不同的方式实现此日期选取器,但每个方法都对该平台的用户很熟悉:

Days Between Dates Select

提示

在 Android 上,可以通过在自定义呈现器中重写 CreateDatePickerDialog 方法来自定义 DatePicker 对话框。 例如,这允许向对话框添加其他按钮。

选择两个日期后,应用程序会显示这些日期之间的天数:

Days Between Dates Result