How can I create a custom renderer for DatePicker for UWP?

邮差的信 提交于 2020-03-25 18:40:49

问题


I'm trying to create a custom DatePicker renderer for UWP but I'm getting a compile error. Trying to get a CalenderDatePicker instead of the normal DataPicker. I am getting the same error whether I try one or the other.

My code is:

CustomControl.cs

namespace myNameSpace.CustomControl
{
    public class CustomDatePicker : DatePicker
    {
    }
}

And my CustomDatePickerRenderer.cs in the UWP folder

[assembly: ExportRenderer(typeof(CustomDatePicker), typeof(CustomDatePickerRenderer))]
namespace myNameSpace.UWP
{    
    public class CustomDatePickerRenderer : ViewRenderer<DatePicker, Windows.UI.Xaml.Controls.CalendarDatePicker>, ITabStopOnDescendants, IDontGetFocus
    {
        protected override void OnElementChanged(ElementChangedEventArgs<DatePicker> e)
        {
            base.OnElementChanged(e);

            if (Control == null)
            {
                Windows.UI.Xaml.Controls.CalendarDatePicker datePicker = new Windows.UI.Xaml.Controls.CalendarDatePicker();
                SetNativeControl(datePicker);
            }
        }
    }
}

The error I get is:

The type 'Windows.UI.Xaml.Controls.DatePicker' cannot be used as type parameter 'TElement' in the generic type or method 'ViewRenderer<TElement, TNativeElement>'. There is no implicit reference conversion from 'Windows.UI.Xaml.Controls.DatePicker' to 'Xamarin.Forms.View'.

From the documentation I can find this should be ok - is it not possible to create a custom renderer for the DatePicker? Please help.


回答1:


That's because it's not using the correct DatePicker.

That method expects the Xamarin.Forms.DatePicker but instead it's referencing the Windows.UI.Xaml.Controls.DatePicker.

To fix it either use the long namespace

[assembly: ExportRenderer(typeof(CustomDatePicker), typeof(CustomDatePickerRenderer))]
namespace myNameSpace.UWP
{    
    public class CustomDatePickerRenderer : ViewRenderer<Xamarin.Forms.DatePicker, Windows.UI.Xaml.Controls.CalendarDatePicker>, ITabStopOnDescendants, IDontGetFocus
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.DatePicker> e)
        {
            base.OnElementChanged(e);

            if (Control == null)
            {
                Windows.UI.Xaml.Controls.CalendarDatePicker datePicker = new Windows.UI.Xaml.Controls.CalendarDatePicker();
                SetNativeControl(datePicker);
            }
        }
    }
}

Or use the using notation at the top of your class to indicate which one to use. Something like

using DatePicker = Xamarin.Forms.DatePicker;

Hope this helps.-




回答2:


This might not be a big thing by experiences developers, but I'm thrilled that I got it working - substituting the Xamarin.Forms DataPicker with the UWP CalendarDatePicke - so I'll just post my working solution, if someone else could use it.

Thanks to pinedax for solving my initial problem - which I actually changed to my CustomDatePicker in the end, because this is what is in the documentation from MS.

The last thing I needed was to ensure that Date changes where registered between to two different controls, since they use different events for this.

My code is:

CustomDatePicker.cs

namespace myNameSpace.CustomControl
{
    public class CustomDatePicker : DatePicker
    {        
    }
}

CustomDatePickerRenderer.cs in the UWP folder


[assembly: ExportRenderer(typeof(CustomDatePicker), typeof(CustomDatePickerRenderer))]
namespace myNameSpace.UWP
{   
    public class CustomDatePickerRenderer : ViewRenderer<CustomDatePicker, Windows.UI.Xaml.Controls.CalendarDatePicker>
    {
        protected override void OnElementChanged(ElementChangedEventArgs<CustomDatePicker> e)
        {
            base.OnElementChanged(e);

            if (e.OldElement != null)
            {
                // Unsubscribe from event handlers and cleanup any resources
                Control.DateChanged -= OnDateChanged;
                Element.DateSelected -= OnDateSelected;
            }

            if (e.NewElement != null)
            {
                if (Control == null)
                {
                    // Instantiate the native control and assign it to the Control property with
                    // the SetNativeControl method
                    if (Control == null)
                    {
                        Windows.UI.Xaml.Controls.CalendarDatePicker datePicker = new Windows.UI.Xaml.Controls.CalendarDatePicker();
                        datePicker.FirstDayOfWeek = Windows.Globalization.DayOfWeek.Monday;
                        SetNativeControl(datePicker);
                    }
                }
                Control.DateChanged += OnDateChanged;
                Element.DateSelected += OnDateSelected;
            }
        }

        private void OnDateChanged(CalendarDatePicker sender, CalendarDatePickerDateChangedEventArgs e)
        {           
            DateTimeOffset dto = (DateTimeOffset)e.NewDate;
            Element.Date = dto.DateTime;
        }

        private void OnDateSelected(Object sender, DateChangedEventArgs e)
        {
            DateTime dt = e.NewDate;
            Control.Date = new DateTimeOffset(dt);
        }
    }   
}

And I can now reference my CustomDatePicker (UWP CalendarDatePicker) from my Xamarin.Forms XAML file

<local:CustomDatePicker x:Name="FilterDatePicker" DateSelected="OnDateFilterDateChanged" VerticalOptions="Center"></local:CustomDatePicker>


来源:https://stackoverflow.com/questions/60437105/how-can-i-create-a-custom-renderer-for-datepicker-for-uwp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!