4

How can we set CursorPosition in Editor. We can set CursorPostion in Entry, but how to set it in Editor? I know we can do it using Custom Renderer in Xamarin Forms, but how to implement it?

Junaid Pathan
  • 3,850
  • 1
  • 25
  • 47

1 Answers1

4

We cannot set CursorPosition in Editor as we set it in Entry. We need to use Custom Renderer.

Using Custom Renderer makes most of the native functions and implementations possible in Xamarin Forms.

To set Cursor Position in Editor in Xamarin Forms. This answer may be a bit lenghthier for beginners like me so please bear with me.

In your Shared Project add a Class EditorExtended.cs

public class EditorExtended : Editor
{
}

In your XAML Page add namespace for reference

<xmlns:Local="clr-namespace:ApplicationName.FolderNameThatContainsEditorExtended class">

<!-- If EditorExtended.cs is in "Controls" Folder-->
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage ...
             xmlns:Local="clr-namespace:MyApplication.Controls">
            
             ...

    <StackLayout HorizontalOptions="Center">             
        <Local:EditorExtended x:Name="CustomEditor"></Local:EditorExtended>
    </StackLayout>
  • Now in your Android Project add Custom Renderer. Make a folder and add EditorRendererExtended.cs
[assembly: ExportRenderer(typeof(EditorExtended), typeof(EditorRendererExtended))]
namespace MyApplication.Droid.PlatformSpecific.ExtendedControls
{
    public class EditorRendererExtended : EditorRenderer
    {
        public EditorRendererExtended(Context context) : base(context)
        {
        }

        protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);
            if (Control != null)
            {
                Control.RequestFocus();                
                Control.SetSelection(Control.Text.Length);                
            }
        }       
    }
}
  • Similarly in UWP Project Make a folder and add Custom Renderer in Platform Specific code.
[assembly: ExportRenderer(typeof(EditorExtended), typeof(EditorRendererExtended))]
namespace MyApplication.UWP.PlatformSpecific.ExtendedControls
{
    public class EditorRendererExtended: EditorRenderer
    {
        public EditorRendererExtended()
        {
        }

        protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);
            if (Control != null)
            {
                Control.Focus(Windows.UI.Xaml.FocusState.Pointer);
                Control.SelectionStart = Control.Text.Length;
            }
        }
    }
}
  • I haven't tested in iOS, but the method will be similar. Just add EditorRendererExtended.cs class in Platform Specific folder in iOS. This code is not tested, you are free to edit the answer if you know the solution. Here is the code I have implemented, but not tested.
[assembly:ExportRenderer(typeof(EditorExtended), typeof(EditorRendererExtended))]
namespace MyApplication.iOS.PlatformSpecific.ExtendedControls
{
    public class EditorRendererExtended : EditorRenderer
    {
        public EditorRendererExtended()
        {
        }

        protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);
            if (Control != null)
            {
                // just change this statement to the one that works.
                Control.SelectedTextRange = Control.GetTextRange(fromPosition: Control.BeginningOfDocument, toPosition: Control.BeginningOfDocument);
            }
        }
    }
}

Do not forget to include the below statement in all the Platform Specific code that you want to target, otherwise it won't work

[assembly: ExportRenderer(typeof(EditorExtended), typeof(EditorRendererExtended))]

EditorRendererExtended is different for each platform, you can change its name like EditorRendererExtendedAndroid or EditorRendererExtendedUWP for better understanding. I have just named them similar as I find naming them differently is not needed and makes it unnecessarily lengthy.

Junaid Pathan
  • 3,850
  • 1
  • 25
  • 47
  • 1
    @LeoZhu-MSFT, I want to mark it as an answer, but don't you know Stackoverflow does not allow to Mark as Answer if I post Question and its Answer immediately? When I click Mark as Answer, it says *"You can accept your own answer tomorrow"*. Please remove the downvote if you have downvoted the Question and the answer. – Junaid Pathan Jun 29 '20 at 09:43
  • You just need wait for two days .You could mark yourself. – Leo Zhu Jun 29 '20 at 09:44
  • @LeoZhu-MSFT, Yes I know that, then why did you say to mark as an answer? I know I can mark it as an answer within 2 days, I had posted the Question and the Answer yesterday, and I need to wait for 1 more day to mark as an accepted answer. – Junaid Pathan Jun 29 '20 at 09:47