如何为 UWP 的 DatePicker 创建自定义渲染器?

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

我正在尝试为 UWP 创建自定义 DatePicker 渲染器,但出现编译错误。 尝试获取 CalenderDatePicker 而不是普通的 DataPicker。无论我尝试其中一个还是另一个,我都会收到相同的错误。

我的代码是:

CustomControl.cs

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

还有我的 CustomDatePickerRenderer.cs 在 UWP 文件夹中

[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 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'.

从文档中我发现这应该没问题 - 是否无法为 DatePicker 创建自定义渲染器?请帮忙。

那是因为它没有使用正确的 DatePicker

该方法需要 Xamarin.Forms.DatePicker,但它引用了 Windows.UI.Xaml.Controls.DatePicker

要修复它,请使用长命名空间

[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);
            }
        }
    }
}

或者使用 class 顶部的 using 符号来指明要使用哪一个。像

using DatePicker = Xamarin.Forms.DatePicker;

希望对您有所帮助。-

对于经验丰富的开发人员来说,这可能不是什么大事,但我很高兴我让它工作了 - 用 UWP CalendarDatePicker 替换 Xamarin.Forms DataPicker - 所以我只是 post我的工作解决方案,如果其他人可以使用它。

感谢 pinedax 解决了我最初的问题 - 最后我实际上将其更改为我的 CustomDatePicker,因为这是 MS 文档中的内容。

我需要做的最后一件事是确保日期更改在两个不同控件之间注册的位置,因为它们为此使用不同的事件。

我的代码是:

CustomDatePicker.cs

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

CustomDatePickerRenderer.cs 在 UWP 文件夹中


[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);
        }
    }   
}

我现在可以从我的 Xamarin.Forms XAML 文件

中引用我的 CustomDatePicker (UWP CalendarDatePicker)
<local:CustomDatePicker x:Name="FilterDatePicker" DateSelected="OnDateFilterDateChanged" VerticalOptions="Center"></local:CustomDatePicker>