Nombre maximal de lignes pour un Wrap TextBlock

J'ai un TextBlock avec le paramètre suivant:

TextWrapping="Wrap"

Puis-je déterminer le nombre maximum de lignes?

Par exemple, considérons la chaîne suivante TextBlock.Text:

This is a very good horse under the blackboard!!

Il a actuellement été montré comme ceci:

This is a very 
good horse under 
the blackboard!!

J'ai besoin de cela pour devenir quelque chose comme:

This is a very 
good horse ...

Une solution?

23
demandé sur Mayank 2012-11-30 05:44:39

7 réponses

Mise à jour (pour UWP)

Dans les applications UWP, vous n'en avez pas besoin et pouvez utiliser la propriété TextBlock MaxLines (Voir MSDN )


Réponse Originale:

Si vous avez un LineHeight spécifique, vous pouvez calculer la hauteur maximale pour le bloc TextBlock.

Exemple:

TextBlock avec un maximum de 3 lignes

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

C'est tout ce dont vous avez besoin pour que vos besoins fonctionnent.

Comment faire cela dynamiquement?

Juste créer un nouveau contrôle dans C# / VB. NET qui étend TextBlock et lui donner un nouveau DependencyProperty int MaxLines .
ensuite, remplacez la méthode OnApplyTemplate() et définissez la MaxHeight en fonction de la LineHeight * MaxLines.

C'est juste une explication de base sur la façon dont vous pourriez résoudre ce problème!

43
répondu tobi.at 2018-09-18 12:50:34

Si vous avez Height, TextWrapping, et TextTrimming tous ensemble, il va se comporter exactement comme vous le souhaitez:

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

Le code ci-dessus va envelopper jusqu'à deux lignes, puis utiliser CharacterEllipsis au-delà de ce point.

3
répondu Greg Lary 2014-10-21 19:38:51

Vous devez TextTrimming="WordEllipsis" définir dans votre TextBlock

2
répondu Mayank 2012-11-30 02:09:45

Basé tobi.at réponse de s et gt j'ai créé ce comportement MaxLines. Fondamentalement, cela ne dépend pas de la définition de la propriété LineHeight en calculant la hauteur de la ligne à partir de la police. Vous devez toujours définir TextWrapping et TextTrimming pour que TextBox soit rendu comme vous le souhaitez.

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

Il y a aussi un comportement MinLines qui peut être différent ou défini sur le même nombre que le comportement MaxLines pour définir le nombre de lignes.

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;
    }
}
1
répondu Itzalive 2017-03-31 11:43:07

Basé sur la réponse de @artistandsocial, j'ai créé une propriété attachée pour définir le nombre maximum de lignes par programme (plutôt que d'avoir à surcharger TextBlock ce qui est déconseillé dans 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);
        }
    }
}

Par défaut, le {[3] } est défini sur double.NaN, donc cette valeur doit d'abord être définie manuellement.

La propriété attachée MaxLines et d'autres propriétés peuvent être définies dans un 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>
0
répondu g t 2016-04-15 12:45:55

Pour quiconque développe des Applications UWP ou WinRT, TextBlock a un MaxLines propriété que vous pouvez définir.

0
répondu Francisco Aguilera 2017-03-01 22:00:26

Je doute que ce soit configurable, L'habillage est basé sur un certain nombre de facteurs tels que la taille de la police/crénage, la largeur disponible du textblock (horizontalalignment=stretch peut faire une grande différence), le type de panneau parent (scrollviewer/stackpanel/grid) etc.

Si vous voulez que le texte passe explicitement à la ligne suivante, vous devez utiliser des blocs "exécuter" à la place, puis utiliser l'habillage des ellipses de type pour ce bloc d'exécution.

-3
répondu Rohit Sharma 2012-11-30 02:12:22