2015-11-07 48 views
3

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

回答

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; 
      } 
     } 
    } 
} 
+0

此代码中的变量和方法是有名的,但文档标签使其不易读。特别是因为他们是德国人。 –

+0

@Alessandro感谢您的回应,但我在寻找Nullable Time选择器,TimePicker使用TimeSpan类进行时间间隔。 –

+1

您应该提及[来源](https://forums.xamarin.com/discussion/comment/146468/#Comment_146468)。这不是你的代码,它只是复制和粘贴。 – testing

1

您可以创建一个自定义的ViewTimePickerLabel。如果没有选择时间,则会出现“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; 
     }   
}