简体   繁体   English

如何使 wpf 文本块自动调整大小

[英]how to make wpf textblock autosize

i have a textblock where i dynamically add string.. even if i add string width and update the textblock the textblock is not showing appropriate width, still some text are cut..我有一个文本块,我在其中动态添加字符串。

how to measure width that has to be displayed in textblock?如何测量必须在文本块中显示的宽度? and how to make it autosize?以及如何使其自动调整大小?

You can get the size of a text using these solutions :您可以使用以下解决方案获取文本的大小:

Solution 1解决方案1

You could FormattedText to measure the size of text, here is an example:您可以使用 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);

Solution 2解决方案2

Use the Graphics class (found here ):使用 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);

Here you are !你来了!

Textblocks that have no height or width specified will expand automatically until they fill their container.没有指定高度或宽度的文本块将自动扩展,直到它们填满它们的容器。 So try that.所以试试吧。

Here's a class i've written that does this.这是我写的一个类,它可以做到这一点。 It only AutoShrinks but you can add the functionality you need.它仅自动收缩,但您可以添加所需的功能。 It uses the parent bounds OR MaxHeight / MaxWidth if they are set.如果已设置,则使用父边界 OR 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);
        }
    }
}

Here is a different way of solving this issue.这是解决此问题的另一种方法。

Set yourTextBlock.Width = double.NaN and same with Height .设置yourTextBlock.Width = double.NaN并与Height相同。

By default, elements have an HorizontalAligment and VerticalAligment properties that are set to Stretch , so they will adapt to their parent.默认情况下,元素具有设置为StretchHorizontalAligmentVerticalAligment属性,因此它们将适应其父级。

But if you set these to Center , the element will keep its natural size, so you can test this (or setting properties using code instead of XAML):但是,如果您将这些设置为Center ,元素将保持其自然大小,因此您可以对此进行测试(或使用代码而不是 XAML 设置属性):

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

It worked in my case, maybe not in every case.它适用于我的情况,也许不是在所有情况下。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM