Xamarin Editor Control CursorPosition на Android - PullRequest
0 голосов
/ 13 июля 2020

В настоящее время я работаю над проектом, который требует большого количества манипуляций с текстом, и я пытаюсь создать функцию, которая может вставлять текст в текущую позицию CursorPosition. Я использую редактор в качестве своего текстового элемента управления, и я заметил, что Xamarin еще не предоставляет реализацию для CursorPosition. не могу дождаться этого, так как у меня крайний срок.

Я создал свой собственный CustomRenderer для элемента управления Editor, и у меня CursorPosition работает для UWP. Однако когда я попытался сделать то же самое для Android, я заметил, что мне нужно использовать событие EventHandler SelectionChanged; в интерфейсе IFormsEditText, который мне недоступен, поскольку они пометили интерфейс как внутренний.

Небольшой фрагмент кода для отображения прогресса:

internal class EditorRenderer : Xamarin.Forms.Platform.Android.EditorRenderer
{
    bool _cursorPositionChangePending;
    bool _nativeSelectionIsUpdating;

    IElementController ElementController => Element as IElementController;

    public EditorRenderer(Context context) : base(context) { }

    private Editor _editor;

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

        _editor = (Editor)Element;

        _cursorPositionChangePending = Element.IsSet(Editor.CursorPositionProperty);

        // I wanted to do something along the lines of this
        //if (Control is IFormsEditText editText)
        //{
        //    editText.SelectionChanged += SelectionChanged;
        //}

        if (_cursorPositionChangePending)
            UpdateCursorSelection();
    }

    protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        base.OnElementPropertyChanged(sender, e);
        if (e.PropertyName == Editor.CursorPositionProperty.PropertyName)
        {
            UpdateCursorSelection();
        }
    }
    void SelectionChanged(object sender, XamarinFormsDroid.SelectionChangedEventArgs e)
    {
        if (_nativeSelectionIsUpdating || Control == null || Element == null)
            return;

        int cursorPosition = _editor.CursorPosition;
        int selectionStart = EditText.SelectionStart;

        if (!_cursorPositionChangePending)
        {
            var start = cursorPosition;

            if (selectionStart != start)
                SetCursorPositionFromRenderer(selectionStart);
        }

        if (!_selectionLengthChangePending)
        {
            int elementSelectionLength = Math.Min(EditText.Text.Length - cursorPosition, _editor.SelectionLength);

            var controlSelectionLength = EditText.SelectionEnd - selectionStart;
            if (controlSelectionLength != elementSelectionLength)
                SetSelectionLengthFromRenderer(controlSelectionLength);
        }
    }

Пробовал ли кто-нибудь создать свой собственный рендерер для android с рабочей реализацией CursorPosition? Или у кого-нибудь есть идеи, как это можно реализовать? Пожалуйста, дайте мне знать.

1 Ответ

0 голосов
/ 16 июля 2020

Редактор не поддерживает CursorPosition Событие изменено. Вы можете создать собственный элемент управления EditText. EditText предоставляет событие OnSelectionChanged. И добавьте этот настраиваемый EditText в EditorRenderer.

MyEditor.cs : Создать настраиваемый элемент управления редактора. И привязка события OnSelectionChanged.

public class MyEditor : Editor
{
    public static readonly BindableProperty SelectionChangedProperty =
    BindableProperty.Create("SelectionChanged", typeof(EventHandler), typeof(MyEditor), null);

    public event EventHandler SelectionChanged;

   public void SelectionChange(int preIndex,int currentIndex)
    {
        EventHandler eventHandler = this.SelectionChanged;
        SelectionEventArgs selectionEventArgs = new SelectionEventArgs() { lastPos = preIndex, curPos = currentIndex };
        eventHandler?.Invoke((object)this, selectionEventArgs);
    }

   public class SelectionEventArgs : EventArgs
    {
       public int lastPos { get; set; }
        public int curPos { get; set; }
    }
}

EditorRenderer.cs :

[assembly: ExportRenderer(typeof(MyEditor), typeof(XamarinDemo.Droid.EditorRenderer))]
namespace XamarinDemo.Droid
{
class EditorRenderer : Xamarin.Forms.Platform.Android.EditorRenderer, MyEditText.EditTextSelectChange
{
    Context _context;
    public EditorRenderer(Context context) : base(context)
    {
        _context = context;
    }

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

        MyEditText myEditText = new MyEditText(_context);
        myEditText.Text = Element.Text;
        myEditText.setEditTextSelectChange(this);
        SetNativeControl(myEditText);
    }


    public void change(int lastPos, int curPos)
    {
        //Console.WriteLine("lastPos ===" + lastPos + "curPos ====" + curPos);
        ((MyEditor)Element).SelectionChange(lastPos, curPos);
    }

}
}

MyEditText.cs : в Xamarin.Forms Android spefi c project, создайте EditTextSelectChange для наследования EditorRenderer.

 class MyEditText :FormsEditText
{

    private int mLastPos = 0;
    private int mCurPos = 0;

    private EditTextSelectChange editTextSelectChange;

    public void setEditTextSelectChange(EditTextSelectChange editTextSelectChange)
    {
        this.editTextSelectChange = editTextSelectChange;
    }

    public MyEditText(Context context):base(context)
    {
    }


    protected override void OnSelectionChanged(int selStart, int selEnd)
    {
        base.OnSelectionChanged(selStart, selEnd);
        if (this.editTextSelectChange != null)
        {
            mCurPos = selEnd;
            editTextSelectChange.change(mLastPos, mCurPos);
            mLastPos = mCurPos;
        }

    }

    public interface EditTextSelectChange
    {
        void change(int lastPos, int curPos);
    }
}

Использование:

        <local:MyEditor SelectionChanged="SelectionChange" Text="hakssksksssfsvdsv" />

Скрытый код:

 public partial class Page13 : ContentPage
{
    public Page13()
    {
        InitializeComponent();
    }

    private void SelectionChange(object sender, EventArgs e)
    {
        Console.WriteLine("lastpos =="+ ((SelectionEventArgs)e).lastPos +"curpos =="+ ((SelectionEventArgs)e).curPos);
    }
}

Скриншот:

введите описание изображения здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...