VB.NET中RTB字体族与字号下拉框编码Bug修复求助
核心问题原因
- 格式被清空、空引用报错:当选区包含多种不同字体、字号、样式的混合格式文本时,
RichTextBox.SelectionFont属性会直接返回Nothing。原有代码未对该返回值做完整容错,且同步下拉框选中项时会直接触发SelectedIndexChanged事件,事件内的格式赋值逻辑会直接覆盖选区内原有混合格式,触发空引用时直接抛错。 - 快捷键误触发:原有按键判断逻辑写法错误,
Keys.Control、Keys.Shift是枚举值,直接用AndAlso拼接永远返回布尔真值,没有实际检测两个修饰键是否按下,导致单独按逗号、句号键时也会触发字号修改逻辑。同时原有字号增减逻辑直接修改文本属性,未做数值校验,步长控制不符合要求。
修复方案
首先在窗体类的全局变量定义位置,加一个同步状态标记,避免程序更新下拉框时循环触发格式修改事件:
' UI同步锁标记,值为True时表示程序正在同步控件状态,不响应用户触发的选择变更事件 Private _isSyncingUi As Boolean = False
修复字体选择框事件
替换原有tbSelectFont_SelectedIndexChanged代码,增加同步锁判断和空值容错:
Private Sub tbSelectFont_SelectedIndexChanged(sender As Object, e As EventArgs) Handles tbSelectFont.SelectedIndexChanged If _isSyncingUi Then Return If tbSelectFont.SelectedItem Is Nothing Then Return If Description.SelectionFont Is Nothing Then Dim baseFont As Font = Description.Font Description.SelectionFont = New Font(tbSelectFont.SelectedItem.ToString(), baseFont.Size, baseFont.Style) Else Description.SelectionFont = New Font(tbSelectFont.SelectedItem.ToString(), Description.SelectionFont.Size, Description.SelectionFont.Style) End If End Sub
修复字号选择框事件
替换原有tbSelectSize_SelectedIndexChanged代码,增加同步锁判断、数值校验和空值容错:
Private Sub tbSelectSize_SelectedIndexChanged(sender As Object, e As EventArgs) Handles tbSelectSize.SelectedIndexChanged If _isSyncingUi Then Return Dim newSize As Single If Not Single.TryParse(tbSelectSize.Text, newSize) Then If tbSelectSize.SelectedItem Is Nothing Then Return newSize = CSng(tbSelectSize.SelectedItem) End If newSize = Math.Clamp(newSize, 1, 200) If Description.SelectionFont Is Nothing Then Dim baseFont As Font = Description.Font Description.SelectionFont = New Font(baseFont.Name, newSize, baseFont.Style) Else Description.SelectionFont = New Font(Description.SelectionFont.Name, newSize, Description.SelectionFont.Style) End If End Sub
修复选区变更同步逻辑
替换原有Description_SelectionChanged代码,处理混合格式场景,同步时开启锁标记避免误触发格式修改:
Private Sub Description_SelectionChanged(sender As Object, e As EventArgs) Handles Description.SelectionChanged _isSyncingUi = True Try If Description.SelectionFont IsNot Nothing Then ' 单格式选区,直接同步对应字体、字号到下拉框 tbSelectFont.Text = Description.SelectionFont.Name tbSelectSize.Text = Description.SelectionFont.Size.ToString() Dim fontMatchIndex = tbSelectFont.FindStringExact(Description.SelectionFont.Name) If fontMatchIndex >= 0 Then tbSelectFont.SelectedIndex = fontMatchIndex Dim sizeMatchIndex = tbSelectSize.FindStringExact(Description.SelectionFont.Size.ToString()) If sizeMatchIndex >= 0 Then tbSelectSize.SelectedIndex = sizeMatchIndex Else ' 混合格式选区,下拉框显示混合提示,不做格式赋值 tbSelectFont.Text = "混合字体" tbSelectSize.Text = "混合字号" tbSelectFont.SelectedIndex = -1 tbSelectSize.SelectedIndex = -1 End If Finally _isSyncingUi = False End Try End Sub
修复字号快捷键逻辑
删除原有错误的按键判断代码,在RichTextBox的KeyDown事件中写正确的组合键判断逻辑,步长固定为1:
Private Sub Description_KeyDown(sender As Object, e As KeyEventArgs) Handles Description.KeyDown ' 仅在Ctrl+Shift同时按下时响应字号调整 If e.Modifiers <> (Keys.Control Or Keys.Shift) Then Return Dim currentSize As Single If Description.SelectionFont IsNot Nothing Then currentSize = Description.SelectionFont.Size Else Single.TryParse(tbSelectSize.Text, currentSize) If currentSize <= 0 Then currentSize = 10 End If Select Case e.KeyCode Case Keys.Oemcomma ' Ctrl+Shift+, 字号-1 currentSize = Math.Max(1, currentSize - 1) e.SuppressKeyPress = True Case Keys.OemPeriod ' Ctrl+Shift+. 字号+1 currentSize = Math.Min(200, currentSize + 1) e.SuppressKeyPress = True Case Else Return End Select ' 应用新字号 tbSelectSize.Text = currentSize.ToString() If Description.SelectionFont IsNot Nothing Then Description.SelectionFont = New Font(Description.SelectionFont.Name, currentSize, Description.SelectionFont.Style) End If End Sub
补充说明
- 窗体加载初始化字体、字号列表后,记得给两个下拉框设置默认选中值(比如默认选微软雅黑10号),避免初始状态空值报错。
- 混合选区的提示文本可根据需求自定义,核心是
SelectionFont返回Nothing时不要强行给选区内文本赋值格式,否则会清空原有混合样式。 - 如果需要支持用户在字号框手动输入非预设字号,保留现有
TryParse逻辑即可,不需要强制匹配下拉框列表项。
内容的提问来源于stack exchange,提问作者John Michael Wilkinson
相关产品推荐
相关产品推荐

