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.