如何获取光标位置字符?文本框自动补全大括号遇数组越界问题
记事本程序自动补全成对大括号的问题
我正在开发一款类似记事本的程序,希望实现文本框中输入左大括号{时自动补全为成对大括号的功能,但当前对应的if语句运行时出现数组越界崩溃问题。该if语句位于文本框的TextChanged方法中,尝试调整textBox1.SelectionStart的加减值后仍无法解决。
当前使用的代码:
if(textBox1.Text[textBox1.SelectionStart] == '{') { //Removes the last { textBoxList.Clear(); for(int i = 0; i < textBox1.TextLength - 2; i++) { textBoxList.Add(Convert.ToString(textBox1.Text[i])); } textBox1.Text = ""; for(int i = 0; i < textBoxList.Count; i++) { textBox1.Text += textBoxList[i]; } //Adds the new curly braces textBox1.Text += indentCurlyBraces; //Goes inside the if textBox1.SelectionStart = textBox1.TextLength - 2; textBox1.ScrollToCaret(); }
问题原因分析
- 数组越界:
textBox1.SelectionStart的取值范围是0到textBox1.Text.Length(光标在文本末尾时等于Length),而字符串索引仅到Length-1,直接访问textBox1.Text[textBox1.SelectionStart]必然会在光标处于末尾时触发越界异常。 - TextChanged递归触发:在TextChanged事件中修改
textBox1.Text会再次触发该事件,导致逻辑重复执行,进一步加剧索引混乱。 - 文本拼接冗余:用List循环拼接字符串的方式效率低且易出错,属于不必要的冗余操作。
修正后的代码实现
// 添加私有变量防止递归触发TextChanged事件 private bool isUpdatingText = false; private void textBox1_TextChanged(object sender, EventArgs e) { if (isUpdatingText) return; // 确保文本长度和光标位置合法,获取刚输入的字符索引 if (textBox1.Text.Length > 0 && textBox1.SelectionStart > 0) { int lastInputIndex = textBox1.SelectionStart - 1; if (textBox1.Text[lastInputIndex] == '{') { isUpdatingText = true; // 移除刚输入的单个左大括号,替换为成对格式 string updatedText = textBox1.Text.Remove(lastInputIndex, 1) + indentCurlyBraces; textBox1.Text = updatedText; // 将光标定位到成对大括号之间 textBox1.SelectionStart = lastInputIndex + 1; textBox1.ScrollToCaret(); isUpdatingText = false; } } }
关键优化点
- 防止递归触发:通过
isUpdatingText标记,避免修改文本时重复执行TextChanged逻辑。 - 合法索引判断:先确认光标位置和文本长度的合法性,再访问字符,彻底避免越界。
- 高效文本操作:使用
string.Remove直接处理文本,替代冗余的List循环拼接。 - 精准光标定位:基于输入位置直接计算光标目标位置,避免通过文本长度间接计算的误差。
内容的提问来源于stack exchange,提问作者user18054055
相关产品推荐
相关产品推荐

