3
votes

I am working on disabling copy/paste option menus on xamarin forms Entry, I am able to disable copy option using IsPassword=true attribute but this attribute also converts the normal input field to password field, which is not a requirement.

<Entry IsPassword="true" Placeholder="Password" TextColor="Green" BackgroundColor="#2c3e50" />

Thanks in advance.

1

1 Answers

8
votes

This has to do with how Forms functions. Using iOS as the example here, the CanPerform override referred to in the other answer's Bugzilla issue is using the UIMenuController as the withSender and not the UITextField itself that might otherwise be expected. This is because the EntryRenderer class is a ViewRenderer<TView, TNativeView> type and subsequently is using whatever TNativeView (in this case, the UITextView) has in its CanPerform. Because nothing is going to be overridden by default, one still sees all of the cut/copy/paste options in the UIMenuController.

As a result, there would be a couple options. You could first make the modification where if you don't want copy/paste but are fine with getting rid of everything else, you can use UIMenuController.SharedMenuController.SetMenuVisible(false, false) in a custom renderer inheriting from EntryRenderer. If you look around on SO, there are similar questions where this is a possible route.

Alternatively, you can create a "true" custom renderer inheriting from ViewRenderer<TView, TNativeView> as ViewRenderer<Entry, YourNoCopyPasteUITextFieldClassName>. The class inheriting from UITextField can then override CanPerform as something like follows:

    public override bool CanPerform(Selector action, NSObject withSender)
    {
        if(action.Name == "paste:" || action.Name == "copy:" || action.Name == "cut:")
            return false;

        return base.CanPerform(action, withSender);
    }

This will require more effort because the custom renderer will not have the same behavior as the EntryRenderer, but as Xamarin.Forms is now open source, you could look to it for some ideas as to how the EntryRenderer functions normally. Something similar would likely have to be done for Android.

Edit: For Android, you can probably use this SO answer as a starting point: How to disable copy/paste from/to EditText

Another custom renderer, this time inheriting from ViewRenderer<Entry, EditText>, and create a class inside of it like this (in the most basic form):

class Callback : Java.Lang.Object, ActionMode.ICallback
{

    public bool OnActionItemClicked(ActionMode mode, IMenuItem item)
    {
        return false;
    }

    public bool OnCreateActionMode(ActionMode mode, IMenu menu)
    {
        return false;
    }

    public void OnDestroyActionMode(ActionMode mode)
    {

    }

    public bool OnPrepareActionMode(ActionMode mode, IMenu menu)
    {
        return false;
    }
}

Then, in your OnElementChanged method, you can set the native control and the CustomSelectionActionModeCallback value:

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

        if (Control != null)
        {
            Control.CustomSelectionActionModeCallback = new Callback();
        }
    }

Doing something like the following appears to disable all of the copy/paste/cut functionality on the custom entry as far as the toolbar goes. However, you can still long click to show the paste button, to which I've poked around a bit hadn't found an answer yet beyond setting LongClickable to false. If I do find anything else in that regard, I'd make sure to update this.