简体   繁体   English

Xamarin.Forms 中的可空 TimePicker

[英]Nullable TimePicker in Xamarin.Forms

I'm using TimePicker for displaying time in my app.我正在使用TimePicker在我的应用程序中显示时间。 When time is already set then it displays correctly, but when time is not set, then it display default 12 : 00 AM time.当时间已经设置时,它会正确显示,但当时间没有设置时,它会显示默认的 12 : 00 AM 时间。 So I just want display null value when time is not set.所以我只想在未设置时间时显示null值。 Is it possible to set nullable value to TimePicker in Xamarin Forms?是否可以在 Xamarin Forms 中将nullable值设置为TimePicker

You can create one custom View with a TimePicker and Label .您可以使用TimePickerLabel创建一个自定义View If no time is selected then "hh:mm" will appear otherwise the time will appear on the label.如果未选择时间,则会出现“hh:mm”,否则时间将出现在标签上。 To show the timepicker dialog there is a tapGestureRecognizer which will set the focus to timepicker when label is tapped.要显示时间选择器对话框,有一个tapGestureRecognizer将在点击标签时将焦点设置为时间选择器。

public class NullableTimePicker : ContentView
{
    private const string NullTimeLabel = "hh : mm";
    private readonly TimePicker _timePicker;
    private readonly Label _label;                

    public static readonly BindableProperty TimeProperty = BindableProperty.Create<NullableTimePicker, TimeSpan?>(t => t.Time, null, BindingMode.TwoWay, propertyChanged: OnTimeChanged);

    public NullableTimePicker()
    {
         _label = new Label
         {
              Text = NullTimeLabel,
              HorizontalOptions = LayoutOptions.FillAndExpand,
              VerticalOptions = LayoutOptions.Fill,
              HorizontalTextAlignment = TextAlignment.Start,
              VerticalTextAlignment = TextAlignment.Center,
              TextColor = Color.Black,
              FontSize = Device.GetNamedSize(NamedSize.Medium, typeof(Label))
         };

         _timePicker = new TimePicker
         {
              IsVisible = false,
              HorizontalOptions = LayoutOptions.FillAndExpand,
              VerticalOptions = LayoutOptions.Fill
         };

         Content = new StackLayout
         {
              Children =
              {
                   _label,
                   _timePicker
              },
              Padding = 0,
              Spacing = 0,
              Margin = 0
         };

         Padding = 0;
         Margin = 0;

         var tapGestureRecognizer = new TapGestureRecognizer();
         tapGestureRecognizer.Tapped += TapGestureRecognizer_Tapped;
         GestureRecognizers.Add(tapGestureRecognizer);

         _timePicker.PropertyChanged += timePicker_PropertyChanged;

         PropertyChanged += NullableTimePicker_PropertyChanged;
   }

  private void NullableTimePicker_PropertyChanged(object sender, PropertyChangedEventArgs e)
  {
         if (_label != null && e.PropertyName == IsEnabledProperty.PropertyName)
         {
               _label.TextColor = IsEnabled ? Color.Black : Color.Gray;
         }
  }

  private void timePicker_PropertyChanged(object sender, PropertyChangedEventArgs e)
  {
         if (e.PropertyName == TimePicker.TimeProperty.PropertyName && _timePicker != null)
         {
                    Time = _timePicker.Time;
         }
   }

   private void TapGestureRecognizer_Tapped(object sender, EventArgs e)
   {
          if (IsEnabled == false)
          {
               return;
          }

          if (_timePicker.IsFocused)
          {
              _timePicker.Unfocus();
          }

          _timePicker.Focus();
     }

     private static void OnTimeChanged(BindableObject bindable, TimeSpan? oldvalue, TimeSpan? newvalue)
     {
           var nullableTimePicker = bindable as NullableTimePicker;
           if (nullableTimePicker != null && oldvalue != newvalue)
           {
               nullableTimePicker.Time = newvalue;
           }
     }

     public TimeSpan? Time
     {
          get
          {
               return GetValue(TimeProperty) as TimeSpan?;
          }
          set
          {
               SetValue(TimeProperty, value);

               if (value.HasValue && _timePicker.Time != value)
               {
                   _timePicker.Time = value.Value;
               }
               SetLabelText(value);
           }
      }

