I need to block the paste function in a datepicker on XamarinForms

試著忘記壹切 提交于 2019-12-23 20:30:01

问题


In the solution that I'm building, I have a date-picker that works fine. But, if the user press the touch and paste something, it will overwrite the date.

When the user pastes, the events of OnElementChanged, OnElementPropertyChanged and even the INotifyPropertyChanged are not raised. I also can't find a option to block the paste function. (When the date is choose normally, the events are being called.)

This happens in iOS and Android. Can someone help me? I am stuck and my researches don't help me much.


回答1:


On iOS platform

DatePicker behaves this way because under the hood it is implemented via UITextField. To avoid editing of UITextField you have to assign it a delegate which returns false from ShouldChangeCharacters method.

The full solution will be the following:

Declare a child of a DatePicker in a shared project:

public class ExtendedDatePicker : DatePicker
{
}

Declare a corresponding renderer in iOS project:

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

Implement the UneditableUITextFieldDelegate:

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

This will not prevent the 'copy'/'paste' menu from being shown but DatePicker value will not be changed after pressing them.

On Android platform

The underlying UI element for DatePicker on Android is EditText.

I have posted articles explaining how to manipulate context menu of EditText in native Android and Xamarin.Forms. You can get the overall idea there.

I was not able to perform a long tap on a DatePicker to see the problem thus I can only guess about the proper fix, but a renderer similar to this one should completely disable context menu for selected text as well as a paste option when a user taps a cursor:

[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 and CustomInsertionActionModeCallback would return false from OnCreateActionMode and will prevent menu from appearing.

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

=======
UPDATE: this question inspired me to create an article extending this answer with some explanations and details.



来源:https://stackoverflow.com/questions/52652007/i-need-to-block-the-paste-function-in-a-datepicker-on-xamarinforms

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