How do I select text in a view (Editor) and use the selected value?

This is needed for both Android and iOS, but I am starting with Android only.
The only thing I have successfully researched and used is a Custom Renderer for EditorRenderer, overriding OnElementChanged and calling SetSelectAllOnFocus(true). However, this is not what I need. And I don't even need the softkeyword, which I am hiding with ShowSoftInputOnFocus = false; SelectAll() does not work.

What I need/want:

  1. Load a page with an Editor and some initial text I set in the code-behind when opening the page.
  2. Highlight All text in the Editor; Do not show the softkeyboard.
  3. The user should be able to use the default Editor selection UI to drag the edges and narrowdown to a particular sentence, blurb, etc, from the text.
  4. I want to suppress the context menu(copy, paste, etc)
  5. Have buttons on the page (or some interface), to allow actions like Use Selection (which would copy the text and use it somewhere else in the app), Clear 6. Selection, Highlight All (self explanatory).

This is sort of a business description of what I need to achieve. Technically, I have tried many things and the last attempt before posting this question here was something like this:

  1. In shared code, Create a IMyEditor interface with methods like HighlightAll(), ClearAll(), Use();
  2. In shared code, Create a MyEditorBase : Editor
  3. In Android (or iOS), Implement IMyEditor as MyEditor using MyEditorBase as a base class and register it with DependencyServices.
  4. In Android, Create and Implement MyEditorRenderer and register the Android class MyEditor with it.
  5. In Android -> MyEditorRenderer create methods HighlightAll(), GetHighlightedText(), etc.
  6. In Android -> MyEditor create methods HighlightAll(), etc.

Here's the import steps which made me go this route.
7. In Android, from MyEditor.HighlightAll() -> Access the renderer which would have access to the native control with var renderer = Platform.GetRenderer(this);

This result of this is null;

I was expecting to have a renderer, so I could finish by doing:

  1. Access the native Editor (EditText for Android) var nativeEditText = (global::Android.Widget.EditText)Control;
  2. nativeEditText.SelectAll();

I've tried many different things, it would make this question enormous. What am I missing? Which the specific need to highlight and use text is the direct question, the other side is fundamentally, how to access native controls, customize and use their behavior (not just colors, background, lines, appearance, etc, which does work). but method overloading, adding behavior, etc.

All help is appreaciated :)

Best Answer

Answers

  • JohnHardmanJohnHardman GBUniversity ✭✭✭✭✭

    @LeonardoRodrigues.1839 - Some of your requirements are going to be tricky, particularly on Android.

    Whilst it is talking about Entry rather than Editor, take a look at https://forums.xamarin.com/discussion/comment/305729/#Comment_305729 as that includes some of the points you need to handle.

    Other bits you will need to look at for Android, will be similar to the following (this is again for Entry, rather than Editor):

                FormsEditText nativeEntryEditText = Control;
                    nativeEntryEditText?.SetSelection(0, Control.Text.Length); // check the args here - I've just typed this rather than tested it, as I don't do this in my app
    
                MainActivity.TheInstance.Window.SetSoftInputMode(SoftInput.AdjustResize);
    
            nativeEntryEditText.CustomSelectionActionModeCallback = MainActivity.TheInstance; // this requires MainActivity to implement an interface, one method of which is shown below
    
    
        public bool OnCreateActionMode(ActionMode mode, IMenu menu)
        {
            // Cut is item 0 - 16908320
            // Copy is item 1 - 16908321
            // Paste is item 2 - 16908322
            // Share is item 3 - 16908341
    
            if (menu != null)
            {
                menu.RemoveItem(16908320); // cut - 1020020 hex
                menu.RemoveItem(16908322); // paste - 1020022 hex
            }
    
            return true;
        }
    

    Sorry that the above is just a collection of snippets, but it should hopefully point you in the right direction

  • @JohnHardman thanks for the reply, I am going to read/try somethings now. Meanwhile, would you care to elaborate on requirements 1-5 as to why/how you think they would be tricky? Thanks and bit back in a bit with an update.

  • JohnHardmanJohnHardman GBUniversity ✭✭✭✭✭

    @LeonardoRodrigues.1839 - Here's my off-the-top-of-my-head thoughts on 1-5

    1. Easy
    2. Highlighting text - easy. Hiding soft keyboard whilst focus remains on Editor - ok on iOS, although potentially fragile if base renderer changes in future. Suspect hiding the soft keyboard whilst still focused, without side-effects, may be tricky on Android.
    3. Easy
    4. Ok, but potentially fragile if base renderers change in future.
    5. As soft keyboard hidden, using built-in buttons may be problematic on Android. Don't know re. own buttons elsewhere on page.
  • Still stuck... any light on step #7 of my thought process in the original question? Why is GetRenderer() returning null.

    From your last reply, requirement #2 (easy) Highlighting. It doesn't work. I tried nativeEntryEditText?.SetSelection(0, Control.Text.Length); and doens't work. I tried looking for some SetFocus/Focus method to see if it is not highlighted due to it not being in focus...no luck.

    Any additional suggestions on other elements/controls to look at? It doesn't have to be the Editor. Even paid controls I can try out.

    I don't mind custom building something, but first I need to get unstuck in principle (back to #7 above).

  • @JohnHardman I will be trying later on today and let you know, thank you so much for the communication. From what I understand, this is what I will be doing... since the way to communicate with the underlying native control would be via a BindableProperty, then I'd set it up with something like a timestamp/milliseconds or boolean then my custom button from the page will interact with the class which will modify the BindableProperty then triggering the code I need to run in the CustomRenderer.

  • Making an acceptable answer because I made progress based on it. Now I have the concept of bindableproperties driving the behavior, thanks @JohnHardman . I realize also the question was bloated with many questions. I'll come back here tomorrow to comment more for posterity and perhaps spin off new questions. (Text is only highlighted if the control has focus, I haven't used the value highlighted yet.)

Sign In or Register to comment.