WinUI 3中如何为部分文本添加背景色并保留自动换行?
WinUI 3 实现带背景色的内联高亮文本(保持自动换行)
方案1:使用RichTextBlock(推荐,内置支持)
WinUI 3的RichTextBlock中的Span元素原生支持Background属性,且能完全保留文本的自然内联换行逻辑,完美匹配你的需求。无需使用会破坏排版的InlineUIContainer,直接用Paragraph包裹普通Run和带背景的Span即可:
<RichTextBlock Style="{StaticResource DefaultTextBlockStyle}" FontWeight="{Binding FontWeight}" LineHeight="30" Visibility="{Binding ItemVisibility}"> <Paragraph> <Run Text="{Binding DisplayLabel}" Foreground="{Binding LabelForeground}"/> <Span Background="{Binding HighlightBackgroundBrush}" Foreground="{Binding ForegroundBrush}" FontWeight="{Binding ValueFontWeight}"> <Run Text="{Binding Value}"/> </Span> </Paragraph> </RichTextBlock>
该方案下,高亮文本的背景会跟随文本自动换行,完全适配每行的宽度,不会出现排版断裂问题。
方案2:自定义TextBlock控件(适配原有TextBlock场景)
如果不想替换现有TextBlock结构,可以自定义一个继承自TextBlock的控件,通过重写OnRender方法手动绘制高亮文本的背景。以下是简化实现:
自定义控件代码(C#)
public class HighlightTextBlock : TextBlock { public static readonly DependencyProperty HighlightTextProperty = DependencyProperty.Register(nameof(HighlightText), typeof(string), typeof(HighlightTextBlock), new PropertyMetadata(string.Empty, OnTextChanged)); public static readonly DependencyProperty HighlightBackgroundProperty = DependencyProperty.Register(nameof(HighlightBackground), typeof(Brush), typeof(HighlightTextBlock), new PropertyMetadata(null, OnTextChanged)); public string HighlightText { get => (string)GetValue(HighlightTextProperty); set => SetValue(HighlightTextProperty, value); } public Brush HighlightBackground { get => (Brush)GetValue(HighlightBackgroundProperty); set => SetValue(HighlightBackgroundProperty, value); } private static void OnTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { ((HighlightTextBlock)d).InvalidateVisual(); } protected override void OnRender(DrawingContext dc) { base.OnRender(dc); if (string.IsNullOrEmpty(HighlightText) || HighlightBackground == null) return; var textLayout = new TextLayout(Text, FontFamily, FontSize, FontStyle, FontWeight, FontStretch, TextWrapping, MaxWidth); var highlightRuns = textLayout.FindRuns(HighlightText); foreach (var run in highlightRuns) { foreach (var line in run.Lines) { var lineBounds = line.LayoutBounds; dc.DrawRectangle(HighlightBackground, null, new Rect(lineBounds.X, lineBounds.Y, lineBounds.Width, lineBounds.Height)); } } } }
XAML使用示例
<local:HighlightTextBlock Style="{StaticResource DefaultTextBlockStyle}" FontWeight="{Binding FontWeight}" LineHeight="30" Visibility="{Binding ItemVisibility}" Text="{Binding DisplayLabel}{Binding Value}" HighlightText="{Binding Value}" HighlightBackground="{Binding HighlightBackgroundBrush}" Foreground="{Binding LabelForeground}"> </local:HighlightTextBlock>
这个方案可以直接替换原有TextBlock,保留原有布局逻辑,同时实现高亮背景。你可以根据实际需求完善文本匹配和绘制的细节。
内容的提问来源于stack exchange,提问作者Bevara Satyasairam
相关产品推荐
相关产品推荐

