我尝试在XF项目中实施24小时Time Picker
给定here。
此问题也是之前解决的Focus
和Unfocused
事件的问题,请参阅here
现在我想设置Time Picker
为Focused
的时间,比如我已经将{2}小时绑定到应该打开的Time
属性并且选择了2小时,这是行不通的
我注意到上一次在Time Picker
上被绑定(时间已被选中且点击了Ok
),但我希望选中绑定的Time
。
我正在使用Xamarin Forms 2.5.0.121934
。
我使用了Constant.TimeToBeShowOnPicker.Hours
和Constant.TimeToBeShowOnPicker.Minutes
在代码中绑定Time else的第一个值,默认情况下它是0:00 hrs
或你设置的任何值。
public class TimePicker24Hours : ViewRenderer<Xamarin.Forms.TimePicker, Android.Widget.EditText>, TimePickerDialog.IOnTimeSetListener, IJavaObject, IDisposable
{
private TimePickerDialog dialog = null;
IElementController ElementController => Element as IElementController;
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.TimePicker> e)
{
base.OnElementChanged(e);
this.SetNativeControl(new Android.Widget.EditText(Forms.Context));
this.Control.Click += Control_Click;
this.Control.Text = DateTime.Now.ToString("HH:mm");
this.Control.KeyListener = null;
this.Control.FocusChange += Control_FocusChange;
}
void Control_FocusChange(object sender, Android.Views.View.FocusChangeEventArgs e)
{
if (e.HasFocus)
{
ShowTimePicker();
ElementController.SetValueFromRenderer(VisualElement.IsFocusedPropertyKey, true);
}
else
{
ElementController.SetValueFromRenderer(VisualElement.IsFocusedPropertyKey, false);
}
}
void Control_Click(object sender, EventArgs e)
{
ShowTimePicker();
}
private void ShowTimePicker()
{
if (dialog == null)
{
dialog = new TimePickerDialog(Forms.Context, this, Constant.TimeToBeShowOnPicker.Hours, Constant.TimeToBeShowOnPicker.Minutes, true);
}
dialog.Show();
}
public void OnTimeSet(Android.Widget.TimePicker view, int hourOfDay, int minute)
{
var time = new TimeSpan(hourOfDay, minute, 0);
this.Element.SetValue(Xamarin.Forms.TimePicker.TimeProperty, time);
this.Control.Text = time.ToString(@"hh\:mm");
this.ClearFocus();
}
}
<TimePicker x:Name="time_Picker" Time="{Binding SelectedTime}" IsVisible="false" PropertyChanged="TimePicker_PropertyChanged" />
当要求Time Picker
来Focus
void EditTime_Tapped(object sender, System.EventArgs e)
{
var eventArgs = e as TappedEventArgs;
ViewModel.SelectedTaskItem = (SomeModel)eventArgs.Parameter;
ViewModel.SelectedTime = TimeSpan.FromHours(ViewModel.SomeModel.Time);
Constant.TimeToBeShowOnPicker = ViewModel.SelectedTime;
Device.BeginInvokeOnMainThread(() =>
{
time_Picker.Focus();
});
}
答案 0 :(得分:1)
要确保点按时间选择器时显示当前时间,我们需要在UpdateTime
中加入ShowPicker()
。
我还注意到Control.Text
始终默认为DateTime.Now
。要解决此问题,我们只需在Control.Text
中设置OnElementChanged
。
我已更新自定义渲染器以检查是否设置了Element.Time
,如果已设置,则我们可以设置Control.Text = Element.Time.ToString(@"hh\:mm");
我在这里创建了一个使用这个24小时时间选择器的示例Xamarin.Forms应用程序: https://github.com/brminnick/24HourTimePicker
using System;
using Foundation;
using TimePickerDemo;
using TimePickerDemo.iOS;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
[assembly: ExportRenderer(typeof(CustomTimePicker24H), typeof(CustomTimePicker24HRenderer))]
namespace TimePickerDemo.iOS
{
public class CustomTimePicker24HRenderer : TimePickerRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<TimePicker> e)
{
base.OnElementChanged(e);
if (Control != null)
{
var timePicker = (UIDatePicker)Control.InputView;
timePicker.Locale = new NSLocale("no_nb");
if (Element != null && !Element.Time.Equals(default(TimeSpan)))
Control.Text = Element.Time.ToString(@"hh\:mm");
else
Control.Text = DateTime.Now.ToString("HH:mm");
}
}
}
}
using System;
using Android.App;
using Android.Text;
using Android.Content;
using Android.Runtime;
using Java.Lang;
using TimePickerDemo;
using TimePickerDemo.Droid;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(CustomTimePicker24H), typeof(CustomTimePicker24HRenderer))]
namespace TimePickerDemo.Droid
{
public class CustomTimePicker24HRenderer : ViewRenderer<TimePicker, Android.Widget.EditText>, TimePickerDialog.IOnTimeSetListener, IJavaObject, IDisposable
{
TimePickerDialog _dialog;
public CustomTimePicker24HRenderer(Context context) : base(context)
{
}
Context CurrentContext => Plugin.CurrentActivity.CrossCurrentActivity.Current.Activity;
IElementController ElementController => Element as IElementController;
public void OnTimeSet(Android.Widget.TimePicker view, int hourOfDay, int minute)
{
var time = new TimeSpan(hourOfDay, minute, 0);
Element.SetValue(TimePicker.TimeProperty, time);
Control.Text = time.ToString(@"hh\:mm");
ClearFocus();
}
protected override void OnElementChanged(ElementChangedEventArgs<TimePicker> e)
{
base.OnElementChanged(e);
SetNativeControl(new Android.Widget.EditText(CurrentContext));
if (Control != null)
{
Control.Click += Control_Click;
Control.FocusChange += Control_FocusChange;
if (Element != null && !Element.Time.Equals(default(TimeSpan)))
Control.Text = Element.Time.ToString(@"hh\:mm");
else
Control.Text = DateTime.Now.ToString("HH:mm");
}
}
void Control_FocusChange(object sender, FocusChangeEventArgs e)
{
if (e.HasFocus)
{
ShowTimePicker();
ElementController.SetValueFromRenderer(VisualElement.IsFocusedPropertyKey, true);
}
else
{
ElementController.SetValueFromRenderer(VisualElement.IsFocusedPropertyKey, false);
}
}
void Control_Click(object sender, EventArgs e) => ShowTimePicker();
void ShowTimePicker()
{
if (_dialog == null)
_dialog = new TimePickerDialog(CurrentContext, this, Element.Time.Hours, Element.Time.Minutes, true);
_dialog.UpdateTime(Element.Time.Hours, Element.Time.Minutes);
_dialog.Show();
}
}
}