「AI 回完话,左边那个框一片黑,一个字都看不见。拿鼠标滚一下,字又冒出来了。」
老大把这条甩过来的时候,我第一反应是控件没重绘,或者是显卡/驱动那类玄学。截图里对话框确实整片黑,可右边 AI 的答案是正常的——也就是说模型答得好好的,是显示这一层,把已经画好的字给盖了。
那个框是 WinForms 的 RichTextBox,用户输入、AI 回复、中间那些「🧠 记忆已更新」的系统行,全往这一个框里追加。写法用的是一套特别常见的:先 AppendText 把新内容贴进去,再把刚贴的那一段选起来,单独设个字体颜色——用户的话一种色、AI 另一种、系统行又一种,看着清楚。
坑就埋在「回选改字体」这半句里。RichTextBox 里你对已经写进去的一段改格式,它会把这一段、甚至整篇重排一遍。内容短的时候看不出来。可 AI 的回复里经常带很长的命令,一行放不下就自动折行,重排之后高度、光标位置全变了。紧接着我调了 ScrollToCaret(),本意是滚到光标那儿,结果它滚过了界,滚到内容下边那片空白里去了。屏幕上一片黑,不是没字,是滚过了头,盯着内容外面的空气看。
第一版我冲着「重排」去改:把「先追加、再回选改字体」改成「先设好插入点格式,再追加」,不再回头选中已有内容,就不触发重排了。自己试了几次,看着好了。发给老大,隔天又是一张黑的。
那次才注意第二个细节:我让它「滚到底」,用的是文档最末尾。而 RichTextBox 的末尾常常挂着一个空行(追加时顺手带了个换行)。滚到最末,等于滚到那个空行底下——又是空白。于是第二版把「滚到底」改成「滚到最后一个真的有字的字符」,再补一句「稳一下再滚一次」的兜底(重排有延迟,滚早了也会滚错位)。两处一起改,才干净。
教训记到现在:「滚到底」别信文档末尾,末尾通常是个空行;还有,追加完再回选改格式,看着方便,代价是整段重排,内容一长就出事。
回头看,这 bug 的脾气和同一批里另一个很像——那次是后台的「🧠 记忆已更新」系统行异步插进来,正好插在用户打字的中途,把人正在输入的字冲成了半截系统提示。都是「界面上看着好端端的内容,其实是另一段东西在捣乱」。
界面这一层的东西,七亿批量远程管理工具的教程页里,动作写得都很直白;可滚动位置、重排时机这种,文档不会写,只能一个个自己踩。这类桌面工具,交互坑往往比逻辑坑更磨人——逻辑错了至少报错,界面错了,它只是安安静静给你一片黑。
改完那天,我顺手在代码里留了行注释:滚到最后一个有字的字符,别滚末尾空行。省得下次换我或者别人,又照着老写法抄一遍。

评论