Xamarin.Forms中的Nullable TimePicker

问题描述 投票:3回答:2

我正在使用TimePicker在我的应用程序中显示时间。当时间已经设置然后它正确显示,但是如果没有设置时间,则它显示默认的上午12:00时间。所以我只想在没有设置时间时显示null值。是否有可能在Xamarin Forms中将nullable值设置为TimePicker

c# xamarin xamarin.forms nullable timepicker
2个回答
1
投票

我用这个

/// <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;
            }
        }
    }
}

1
投票

您可以使用ViewTimePicker创建一个自定义Label。如果没有选择时间,则会出现“hh:mm”,否则时间将出现在标签上。为了显示timepicker对话框,有一个tapGestureRecognizer,它会在点击标签时将焦点设置为timepicker。

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;
      }          
}
© www.soinside.com 2019 - 2024. All rights reserved.