You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MAUI Entry控件处理连续空格时光标跳至开头问题求助

MAUI Entry控件Behavior修改文本后光标跳转问题解决方法

直接修改Entry.Text会触发控件把光标重置到输入框开头,要解决这个问题,你需要手动计算并恢复光标位置,同时避免事件循环触发。

修改后的WhiteSpaceBehavior代码如下:

namespace TestProj.Behaviors {
    public class WhiteSpaceBehavior : Behavior<Entry>
    {
        private bool _isUpdatingText; // 防止循环触发TextChanged事件

        protected override void OnAttachedTo(Entry entry)
        {
            base.OnAttachedTo(entry);
            entry.TextChanged += OnEntryTextChanged;
        }

        protected override void OnDetachingFrom(Entry entry)
        {
            entry.TextChanged -= OnEntryTextChanged;
            base.OnDetachingFrom(entry);
        }

        private void OnEntryTextChanged(object sender, TextChangedEventArgs e)
        {
            if (_isUpdatingText) return;

            var entry = (Entry)sender;
            var newText = e.NewTextValue ?? string.Empty;

            if (!ContainsConsecutiveWhiteSpaces(newText)) return;

            // 记录当前光标位置
            int originalCursorPosition = entry.CursorPosition;
            // 处理连续空格
            var processedText = RemoveConsecutiveWhiteSpaces(newText);
            // 计算新光标位置:根据文本长度变化调整,避免越界
            int newCursorPosition = originalCursorPosition + (processedText.Length - newText.Length);
            newCursorPosition = Math.Clamp(newCursorPosition, 0, processedText.Length);

            _isUpdatingText = true;
            entry.Text = processedText;
            entry.CursorPosition = newCursorPosition;
            _isUpdatingText = false;
        }

        private bool ContainsConsecutiveWhiteSpaces(string text)
        {
            for (int i = 0; i < text.Length - 1; i++)
            {
                if (char.IsWhiteSpace(text[i]) && char.IsWhiteSpace(text[i + 1]))
                {
                    return true;
                }
            }
            return false;
        }

        private string RemoveConsecutiveWhiteSpaces(string text)
        {
            // 用StringBuilder优化处理效率,替代递归Replace
            StringBuilder sb = new StringBuilder();
            bool lastWasSpace = false;
            foreach (char c in text)
            {
                if (char.IsWhiteSpace(c))
                {
                    if (!lastWasSpace)
                    {
                        sb.Append(c);
                        lastWasSpace = true;
                    }
                }
                else
                {
                    sb.Append(c);
                    lastWasSpace = false;
                }
            }
            return sb.ToString();
        }
    }
 }

核心逻辑说明:

  • _isUpdatingText标志位:避免手动设置entry.Text时再次触发TextChanged事件,造成循环处理。
  • 光标位置计算:根据修改前后文本的长度差调整光标位置,确保光标停留在用户输入的逻辑位置,不会跳回开头。
  • 空格处理优化:用StringBuilder一次遍历完成去重,比递归Replace效率更高,适合长文本场景。

测试时输入This is nice,控件会自动转为This is nice,光标将保持在输入位置,不会出现跳转问题。

内容的提问来源于stack exchange,提问作者Noah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 05:12:47