Maximum number of lines for a Wrap TextBlock

前端 未结 7 1555
心在旅途
心在旅途 2021-02-05 02:40

I have a TextBlock with the following setting:

TextWrapping=\"Wrap\"

Can I determine the maximum number of lines?

for exam

相关标签:
7条回答
  • 2021-02-05 03:03

    For anybody developing UWP or WinRT Applications, TextBlock has a MaxLines property you can set.

    0 讨论(0)
  • 2021-02-05 03:05

    Based tobi.at's and gt's answer I have created this MaxLines behaviour. Crucially it doesn't depend upon setting the LineHeight property by calculating the line height from the font. You still need to set TextWrapping and TextTrimming for it the TextBox to be render as you would like.

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

    There in also a MinLines behaviour which can be different or set to the same number as the MaxLines behaviour to set the number of lines.

    public class NumLinesBehaviour : Behavior<TextBlock>
    {
        TextBlock textBlock => AssociatedObject;
    
        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;
        }
    }
    
    0 讨论(0)
  • 2021-02-05 03:06

    you need TextTrimming="WordEllipsis" setting in your TextBlock

    0 讨论(0)
  • 2021-02-05 03:08

    If you have Height, TextWrapping, and TextTrimming all set, it will behave exactly like you want:

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

    The above code will wrap up to two lines, then use CharacterEllipsis beyond that point.

    0 讨论(0)
  • 2021-02-05 03:12

    Based on @artistandsocial's answer, I created a attached property to set the maximum number of lines programatically (rather than having to overload TextBlock which is discouraged in 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);
            }
        }
    }
    

    By default, the LineHeight is set to double.NaN, so this value must first be set manually.

    The attached property MaxLines and other relevant properties can then be set in a 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 讨论(0)
  • 2021-02-05 03:12

    I doubt that is configurable, Wrapping is based on a number of factors such as font-size/kerning, available width of the textblock (horizontalalignment=stretch can make a big difference), parent's panel type (scrollviewer/stackpanel/grid) etc.

    If you want the text to flow to the next line explicitly you should use "Run" blocks instead and then use wrapping of type ellipses for that run block.

    0 讨论(0)
提交回复
热议问题