簡體   English   中英

如何使 wpf 文本塊自動調整大小

[英]how to make wpf textblock autosize

我有一個文本塊,我在其中動態添加字符串。

如何測量必須在文本塊中顯示的寬度? 以及如何使其自動調整大小?

您可以使用以下解決方案獲取文本的大小:

解決方案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);

你來了!

沒有指定高度或寬度的文本塊將自動擴展,直到它們填滿它們的容器。 所以試試吧。

這是我寫的一個類,它可以做到這一點。 它僅自動收縮,但您可以添加所需的功能。 如果已設置,則使用父邊界 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);
        }
    }
}

這是解決此問題的另一種方法。

設置yourTextBlock.Width = double.NaN並與Height相同。

默認情況下,元素具有設置為StretchHorizontalAligmentVerticalAligment屬性,因此它們將適應其父級。

但是,如果您將這些設置為Center ,元素將保持其自然大小,因此您可以對此進行測試(或使用代碼而不是 XAML 設置屬性):

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

它適用於我的情況,也許不是在所有情況下。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM