You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在.NET MAUI中实现Label文本背景色(类似选中文本样式)

在.NET MAUI中实现Label文本行背景高亮(类似文本选中效果)

.NET MAUI的原生Label控件没有直接提供这种仅文本行带背景、换行终止、行间带细白线的API,不过可以通过自定义控件+平台渲染器的方式实现,以下是具体方案:


步骤1:创建自定义Label控件

先定义一个继承自Label的自定义控件,添加可绑定属性来控制高亮颜色和行间隙宽度:

using Microsoft.Maui.Controls;

namespace YourAppNamespace.Controls;

public class HighlightLineLabel : Label
{
    // 行高亮背景色
    public static readonly BindableProperty LineHighlightColorProperty =
        BindableProperty.Create(nameof(LineHighlightColor), typeof(Color), typeof(HighlightLineLabel), Colors.LightYellow);

    public Color LineHighlightColor
    {
        get => (Color)GetValue(LineHighlightColorProperty);
        set => SetValue(LineHighlightColorProperty, value);
    }

    // 行间隙宽度(控制行间白线的粗细)
    public static readonly BindableProperty LineGapWidthProperty =
        BindableProperty.Create(nameof(LineGapWidth), typeof(float), typeof(HighlightLineLabel), 2f);

    public float LineGapWidth
    {
        get => (float)GetValue(LineGapWidthProperty);
        set => SetValue(LineGapWidthProperty, value);
    }
}

步骤2:实现Android平台自定义渲染器

在Android项目中,利用LineBackgroundSpan为每行文本绘制带间隙的背景:

using Android.Content;
using Android.Text;
using Android.Text.Style;
using Android.Widget;
using YourAppNamespace.Controls;
using YourAppNamespace.Platforms.Android.Renderers;
using Microsoft.Maui.Controls.Compatibility.Platform.Android;
using Microsoft.Maui.Graphics;

[assembly: ExportRenderer(typeof(HighlightLineLabel), typeof(HighlightLineLabelRenderer))]
namespace YourAppNamespace.Platforms.Android.Renderers;

public class HighlightLineLabelRenderer : LabelRenderer
{
    public HighlightLineLabelRenderer(Context context) : base(context)
    {
    }

    protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
    {
        base.OnElementChanged(e);

        if (Control is TextView textView && Element is HighlightLineLabel highlightLabel)
        {
            var spannableText = new SpannableString(textView.Text);
            var highlightColor = highlightLabel.LineHighlightColor.ToAndroid();
            var lineGap = highlightLabel.LineGapWidth;

            // 为整个文本添加自定义行背景Span
            spannableText.SetSpan(
                new CustomLineBackgroundSpan(highlightColor, lineGap),
                0,
                spannableText.Length(),
                SpanTypes.ExclusiveExclusive);

            textView.TextFormatted = spannableText;
        }
    }

    // 自定义行背景绘制逻辑
    private class CustomLineBackgroundSpan : LineBackgroundSpan
    {
        private readonly Android.Graphics.Color _highlightColor;
        private readonly float _lineGap;

        public CustomLineBackgroundSpan(Android.Graphics.Color highlightColor, float lineGap)
        {
            _highlightColor = highlightColor;
            _lineGap = lineGap;
        }

        public override void DrawBackground(Canvas canvas, Paint paint, int left, int right, int top, int baseline, int bottom, ICharSequence text, int start, int end, int lineNumber)
        {
            var originalColor = paint.Color;
            paint.Color = _highlightColor;

            // 绘制背景时上下留出间隙,形成行间白线
            var drawRect = new Android.Graphics.RectF(left, top + _lineGap/2, right, bottom - _lineGap/2);
            canvas.DrawRect(drawRect, paint);

            paint.Color = originalColor;
        }
    }
}

步骤3:实现iOS平台自定义渲染器

在iOS项目中,通过NSTextStorage和NSLayoutManager计算每行位置,手动绘制带间隙的背景:

using CoreGraphics;
using Foundation;
using UIKit;
using YourAppNamespace.Controls;
using YourAppNamespace.Platforms.iOS.Renderers;
using Microsoft.Maui.Controls.Compatibility.Platform.iOS;
using Microsoft.Maui.Graphics;

[assembly: ExportRenderer(typeof(HighlightLineLabel), typeof(HighlightLineLabelRenderer))]
namespace YourAppNamespace.Platforms.iOS.Renderers;

public class HighlightLineLabelRenderer : LabelRenderer
{
    protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
    {
        base.OnElementChanged(e);

        if (Control is UILabel label && Element is HighlightLineLabel highlightLabel)
        {
            var text = label.Text ?? string.Empty;
            var textStorage = new NSTextStorage(text);
            var layoutManager = new NSLayoutManager();
            var textContainer = new NSTextContainer(label.Bounds.Size)
            {
                LineFragmentPadding = 0,
                MaximumNumberOfLines = (nint)label.Lines,
                LineBreakMode = label.LineBreakMode
            };

            layoutManager.AddTextContainer(textContainer);
            textStorage.AddLayoutManager(layoutManager);

            var highlightColor = highlightLabel.LineHighlightColor.ToUIColor();
            var lineGap = highlightLabel.LineGapWidth;

            // 监听Label的绘制事件,手动绘制行背景
            label.DrawText += (sender, args) =>
            {
                var context = UIGraphics.GetCurrentContext();
                context.SaveState();

                var glyphRange = layoutManager.GlyphRangeForTextContainer(textContainer);
                var currentLineRange = new NSRange(0, 0);

                // 遍历每一行文本,绘制背景
                while (layoutManager.GetLineRangeForGlyphRange(glyphRange, ref currentLineRange))
                {
                    var lineRect = layoutManager.GetLineFragmentUsedRectForGlyphRange(currentLineRange, textContainer);
                    // 调整绘制区域,留出上下间隙
                    var highlightRect = new CGRect(
                        lineRect.Left,
                        lineRect.Top + lineGap/2,
                        lineRect.Width,
                        lineRect.Height - lineGap);

                    highlightColor.SetFill();
                    UIGraphics.RectFill(highlightRect);

                    // 移动到下一行
                    glyphRange = new NSRange(currentLineRange.Location + currentLineRange.Length, glyphRange.Length - currentLineRange.Length);
                }

                context.RestoreState();
            };
        }
    }
}

步骤4:在XAML中使用自定义控件

直接引用自定义控件,配置高亮颜色和行间隙即可:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:controls="clr-namespace:YourAppNamespace.Controls"
             x:Class="YourAppNamespace.MainPage">

    <VerticalStackLayout Padding="20">
        <controls:HighlightLineLabel 
            Text="这是一段测试文本,用于验证行背景高亮效果。当文本自动换行时,每行都会有独立的背景色,行与行之间会显示细白线分隔,完全符合你需要的类似文本选中的视觉效果。"
            LineHighlightColor="#FFF9C4"
            LineGapWidth="2"
            FontSize="16"
            Margin="0 0 0 10"/>
    </VerticalStackLayout>

</ContentPage>

这种方案基于原生平台API实现,性能稳定,支持自动换行、动态文本内容,并且可以通过绑定属性灵活调整样式。

内容的提问来源于stack exchange,提问作者Emilien Rakotonoelina

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 13:22:12