Avalon Text Editor选中特殊字符时显示异常(\或__)求助
AvalonEdit JSON文本选中特殊字符显示异常修复方案
问题现象
在封装的CustomizedPrettyJSONTextBox中输入"some, text",双击选中逗号时自动显示反斜杠\;选中{或}等字符时显示__,存在怪异的显示异常。
代码背景
为实现多窗口复用,将AvalonEdit封装为CustomizedPrettyJSONTextBox类,把Text设为依赖属性用于ViewModel双向绑定,语法高亮采用官方JSON.xshd规则。
封装类代码
public class CustomizedPrettyJSONTextBox : TextEditor, INotifyPropertyChanged { public CustomizedPrettyJSONTextBox() { using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("mynamespace.JSONSyntaxColoringRule.xshd")) { if (stream != null) { using (XmlReader reader = new XmlTextReader(stream)) { IHighlightingDefinition highlightingDefinition = HighlightingLoader.Load(reader, HighlightingManager.Instance); ((TextEditor)this).SyntaxHighlighting = highlightingDefinition; } } } } public static DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(CustomizedPrettyJSONTextBox), new PropertyMetadata((obj, args) => { CustomizedPrettyJSONTextBox target = (CustomizedPrettyJSONTextBox)obj; if (target.Text != (string)args.NewValue) target.Text = (string)args.NewValue; }) ); public string Text { get { return base.Text; } set { base.Text = value; } } protected override void OnTextChanged(EventArgs e) { SetCurrentValue(TextProperty, base.Text); RaisePropertyChanged(TextProperty.Name); base.OnTextChanged(e); } public event PropertyChangedEventHandler? PropertyChanged; public void RaisePropertyChanged(string info) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(info)); } } }
XAML使用示例
<mynamespace:CustomizedPrettyJSONTextBox x:Name="avalonJSONTextBox" Margin="10" Grid.Row="2" Style="{StaticResource CustomJSONTextBoxStyle}" > <Binding Path="MyViewModelProperty" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged" NotifyOnValidationError="True"> <Binding.ValidationRules> <commonItems:JSONValidator /> </Binding.ValidationRules> </Binding> </mynamespace:CustomizedPrettyJSONTextBox>
问题根源
- 循环触发的属性更新:自定义
Text依赖属性的回调中直接赋值target.Text = args.NewValue,而Text的setter又调用base.Text = value,同时OnTextChanged里再用SetCurrentValue更新依赖属性,形成循环触发,导致文本被意外转义或替换。 - 冗余的属性变更通知:AvalonEdit的
TextEditor本身已内置属性变更通知逻辑,额外实现INotifyPropertyChanged并在OnTextChanged中触发,干扰了原有文本处理流程。
修复方案
方案1:修复依赖属性回调逻辑
修改依赖属性的PropertyChanged回调,使用SetCurrentValue更新基类的TextProperty,避免循环触发:
public static DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(CustomizedPrettyJSONTextBox), new PropertyMetadata((obj, args) => { CustomizedPrettyJSONTextBox target = (CustomizedPrettyJSONTextBox)obj; string newValue = args.NewValue as string; if (target.base.Text != newValue) { target.SetCurrentValue(TextEditor.TextProperty, newValue); } }) );
方案2:简化封装类实现
直接复用基类的TextProperty,移除冗余的自定义Text属性和INotifyPropertyChanged实现:
public class CustomizedPrettyJSONTextBox : TextEditor { public CustomizedPrettyJSONTextBox() { using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("mynamespace.JSONSyntaxColoringRule.xshd")) { if (stream != null) { using (XmlReader reader = XmlReader.Create(stream)) { IHighlightingDefinition highlightingDefinition = HighlightingLoader.Load(reader, HighlightingManager.Instance); SyntaxHighlighting = highlightingDefinition; } } } } // 直接使用基类的TextProperty进行绑定,无需额外封装 }
方案3:调整OnTextChanged逻辑
若需保留自定义Text属性,修改OnTextChanged仅在值不同时更新依赖属性:
protected override void OnTextChanged(EventArgs e) { string currentText = base.Text; if (currentText != GetValue(TextProperty) as string) { SetCurrentValue(TextProperty, currentText); } base.OnTextChanged(e); }
额外检查
确保嵌入的JSONSyntaxColoringRule.xshd文件与官方版本一致,没有被修改导致特殊字符的高亮规则出现错误(比如错误的转义或替换配置)。
内容的提问来源于stack exchange,提问作者Vignesh G
相关产品推荐
相关产品推荐

