.NET 9 MAUI Entry控件动态格式化印度数字时光标位置异常求助
解决MAUI .NET9中数字格式化后光标位置异常问题
问题根源
升级到.NET9后,动态格式化数字时,双向绑定触发的TextChanged事件会覆盖光标位置设置,且未考虑印度格式(hi-IN)中分隔符对光标位置的影响,导致光标跳至错误位置。
解决方案步骤
- 区分用户输入与绑定更新:添加标志位避免循环触发
TextChanged事件; - 精准计算光标位置:遍历格式化后的文本,定位到用户最后输入数字的后方;
- 优化ViewModel格式化逻辑:同步处理数字格式化,避免异步引发的时序问题。
修改后的代码
后台代码(Page.xaml.cs)
private bool _isUpdatingFromViewModel; private void OnTextChanged(object sender, TextChangedEventArgs e) { if (_isUpdatingFromViewModel || string.IsNullOrEmpty(e.NewTextValue)) return; // 仅处理用户输入的纯数字(Numeric键盘输入无逗号) if (e.NewTextValue.Any(c => !char.IsDigit(c))) return; string rawDigits = e.NewTextValue; int newDigitCount = rawDigits.Length; _isUpdatingFromViewModel = true; try { updateCounterPageViewModel.CounterChanged(rawDigits); // 延迟到UI线程绑定更新完成后设置光标 CurrentCounterEntry.Dispatcher.Dispatch(() => { string formattedText = CurrentCounterEntry.Text; int cursorPos = 0; int digitCount = 0; foreach (char c in formattedText) { if (char.IsDigit(c)) { digitCount++; if (digitCount == newDigitCount) { cursorPos++; break; } } cursorPos++; } // 若已遍历完所有数字,光标移至末尾 if (digitCount == newDigitCount) { cursorPos = formattedText.Length; } CurrentCounterEntry.CursorPosition = cursorPos; }); } finally { _isUpdatingFromViewModel = false; } }
ViewModel代码
public void CounterChanged(string addedCounter) { try { if (int.TryParse(addedCounter, out int counterInt)) { CurrentCounter = counterInt.ToString("N0", new CultureInfo("hi-IN")); } else { CurrentCounter = addedCounter; } } catch (Exception ex) { // 可添加日志记录逻辑 } }
XAML调整(可选,显式声明绑定模式)
<customcontrols:BorderlessEntry x:Name="CurrentCounterEntry" Placeholder="Enter counter" Keyboard="Numeric" Text="{Binding CurrentCounter, Mode=TwoWay}" TextChanged="OnTextChanged" Margin="15,3" MaxLength="12"/>
关键说明
_isUpdatingFromViewModel标志位:防止ViewModel更新文本时重复触发格式化逻辑,避免循环;- 光标位置计算:通过遍历格式化后的文本,精准定位到用户最后输入数字的后方,适配印度格式的分隔符规则;
Dispatcher.Dispatch:确保在UI线程上执行光标位置设置,等待绑定更新完成后再操作,避免时序问题。
内容的提问来源于stack exchange,提问作者BSB
相关产品推荐
相关产品推荐

