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?
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!
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.
Vous devez TextTrimming="WordEllipsis" définir dans votre TextBlock
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;
}
}
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>
Pour quiconque développe des Applications UWP ou WinRT, TextBlock a un MaxLines propriété que vous pouvez définir.
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.