当前位置 : 主页 > 手机开发 > android >

我需要在XamarinForms上的datepicker中阻止粘贴功能

来源:互联网 收集:自由互联 发布时间:2021-06-11
在我正在构建的解决方案中,我有一个工作正常的日期选择器.但是,如果用户按下触摸并粘贴某些内容,它将覆盖日期. 当用户粘贴时,不会引发OnElementChanged,OnElementPropertyChanged甚至INotifyPr
在我正在构建的解决方案中,我有一个工作正常的日期选择器.但是,如果用户按下触摸并粘贴某些内容,它将覆盖日期.

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

这种情况发生在iOS和Android中.有人能帮我吗?我被困住了,我的研究对我帮助不大.

在iOS平台上

DatePicker以这种方式运行,因为它是通过UITextField实现的.
为了避免编辑UITextField,您必须为其分配一个委托,该委托从ShouldChangeCharacters方法返回false.

完整的解决方案如下:

在共享项目中声明DatePicker的子级:

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

实现UneditableUITextFieldDelegate:

public class UneditableUITextFieldDelegate : NSObject, IUITextFieldDelegate
{
    [Export("textField:shouldChangeCharactersInRange:replacementString:")]
    public bool ShouldChangeCharacters(UITextField textField, NSRange range, string replacementString) =>
        false;
}

这不会阻止显示“复制”/“粘贴”菜单,但按下后不会更改DatePicker值.

在Android平台上

Android上DatePicker的底层UI元素是EditText.

我已发布文章解释如何在native Android和Xamarin.Forms中操作EditText的上下文菜单.您可以在那里获得整体想法.

我无法长时间点击DatePicker来查看问题因此我只能猜测正确的修复,但是类似于这个的渲染器应该完全禁用所选文本的上下文菜单以及用户时的粘贴选项点击一个光标:

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

CustomInsertionActionModeCallback和CustomInsertionActionModeCallback将从OnCreateActionMode返回false并阻止菜单出现.

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) { }
}

=======
更新:这个问题激发了我创建一个article扩展这个答案的一些解释和细节.

网友评论