Подтвердить что ты не робот

Максимальное количество строк для Wrap TextBlock

У меня есть TextBlock со следующей настройкой:

TextWrapping="Wrap"

Могу ли я определить максимальное количество строк?

например, рассмотрим следующую строку TextBlock.Text:

This is a very good horse under the blackboard!!

В настоящее время он выглядит следующим образом:

This is a very 
good horse under 
the blackboard!!

Мне нужно это, чтобы стать чем-то вроде:

This is a very 
good horse ...

любое решение?

4b9b3361

Ответ 1

Если у вас есть определенный LineHeight, вы можете вычислить максимальную высоту для TextBlock.

Пример:

Текстовый блок с максимальными тремя строками

<TextBlock 
  Width="300"
  TextWrapping="Wrap" 
  TextTrimming="WordEllipsis" 
  FontSize="24" 
  LineStackingStrategy="BlockLineHeight"
  LineHeight="28"
  MaxHeight="84">YOUR TEXT</TextBlock>

Это все, что вам нужно, чтобы ваше требование работало.

Как это сделать динамически?

Просто создайте новый элемент управления в С#/VB.NET, который расширяет TextBlock и присваивает ему новый DependencyProperty int MaxLines.
Затем переопределите метод OnApplyTemplate() и установите MaxHeight на основе LineHeight * MaxLines.

Это просто базовое объяснение того, как вы могли бы решить эту проблему!

Обновление (для UWP)

В приложениях UWP вам это не нужно и может использовать свойство TextBlock MaxLines (см. MSDN)

Ответ 2

вам нужно установить TextTrimming="WordEllipsis" в TextBlock

Ответ 3

Если у вас установлены все Height, TextWrapping и TextTrimming, они будут вести себя точно так, как вы хотите:

<TextBlock Height="60" FontSize="22" FontWeight="Thin"
    TextWrapping="Wrap" TextTrimming="CharacterEllipsis">

Вышеприведенный код завершает до двух строк, затем используйте CharacterEllipsis после этой точки.

Ответ 4

На основе tobi.at и gt answer я создал это поведение MaxLines. Реально это не зависит от установки свойства LineHeight путем вычисления высоты строки из шрифта. Вам еще нужно установить TextWrapping и TextTrimming, чтобы он TextBox отображался так, как вам хотелось бы.

<TextBlock behaviours:NumLinesBehaviour.MaxLines="3" TextWrapping="Wrap" TextTrimming="CharacterEllipsis" Text="Some text here"/>

Здесь также существует поведение MinLines, которое может быть различным или установлено на тот же номер, что и поведение MaxLines для установки количества строк.

public class NumLinesBehaviour : Behavior<TextBlock>
{
    TextBlock textBlock => AssociatedObject;

    protected override void OnAttached()
    {
        base.OnAttached();
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
    }

    public static readonly DependencyProperty MaxLinesProperty =
        DependencyProperty.RegisterAttached(
            "MaxLines",
            typeof(int),
            typeof(NumLinesBehaviour),
            new PropertyMetadata(default(int), OnMaxLinesPropertyChangedCallback));

    public static void SetMaxLines(DependencyObject element, int value)
    {
        element.SetValue(MaxLinesProperty, value);
    }

    public static int GetMaxLines(DependencyObject element)
    {
        return (int)element.GetValue(MaxLinesProperty);
    }

    private static void OnMaxLinesPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        TextBlock element = d as TextBlock;
        element.MaxHeight = getLineHeight(element) * GetMaxLines(element);
    }

    public static readonly DependencyProperty MinLinesProperty =
        DependencyProperty.RegisterAttached(
            "MinLines",
            typeof(int),
            typeof(NumLinesBehaviour),
            new PropertyMetadata(default(int), OnMinLinesPropertyChangedCallback));

    public static void SetMinLines(DependencyObject element, int value)
    {
        element.SetValue(MinLinesProperty, value);
    }

    public static int GetMinLines(DependencyObject element)
    {
        return (int)element.GetValue(MinLinesProperty);
    }

    private static void OnMinLinesPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        TextBlock element = d as TextBlock;
        element.MinHeight = getLineHeight(element) * GetMinLines(element);
    }

    private static double getLineHeight(TextBlock textBlock)
    {
        double lineHeight = textBlock.LineHeight;
        if (double.IsNaN(lineHeight))
            lineHeight = Math.Ceiling(textBlock.FontSize * textBlock.FontFamily.LineSpacing);
        return lineHeight;
    }
}

Ответ 5

На основе @artistandsocial ответ я создал прикрепленное свойство, чтобы установить максимальное количество строк программным образом (вместо того, чтобы перегружать TextBlock, который не рекомендуется в WPF).

public class LineHeightBehavior
{
    public static readonly DependencyProperty MaxLinesProperty =
        DependencyProperty.RegisterAttached(
            "MaxLines",
            typeof(int),
            typeof(LineHeightBehavior),
            new PropertyMetadata(default(int), OnMaxLinesPropertyChangedCallback));

    public static void SetMaxLines(DependencyObject element, int value)
    {
        element.SetValue(MaxLinesProperty, value);
    }

    public static int GetMaxLines(DependencyObject element)
    {
        return (int)element.GetValue(MaxLinesProperty);
    }

    private static void OnMaxLinesPropertyChangedCallback(
        DependencyObject d,
        DependencyPropertyChangedEventArgs e)
    {
        var element = d as TextBlock;
        if (element != null)
        {
            element.MaxHeight = element.LineHeight * GetMaxLines(element);
        }
    }
}

По умолчанию для параметра LineHeight установлено значение double.NaN, поэтому это значение должно быть сначала задано вручную.

Вложенное свойство MaxLines и другие соответствующие свойства затем могут быть установлены в Style:

<Style TargetType="{x:Type TextBlock}"
       BasedOn="{StaticResource {x:Type TextBlock}}">
    <Setter Property="TextTrimming"
            Value="CharacterEllipsis" />
    <Setter Property="TextWrapping"
            Value="Wrap" />
    <Setter Property="LineHeight"
            Value="16" />
    <Setter Property="LineStackingStrategy"
            Value="BlockLineHeight" />
    <Setter Property="behaviors:LineHeightBehavior.MaxLines"
            Value="2" />
</Style>

Ответ 6

Для любого, кто разрабатывает приложения UWP или WinRT, TextBlock имеет свойство MaxLines, которое вы можете установить.

Ответ 7

Я сомневаюсь, что это настраивается. Обертка основана на ряде факторов, таких как размер шрифта/кернинг, доступная ширина текстового блока (horizontalalignment = stretch может иметь большое значение), тип родительской панели (scrollviewer/stackpanel/grid ) и т.д.

Если вы хотите, чтобы текст переместился в следующую строку явно, вы должны использовать блоки "Запустить", а затем использовать обертку эллипсов типа для этого блока выполнения.