我需要在XamarinForms上的日期选择器中阻止粘贴函数

我需要在XamarinForms上的日期选择器中阻止粘贴函数,xamarin,xamarin.forms,xamarin.ios,xamarin.android,Xamarin,Xamarin.forms,Xamarin.ios,Xamarin.android,在我正在构建的解决方案中,我有一个工作正常的日期选择器。但是,如果用户按下触摸键并粘贴某些内容,则会覆盖日期 当用户粘贴时,不会引发OnElementChanged、OnElementPropertyChanged甚至INotifyPropertyChanged的事件。我也找不到阻止粘贴功能的选项。(正常选择日期时,将调用事件。) 这发生在iOS和Android中。有人能帮我吗?我陷入困境,我的研究对我帮助不大。在iOS平台上 DatePicker的行为是这样的,因为在引擎盖下,它是通过UITe

在我正在构建的解决方案中,我有一个工作正常的日期选择器。但是,如果用户按下触摸键并粘贴某些内容,则会覆盖日期

当用户粘贴时,不会引发
OnElementChanged
OnElementPropertyChanged
甚至
INotifyPropertyChanged
的事件。我也找不到阻止粘贴功能的选项。(正常选择日期时,将调用事件。)


这发生在iOS和Android中。有人能帮我吗?我陷入困境,我的研究对我帮助不大。

在iOS平台上

DatePicker
的行为是这样的,因为在引擎盖下,它是通过
UITextField
实现的。 为了避免编辑
UITextField
,您必须为其分配一个委托,该委托从
ShouldChangeCharacters
方法返回
false

完整的解决方案如下:

在共享项目中声明日期选择器的子项:

public class ExtendedDatePicker : DatePicker
{
}
在iOS项目中声明相应的渲染器:

[assembly: ExportRenderer(typeof(ExtendedDatePicker), typeof(ExtendedDatePickerRenderer))]  
...    

public class ExtendedDatePickerRenderer : DatePickerRenderer  
{  
    private UneditableUITextFieldDelegate _delegate = new UneditableUITextFieldDelegate();  

    protected override void OnElementChanged(ElementChangedEventArgs<DatePicker> e)  
    {
        base.OnElementChanged(e);

        Control.Delegate = _delegate;
    }
}
这不会阻止显示“复制”/“粘贴”菜单,但按下后不会更改日期选择器的值

在Android平台上

Android上
DatePicker
的底层UI元素是
EditText

我已经发表了一些文章,解释了如何在和中操作
EditText
的上下文菜单。你可以在那里得到整体的想法

我无法在
日期选择器上长时间点击查看问题,因此我只能猜测正确的修复方法,但类似于此的渲染器应完全禁用选定文本的上下文菜单以及用户点击光标时的粘贴选项:

[assembly: ExportRenderer(typeof(ExtendedDatePicker), typeof(ExtendedDatePickerRenderer))]
...

public class ExtendedDatePickerRenderer : DatePickerRenderer
{
    public ExtendedDatePickerRenderer(Context context) : base(context)
    {
    }

    protected override void OnElementChanged(ElementChangedEventArgs<DatePicker> e)
    {
        base.OnElementChanged(e);

        Control.CustomSelectionActionModeCallback = new CustomSelectionActionModeCallback();
        Control.CustomInsertionActionModeCallback = new CustomInsertionActionModeCallback();
    }
}
=======

更新:这个问题激发了我的灵感,用一些解释和细节来扩展这个答案。

如果你能找到android的解决方案并与大家分享,我会非常高兴grateful@ViníciusBritto我已经用Android平台的一些信息更新了我的答案。根据我的经验,短时间和长时间点击
DatePicker
都会打开一个标准系统对话框,因此我无法100%测试我的解决方案。我希望它对你有用,否则请留下评论。对android也有用!非常感谢你!!CustomSelectionActionModeCallback不适用于Tablet。我相信在旧版本的android中,
CustomSelectionActionModeCallback
将无法工作。在我看来,这是操作系统版本或设备制造商的问题,而不是设备的外形因素
[assembly: ExportRenderer(typeof(ExtendedDatePicker), typeof(ExtendedDatePickerRenderer))]
...

public class ExtendedDatePickerRenderer : DatePickerRenderer
{
    public ExtendedDatePickerRenderer(Context context) : base(context)
    {
    }

    protected override void OnElementChanged(ElementChangedEventArgs<DatePicker> e)
    {
        base.OnElementChanged(e);

        Control.CustomSelectionActionModeCallback = new CustomSelectionActionModeCallback();
        Control.CustomInsertionActionModeCallback = new CustomInsertionActionModeCallback();
    }
}
public class CustomInsertionActionModeCallback : Java.Lang.Object, ActionMode.ICallback
{
    public bool OnCreateActionMode(ActionMode mode, IMenu menu) => false;

    public bool OnActionItemClicked(ActionMode m, IMenuItem i) => false;

    public bool OnPrepareActionMode(ActionMode mode, IMenu menu) => true;

    public void OnDestroyActionMode(ActionMode mode) { }
}

public class CustomSelectionActionModeCallback : Java.Lang.Object, ActionMode.ICallback
{
    public bool OnActionItemClicked(ActionMode m, IMenuItem i) => false;

    public bool OnCreateActionMode(ActionMode mode, IMenu menu) => false;

    public bool OnPrepareActionMode(ActionMode mode, IMenu menu) => true;

    public void OnDestroyActionMode(ActionMode mode) { }
}