Issue
I have found a custom renderer online but there is an error. Does anyone know how can I make a date time control? Currently I am using separate date picker and time picker but I want it to be combined.
I will post the code below that I have found from another post. This is the link to the post Xamarin Forms date and time picker
using System;
using Foundation;
using Test;
using Test.Droid;
using UIKit;
using ObjCRuntime;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly:ExportRenderer(typeof(MyPicker), typeof(MyPickerRenderer))]
namespace Test.Droid
{
public class MyPickerRenderer : PickerRenderer
{
string SelectedValue;
[Obsolete]
public MyPickerRenderer()
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Picker> e)
{
base.OnElementChanged(e);
if (Control != null)
{
SetTimePicker();
}
}
void SetTimePicker()
{
UIDatePicker picker = new UIDatePicker
{
Mode = UIDatePickerMode.DateAndTime
};
picker.SetDate(NSDate.Now, true);
picker.AddTarget(this, new Selector("DateChange:"), UIControlEvent.ValueChanged);
Control.InputView = picker;
UIToolbar toolbar = (UIToolbar)Control.InputAccessoryView;
UIBarButtonItem done = new UIBarButtonItem("Done", UIBarButtonItemStyle.Done, (object sender, EventArgs click) =>
{
Control.Text = SelectedValue;
toolbar.RemoveFromSuperview();
picker.RemoveFromSuperview();
Control.ResignFirstResponder();
MessagingCenter.Send<Object, string>(this, "pickerSelected", SelectedValue);
});
UIBarButtonItem empty = new UIBarButtonItem(UIBarButtonSystemItem.FlexibleSpace, null);
toolbar.Items = new UIBarButtonItem[] { empty, done };
}
[Export("DateChange:")]
void DateChange(UIDatePicker picker)
{
NSDateFormatter formatter = new NSDateFormatter();
formatter.DateFormat = "MM-dd HH:mm aa"; //you can set the format as you want
Control.Text = formatter.ToString(picker.Date);
SelectedValue = formatter.ToString(picker.Date);
MessagingCenter.Send<Object, string>(this, "pickerSelected", SelectedValue);
}
}
}
Solution
Make the DateTimePicker inherit a ContentView
instead of just an Entry, and then creates the Stacklayout which add the Entry and the date and time pickers to content.
See the DateTimePicker2.cs:
public class DateTimePicker2 : ContentView, INotifyPropertyChanged
{
public Entry _entry { get; private set; } = new Entry();
public DatePicker _datePicker { get; private set; } = new DatePicker() { MinimumDate = DateTime.Today, IsVisible = false };
public TimePicker _timePicker { get; private set; } = new TimePicker() { IsVisible = false };
string _stringFormat { get; set; }
public string StringFormat { get { return _stringFormat ?? "dd/MM/yyyy HH:mm"; } set { _stringFormat = value; } }
public DateTime DateTime
{
get { return (DateTime)GetValue(DateTimeProperty); }
set { SetValue(DateTimeProperty, value); OnPropertyChanged("DateTime"); }
}
private TimeSpan _time
{
get
{
return TimeSpan.FromTicks(DateTime.Ticks);
}
set
{
DateTime = new DateTime(DateTime.Date.Ticks).AddTicks(value.Ticks);
}
}
private DateTime _date
{
get
{
return DateTime.Date;
}
set
{
DateTime = new DateTime(DateTime.TimeOfDay.Ticks).AddTicks(value.Ticks);
}
}
BindableProperty DateTimeProperty = BindableProperty.Create("DateTime", typeof(DateTime), typeof(DateTimePicker2), DateTime.Now, BindingMode.TwoWay, propertyChanged: DTPropertyChanged);
public DateTimePicker2()
{
BindingContext = this;
Content = new StackLayout()
{
Children =
{
_datePicker,
_timePicker,
_entry
}
};
_datePicker.SetBinding<DateTimePicker2>(DatePicker.DateProperty, p => p._date);
_timePicker.SetBinding<DateTimePicker2>(TimePicker.TimeProperty, p => p._time);
_timePicker.Unfocused += (sender, args) => _time = _timePicker.Time;
_datePicker.Focused += (s, a) => UpdateEntryText();
GestureRecognizers.Add(new TapGestureRecognizer()
{
Command = new Command(() => _datePicker.Focus())
});
_entry.Focused += (sender, args) =>
{
Device.BeginInvokeOnMainThread(() => _datePicker.Focus());
};
_datePicker.Unfocused += (sender, args) =>
{
Device.BeginInvokeOnMainThread(() =>
{
_timePicker.Focus();
_date = _datePicker.Date;
UpdateEntryText();
});
};
}
private void UpdateEntryText()
{
_entry.Text = DateTime.ToString(StringFormat);
}
static void DTPropertyChanged(BindableObject bindable, object oldValue, object newValue)
{
var timePicker = (bindable as DateTimePicker2);
timePicker.UpdateEntryText();
}
}
Usage in Xaml:
<StackLayout>
<local:DateTimePicker2></local:DateTimePicker2>
</StackLayout>
Answered By - Wendy Zang - MSFT
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.