设置UseAdornerForTextboxSelectionRendering开关后RichTextBox无法显示文本的问题
问题
设置AppContext.SetSwitch("Switch.System.Windows.Controls.Text.UseAdornerForTextboxSelectionRendering", false)后,TextBox表现正常,但RichTextBox无法显示文本,请问原因是什么?能否在不修改XAML代码的前提下,让RichTextBox的表现与TextBox一致?
相关代码
XAML代码
<Grid> <Grid.RowDefinitions> <RowDefinition Height="*" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <Label Content="TextBox" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="25"></Label> <TextBox Height="80" Width="500" Grid.Column="1" SelectionOpacity="1"></TextBox> <Label Content="RichTextBox" Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="25"></Label> <RichTextBox Height="80" Width="500" Grid.Row="1" Grid.Column="1" SelectionOpacity="1" Style="{StaticResource RichTextBoxStyle}"></RichTextBox> </Grid>
.NET 6后台代码
public MainWindow() { AppContext.SetSwitch("Switch.System.Windows.Controls.Text.UseAdornerForTextboxSelectionRendering", false); InitializeComponent(); }
.NET Framework 4.8的App.config配置
<runtime> <AppContextSwitchOverrides value="Switch.System.Windows.Controls.Text.UseAdornerForTextboxSelectionRendering=false"/> </runtime>
原因分析
Switch.System.Windows.Controls.Text.UseAdornerForTextboxSelectionRendering这个开关是专门为TextBox设计的,作用是控制是否用装饰器(Adorner)渲染文本选择区域。但RichTextBox的文本渲染、布局逻辑和TextBox完全不同,它内部依赖装饰器相关逻辑来完成文本绘制和布局管理。当全局关闭这个开关后,RichTextBox的依赖逻辑被破坏,导致文本无法正常显示。
解决方法
.NET 6 实现(不修改XAML)
可以通过反射在后台代码中单独为RichTextBox启用装饰器渲染,无需改动XAML:
public MainWindow() { AppContext.SetSwitch("Switch.System.Windows.Controls.Text.UseAdornerForTextboxSelectionRendering", false); InitializeComponent(); // 遍历可视化树找到RichTextBox实例 var richTextBox = FindVisualChild<RichTextBox>(this); if (richTextBox != null) { // 通过反射设置内部属性恢复装饰器渲染 var prop = typeof(RichTextBox).GetProperty("UseAdornerForSelectionRendering", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); prop?.SetValue(richTextBox, true); } } // 辅助方法:遍历可视化树查找控件 private T FindVisualChild<T>(DependencyObject parent) where T : DependencyObject { for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++) { var child = VisualTreeHelper.GetChild(parent, i); if (child is T tChild) return tChild; var result = FindVisualChild<T>(child); if (result != null) return result; } return null; }
.NET Framework 4.8 实现(不修改XAML)
在App.config中添加RichTextBox专属的开关配置,全局控制两种控件的行为:
<runtime> <AppContextSwitchOverrides value="Switch.System.Windows.Controls.Text.UseAdornerForTextboxSelectionRendering=false;Switch.System.Windows.Controls.RichTextBox.UseAdornerForSelectionRendering=true"/> </runtime>
这个配置会关闭TextBox的装饰器渲染,同时强制RichTextBox启用装饰器渲染,完全不需要修改XAML代码。
内容的提问来源于stack exchange,提问作者wpf
相关产品推荐
相关产品推荐

