web-dev-qa-db-ja.com

Wrap 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 ...

解決策はありますか?

26
MBZ

更新(UWP用)

UWPアプリではこれは必要なく、TextBlockプロパティMaxLinesを使用できます( [〜#〜] msdn [〜#〜] を参照)


元の回答:

特定のLineHeightがある場合、TextBlockの最大高さを計算できます。

例:

最大3行のTextBlock

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

これが要件を機能させるために必要なすべてです。

これを動的に行う方法は?

TextBlockを拡張するC#/ VB.NETで新しいコントロールを作成し、それに新しいDependencyPropertyint MaxLinesを与えます。
次に、OnApplyTemplate()メソッドをオーバーライドし、MaxHeight * LineHeightに基づいてMaxLinesを設定します。

これは、この問題を解決する方法についての基本的な説明にすぎません。

46
tobi.at

HeightTextWrapping、およびTextTrimmingがすべて設定されている場合は、期待どおりに動作します。

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

上記のコードは最大2行まで折り返し、そのポイントを超えてCharacterEllipsisを使用します。

3
Greg Lary

Tobi.atとgtの答えに基づいて、私はこのMaxLines動作を作成しました。重要なのは、フォントから行の高さを計算することによるLineHeightプロパティの設定に依存しないことです。 TextWrappingを希望どおりにレンダリングするには、TextTrimmingTextBoxを設定する必要があります。

<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;
    }
}
2
Itzalive

TextBlockTextTrimming="WordEllipsis"設定が必要です

2
Mayank

UWPまたはWinRTアプリケーションを開発している人のために、TextBlockには MaxLines プロパティを設定できます。

0

@artistandsocialの回答に基づいて、プログラムで行の最大数を設定する添付プロパティを作成しました(WPFでは推奨されないTextBlockをオーバーロードする必要はありません)。

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);
        }
    }
}

デフォルトでは、LineHeightdouble.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>
0
g t