假如代码通过读取一个文本文件逐行处理数据,每 2~3 秒向多行 TextBox 中追加一行处理结果,同时允许用户对这些内容进行实时修改。会出现这样一种情况,当使用 TextBox.AppendText() 方法追加内容时,用户的编辑焦点会被抢占,用户可能正在输入或选择文本,但由于焦点的丢失,这些操作会被打断,影响用户体验。
解决思路
我们需要记录用户在 TextBox 中的光标位置和选中的文本范围,确保在追加内容后光标和选中区域保持不变,如果用户没有主动滚动,TextBox 可以滚动到最新内容。
示例代码
private void SafeAppendText(string line)
{
// 检查是否需要跨线程操作
if (InvokeRequired)
{
Invoke(new Action<string>(SafeAppendText), line);
return;
}
// 保存当前选择状态
int selStart = textBox.SelectionStart;
int selLength = textBox.SelectionLength;
// 追加新内容
textBox.AppendText(line);
// 恢复用户的选择状态
textBox.SelectionStart = selStart;
textBox.SelectionLength = selLength;
// 滚动到光标位置(如果用户没有选中文本)
if (selLength == 0)
{
textBox.ScrollToCaret();
}
}
SelectionStart 和 SelectionLength 分别记录光标位置和选中范围。在追加新内容后,重新设置这些值,确保用户输入的连续性。如果你的场景很复杂,如大批量数据更新 TextBox,可能仍然会出现轻微的界面闪烁或焦点跳动。这种情况无法完全避免,可以通过减少更新频率或改用其他控件(如 RichTextBox)优化体验。