Wrap TextBlock的最大行数

时间:2012-11-30 01:44:39

标签: xaml windows-8 microsoft-metro 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 ...

任何解决方案?

7 个答案:

答案 0 :(得分:46)

更新(针对UWP)

在UWP应用中,您不需要此功能,可以使用TextBlock属性MaxLines(请参阅MSDN


原始答案:

如果您有特定的LineHeight,则可以计算TextBlock的最大高度

实施例

TextBlock,最多3行

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

这就是满足您的要求所需的一切。

如何动态地执行此操作?

只需在C#/ VB.NET中创建一个扩展TextBlock的新控件,并为其提供一个新的DependencyProperty int MaxLines
然后覆盖OnApplyTemplate()方法,并根据MaxHeight * LineHeight设置MaxLines

这只是关于如何解决这个问题的基本解释!

答案 1 :(得分:3)

如果您设置了HeightTextWrappingTextTrimming,则其行为将完全符合您的要求:

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

上面的代码最多包含两行,然后在此之后使用CharacterEllipsis

答案 2 :(得分:2)

您需要在TextTrimming="WordEllipsis"

中设置TextBlock

答案 3 :(得分:2)

根据tobi.at和gt的回答,我创建了这个MaxLines行为。至关重要的是,它不依赖于通过从字体计算行高来设置LineHeight属性。您仍然需要为TextWrappingTextTrimming设置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;
    }
}

答案 4 :(得分:0)

基于@ 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>

答案 5 :(得分:0)

对于开发UWP或WinRT应用程序的任何人,TextBlock都有MaxLines属性,您可以设置。

答案 6 :(得分:-4)

我怀疑这是可配置的,Wrapping是基于许多因素,例如font-size / kerning,textblock的可用宽度(horizo​​ntalalignment = stretch可以产生很大的不同),parent的面板类型(scrollviewer / stackpanel / grid) )等等。

如果您希望文本明确地流向下一行,则应使用“运行”块,然后使用类型省略号包装该运行块。