      private void SetLabelText(TimeSpan? value)
      {
           _label.Text = value.HasValue ? ConvertTimeSpanToString(value.Value) : NullTimeLabel;
      }          
}

I use this我用这个

/// <summary>
/// DatePicker der null Werte erlaubt
/// </summary>
public class CustomDatePicker : DatePicker
{
    /// <summary>
    /// PropertyName für die <c>NullableDate</c> Property
    /// </summary>
    public const string NullableDatePropertyName = "NullableDate";
    /// <summary>
    /// Die BinableProperty
    /// </summary>
    public static readonly BindableProperty NullableDateProperty = BindableProperty.Create<CustomDatePicker, DateTime?>(i => i.NullableDate, null, BindingMode.TwoWay, null, NullableDateChanged);
    /// <summary>
    /// Datumswert welches null Werte akzeptiert
    /// </summary>
    public DateTime? NullableDate
    {
        get
        {
            return (DateTime?)this.GetValue(NullableDateProperty);
        }
        set
        {
            this.SetValue(NullableDateProperty, value);
        }
    }
    /// <summary>
    /// Der Name der <c>NullText</c> Property
    /// </summary>
    public const string NullTextPropertyName = "NullText";
    /// <summary>
    /// Die BindableProperty
    /// </summary>
    public static readonly BindableProperty NullTextProperty = BindableProperty.Create<CustomDatePicker, string>(i => i.NullText, default(string), BindingMode.TwoWay);
    /// <summary>
    /// Der Text der angezeigt wird wenn <c>NullableDate</c> keinen Wert hat
    /// </summary>
    public string NullText
    {
        get
        {
            return (string)this.GetValue(NullTextProperty);
        }
        set
        {
            this.SetValue(NullTextProperty, value);
        }
    }
    /// <summary>
    /// Der Name der <c>DisplayBorder</c> Property
    /// </summary>
    public const string DisplayBorderPropertyName = "DisplayBorder";
    /// <summary>
    /// Die BindableProperty
    /// </summary>
    public static readonly BindableProperty DisplayBorderProperty = BindableProperty.Create<CustomDatePicker, bool>(i => i.DisplayBorder, default(bool), BindingMode.TwoWay);
    /// <summary>
    /// Gibt an ob eine Umrandung angezeigt werden soll oder nicht
    /// </summary>
    public bool DisplayBorder
    {
        get
        {
            return (bool)this.GetValue(DisplayBorderProperty);
        }
        set
        {
            this.SetValue(DisplayBorderProperty, value);
        }
    }

    /// <summary>
    /// Erstellt eine neue Instanz von <c>CustomDatePicker</c>
    /// </summary>
    public CustomDatePicker()
    {
        this.DateSelected += CustomDatePicker_DateSelected;

        this.Format = "dd.MM.yyyy";
    }
    /// <summary>
    /// Wird gefeuert wenn ein neues Datum selektiert wurde
    /// </summary>
    /// <param name="sender">Der Sender</param>
    /// <param name="e">Event Argumente</param>
    void CustomDatePicker_DateSelected(object sender, DateChangedEventArgs e)
    {
        this.NullableDate = new DateTime(
            e.NewDate.Year, 
            e.NewDate.Month, 
            e.NewDate.Day, 
            this.NullableDate.HasValue ? this.NullableDate.Value.Hour : 0,
            this.NullableDate.HasValue ? this.NullableDate.Value.Minute : 0,
            this.NullableDate.HasValue ? this.NullableDate.Value.Second : 0);
    }

    /// <summary>
    /// Gefeuert wenn sich <c>NullableDate</c> ändert
    /// </summary>
    /// <param name="obj">Der Sender</param>
    /// <param name="oldValue">Der alte Wert</param>
    /// <param name="newValue">Der neue Wert</param>
    private static void NullableDateChanged(BindableObject obj, DateTime? oldValue, DateTime? newValue)
    {
        var customDatePicker = obj as CustomDatePicker;

        if (customDatePicker != null)
        {
            if (newValue.HasValue)
            {
                customDatePicker.Date = newValue.Value;
            }
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM