如何使WPF TextBlock自适应大小

6

我有一个文本块,我动态添加字符串。即使我添加了字符串的宽度并更新了文本块,文本块仍然没有显示适当的宽度,仍然有一些文字被截断。

如何测量要在文本块中显示的宽度?如何使其自动调整大小?


这个链接应该能解决你的问题。 - nam
6个回答

7

以下是关于如何获取文本大小的解决方案:

解决方案1

您可以使用FormattedText来测量文本的大小,以下是一个示例:

String text = "Here is my text";
Typeface myTypeface = new Typeface("Helvetica");
FormattedText ft = new FormattedText(text, CultureInfo.CurrentCulture, 
        FlowDirection.LeftToRight, myTypeface, 16, Brushes.Red);

Size textSize = new Size(ft.Width, ft.Height);

解决方案2

使用Graphics类(在这里找到):

System.Drawing.Font font = new System.Drawing.Font("Calibri", 12, FontStyle.Bold);
Bitmap bitmap = new Bitmap(1, 1);
Graphics g = Graphics.FromImage(bitmap);
SizeF measureString = g.MeasureString(text, font);

这里是你需要的内容!


6

没有指定高度或宽度的文本块将自动扩展,直到填满其容器。因此,请尝试这样做。


1
这是正确的,没有必要依赖于System.Drawing。 - TimothyP

3

我写了一个类来实现这个功能。它只能自动缩小,但你可以添加你需要的功能。它使用父级边界或者如果设置了MaxHeight/MaxWidth,则使用它们。

public class TextBlockAutoShrink : TextBlock
{
    // private Viewbox _viewBox;
    private double _defaultMargin = 6;
    private Typeface _typeface;

    static TextBlockAutoShrink()
    {
        TextBlock.TextProperty.OverrideMetadata(typeof(TextBlockAutoShrink), new FrameworkPropertyMetadata(new PropertyChangedCallback(TextPropertyChanged)));
    }

    public TextBlockAutoShrink() : base() 
    {
        _typeface = new Typeface(this.FontFamily, this.FontStyle, this.FontWeight, this.FontStretch, this.FontFamily);
        base.DataContextChanged += new DependencyPropertyChangedEventHandler(TextBlockAutoShrink_DataContextChanged);
    }

    private static void TextPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
    {
        var t = sender as TextBlockAutoShrink;
        if (t != null)
        {
            t.FitSize();
        }
    }

    void TextBlockAutoShrink_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
        FitSize();
    }

    protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
    {
        FitSize();

        base.OnRenderSizeChanged(sizeInfo);
    }

    private void FitSize()
    {
        FrameworkElement parent = this.Parent as FrameworkElement;
        if (parent != null)
        {
            var targetWidthSize = this.FontSize;
            var targetHeightSize = this.FontSize;

            var maxWidth = double.IsInfinity(this.MaxWidth) ? parent.ActualWidth : this.MaxWidth;
            var maxHeight = double.IsInfinity(this.MaxHeight) ? parent.ActualHeight : this.MaxHeight;

            if (this.ActualWidth > maxWidth)
            {
                targetWidthSize = (double)(this.FontSize * (maxWidth / (this.ActualWidth + _defaultMargin)));
            }

            if (this.ActualHeight > maxHeight)
            {
                var ratio = maxHeight / (this.ActualHeight);

                // Normalize due to Height miscalculation. We do it step by step repeatedly until the requested height is reached. Once the fontsize is changed, this event is re-raised
                // And the ActualHeight is lowered a bit more until it doesnt enter the enclosing If block.
                ratio = (1 - ratio > 0.04) ? Math.Sqrt(ratio) : ratio;

                targetHeightSize = (double)(this.FontSize *  ratio);
            }

            this.FontSize = Math.Min(targetWidthSize, targetHeightSize);
        }
    }
}

3

这里提供一种解决该问题的不同方法。

设置yourTextBlock.Width = double.NaN,同时设置Height也是同样的方式。


1

默认情况下,元素具有HorizontalAligmentVerticalAligment属性,其设置为Stretch,因此它们将适应其父级。

但是,如果您将这些设置为Center,则元素将保持其自然大小,因此您可以测试此功能(或者使用代码而不是XAML设置属性):

<TextBlock Text="This is my text"
      HorizontalAlignment="Center"
      VerticalAlignment="Center"
/>

它在我的情况下起作用了,可能不是每种情况都适用。


0

MyTextBlock.TextWrapping = TextWrapping.Wrap;

我的文本块.TextWrapping = TextWrapping.Wrap;


你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心中找到有关如何编写良好答案的更多信息。 - Community

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接