首页 > 解决方案 > 如何为 UWP 的 DatePicker 创建自定义渲染器?

问题描述

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

我的代码是:

自定义控件.cs

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

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

[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 创建自定义渲染器吗?请帮忙。

标签: xamarin.formsxamarin.uwp

解决方案


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

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

我需要做的最后一件事是确保 Date 在两个不同控件之间注册的位置发生变化,因为它们为此使用了不同的事件。

我的代码是:

自定义日期选择器.cs

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

UWP 文件夹中的 CustomDatePickerRenderer.cs


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

推荐阅读