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

C# 如何使wpf文本块自动调整大小,c#,wpf,C#,Wpf,我有一个文本块,动态添加字符串。。 即使我添加了字符串宽度并更新了textblock,但textblock没有显示适当的宽度,仍然会剪切一些文本 如何测量必须在textblock中显示的宽度? 如何使其自动调整大小?没有指定高度或宽度的文本块将自动展开,直到它们 装满他们的容器。所以试试看。您可以使用以下解决方案获得文本的大小: 解决方案1 您可以格式化文本来测量文本的大小,以下是一个示例: String text = "Here is my text"; Typeface myTypeface

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

如何测量必须在textblock中显示的宽度?
如何使其自动调整大小?

没有指定高度或宽度的文本块将自动展开,直到它们
装满他们的容器。所以试试看。

您可以使用以下解决方案获得文本的大小:

解决方案1 您可以格式化文本来测量文本的大小,以下是一个示例:

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 使用图形类(找到):


给你

这里有一种不同的方法来解决这个问题


设置
yourTextBlock.Width=double.NaN
Height

这是我写的一个类。它只会自动收缩,但您可以添加所需的功能。它使用父边界或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);
        }
    }
}

默认情况下,元素的
水平对齐
垂直照明
属性设置为
拉伸
,因此它们将适应其父元素

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



它在我的情况下有效,可能不是在所有情况下都有效。

这是正确的,不需要依赖于系统。绘制链接应该为您完成这项工作。
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);
        }
    }
}
<TextBlock Text="This is my text"
      HorizontalAlignment="Center"
      VerticalAlignment="Center"
/>