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

WPF技术问询:如何获取开启TextTrimming的TextBlock的隐藏文本范围

WPF TextBlock开启文本裁剪后获取被裁剪内容或裁剪索引的方法

WPF的TextBlock控件在设置TextTrimming为WordEllipsis或CharacterEllipsis时,没有内置属性直接返回被裁剪的文本或裁剪位置,需要通过计算文本的显示宽度来实现。

核心思路

利用FormattedText类模拟TextBlock的文本渲染,计算每个字符(或单词)的显示宽度,结合控件的可用宽度(扣除内边距)和省略号的宽度,逐步判断文本在哪一处开始超过显示范围,从而确定裁剪索引。

实现代码

下面是一个工具方法,可直接用于获取裁剪索引,进而得到被裁剪的文本:

using System.Globalization;
using System.Windows;
using System.Windows.Media;

public static class TextBlockHelper
{
    public static int GetTextTrimmingIndex(TextBlock textBlock)
    {
        if (textBlock == null || string.IsNullOrEmpty(textBlock.Text))
            return -1;

        // 创建与TextBlock格式一致的FormattedText对象
        var baseFormattedText = new FormattedText(
            textBlock.Text,
            CultureInfo.CurrentCulture,
            textBlock.FlowDirection,
            new Typeface(textBlock.FontFamily, textBlock.FontStyle, textBlock.FontWeight, textBlock.FontStretch),
            textBlock.FontSize,
            textBlock.Foreground);

        // 计算省略号的显示宽度
        var ellipsisWidth = new FormattedText(
            "...",
            CultureInfo.CurrentCulture,
            textBlock.FlowDirection,
            new Typeface(textBlock.FontFamily, textBlock.FontStyle, textBlock.FontWeight, textBlock.FontStretch),
            textBlock.FontSize,
            textBlock.Foreground).Width;

        // 计算控件的可用显示宽度
        double availableWidth = textBlock.ActualWidth - textBlock.Padding.Left - textBlock.Padding.Right;
        double currentTotalWidth = 0;
        int trimIndex = textBlock.Text.Length;

        if (textBlock.TextTrimming == TextTrimming.WordEllipsis)
        {
            // 按单词分割处理,匹配WordEllipsis的裁剪逻辑
            string[] words = textBlock.Text.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
            int currentWordPos = 0;
            foreach (var word in words)
            {
                // 获取当前单词的起始索引
                int wordStartIndex = textBlock.Text.IndexOf(word, currentWordPos);
                // 计算当前单词的宽度
                double wordWidth = baseFormattedText.BuildHighlightGeometry(new Point(currentTotalWidth, 0), wordStartIndex, word.Length).Bounds.Width;
                
                // 判断加上当前单词和省略号后是否超出可用宽度
                if (currentTotalWidth + wordWidth + ellipsisWidth > availableWidth)
                {
                    trimIndex = wordStartIndex;
                    break;
                }

                // 累加单词宽度和后续空格的宽度
                currentTotalWidth += wordWidth;
                if (wordStartIndex + word.Length < textBlock.Text.Length)
                {
                    double spaceWidth = baseFormattedText.BuildHighlightGeometry(new Point(currentTotalWidth, 0), wordStartIndex + word.Length, 1).Bounds.Width;
                    currentTotalWidth += spaceWidth;
                }
                currentWordPos = wordStartIndex + word.Length + 1;
            }
        }
        else if (textBlock.TextTrimming == TextTrimming.CharacterEllipsis)
        {
            // 按单个字符处理,匹配CharacterEllipsis的裁剪逻辑
            for (int i = 0; i < textBlock.Text.Length; i++)
            {
                double charWidth = baseFormattedText.BuildHighlightGeometry(new Point(currentTotalWidth, 0), i, 1).Bounds.Width;
                if (currentTotalWidth + charWidth + ellipsisWidth > availableWidth)
                {
                    trimIndex = i;
                    break;
                }
                currentTotalWidth += charWidth;
            }
        }

        return trimIndex;
    }
}

使用示例

在TextBlock加载完成后调用该方法,即可获取裁剪索引和被裁剪文本:

// 假设xaml中定义的TextBlock名为text1
private void TextBlock_Loaded(object sender, RoutedEventArgs e)
{
    int trimIndex = TextBlockHelper.GetTextTrimmingIndex(text1);
    if (trimIndex != -1 && trimIndex < text1.Text.Length)
    {
        string trimmedContent = text1.Text.Substring(trimIndex);
        // 示例中trimmedContent将是"LONG TEXT",trimIndex为10
    }
}

注意事项

  • 必须在TextBlock加载完成后调用(比如Loaded事件中),否则ActualWidth可能未正确计算。
  • 该方法会模拟TextBlock的文本渲染逻辑,计算结果与实际显示的裁剪位置一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 06:01:34