WPF TextBlock получает обрезанный текст

Как получить обрезанный текст TextBlock, когда TextTrimming установлен на «WordEllipsis» или «CharacterEllipsis»?

Например, этот код:

<TextBlock Name = "text1" FontSize = "12" Width = "94" Text = "THIS IS A LONG TEXT" TextTrimming = "WordEllipsis"/>

отображает: THIS IS A...

Как получить обрезанный текст: LONG TEXT или индекс обрезания строки: 10

Значение свойства Text не меняется. Только текстовое представление TextBlock изменяется в том смысле, что оно заменяет отсеченный визуализированный текст многоточием.

BionicCode. 11.07.2023 18:16

Я знаю, что значение Text не меняется. Может быть, есть обходной путь, чтобы получить обрезанный текст?

ErinQvnm 12.07.2023 02:14

Тогда я неправильно вас понял. Вы должны измерить текст.

BionicCode. 12.07.2023 14:54
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
53
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вам нужно вручную измерить текст (со всеми примененными стилями шрифта).

Общее решение, которое также работает с TextTrimming, установленным на TextTrimming.WordEllipsis, должно итеративно находить позицию последнего символа.
Поскольку нет связанного API, мы должны сделать это сложным путем и итеративно тестировать, пока мы больше не получим исключение. Другого пути нет (требование знать точную текстовую часть, которая обрезает доступную текстовую область, обычно не имеет смысла).

Однако, когда для TextTrimming установлено значение TextTrimming.CharacterEllipsis, исключений не будет. Это связано с тем, что обрезка на основе символов дает предсказуемый результат, в отличие от обрезки слов, когда длина слов является случайной (поскольку слова неизвестны). Это означает, что случай на основе TextTrimming.CharacterEllipsis более удобен для производительности.

Окончательное решение, поддерживающее TextTrimming.WordEllipsis и TextTrimming.CharacterEllipsis, может выглядеть следующим образом:

public string GetHiddenRangeOfTrimmedText(TextBlock textBlock)
{
  var typeFace = new Typeface(textBlock.FontFamily, textBlock.FontStyle, textBlock.FontWeight, textBlock.FontStretch);
  var numberSubstitution = new NumberSubstitution(NumberSubstitution.GetCultureSource(textBlock), CultureInfo.CurrentUICulture, NumberSubstitution.GetSubstitution(textBlock));

  // Define ellipsis using four ellipsis characters (instead of three).
  // This is because ellipsis is rendered using three visible and one hidden ellipsis characters.
  var formattedEllipsisText = new FormattedText(
    "....",
    CultureInfo.CurrentUICulture,
    textBlock.FlowDirection,
    typeFace,
    textBlock.FontSize,
    textBlock.Foreground,
    numberSubstitution,
    VisualTreeHelper.GetDpi(textBlock).PixelsPerDip);
  double clippingOffset = textBlock.ActualWidth - formattedEllipsisText.Width - textBlock.Padding.Right;
  var clippingPosition = new Point(clippingOffset, 0);

  TextPointer clippingPositionTextPointer = null;
  do
  {
    try
    {
      clippingPositionTextPointer = textBlock.GetPositionFromPoint(clippingPosition, true);
    }
    catch (ArgumentException)
    {
      if (clippingPosition.X == 0)
      {
        return string.Empty;
      }

      clippingPosition.Offset(-1, 0);
    }

    if (clippingPositionTextPointer is not null)
    {
      break;
    }
  } while (clippingPosition.X >= 0);

  var clippedTextRange = new TextRange(clippingPositionTextPointer, textBlock.ContentEnd);
  string clippedText = clippedTextRange.Text;
      
  return clippedText;
}

Другие вопросы по теме