WPF 测量Text的宽度 根据TextBox宽度自动适应字体大小

发布时间 2023-09-08 09:23:46作者: 多见多闻

根据TextBox的宽度自动适应字体大小,特此记录下

查了一下.net API发现有个FormattedText Class,可以使用这个类类测量text的width,如下:

    private FormattedText MeasureTextWidth(double fontSize)
    {
            
        FormattedText formattedText = new      
               FormattedText(this.Text,ultureInfo.CurrentCulture,
               FlowDirection.LeftToRight,
               new Typeface(this.FontFamily, this.FontStyle, 
               this.FontWeight, this.FontStretch),
               fontSize,this.Foreground, DpiUtil.GetPixelsPerDip);
            
 
        return formattedText;
 
    }

 之后使用控件本身的FontSize的宽度与TextBox的宽度比较,每次比较减去space,通过二分法提高效率,如下:

double space = 1;        
private double CalculateMaxWidthFontSize()
        {
            // this is the width of the Text Box.
            var boxWidth = this.Width;
 
            double endSize = FontSizeViewModel;
            if (double.IsNaN(boxWidth))
            {
                return endSize;
            }
            if (MeasureText(endSize).WidthIncludingTrailingWhitespace < boxWidth)
            {
                return endSize;
            }
            double startSize = 0;
            while (endSize > 0)
            {
                double middleSize = (endSize + startSize) / 2;
                if (MeasureText(middleSize).WidthIncludingTrailingWhitespace < boxWidth &&
                    MeasureText(middleSize + space).WidthIncludingTrailingWhitespace > boxWidth)
                {
                    return middleSize;
                }
                else if (MeasureText(middleSize).WidthIncludingTrailingWhitespace <
                    boxWidth)
                {
                    startSize = middleSize + space;
                }
                else if (MeasureText(middleSize).WidthIncludingTrailingWhitespace >
                    boxWidth)
                {
                    endSize = middleSize - space;
                }
                else
                {
                    return middleSize;
                }
            }
            return FontSize;
        }

得到的FontSize就是自动适应后的字体大小,绑定到TextBox就完成了。。

上面只是一种方法,下面说另一种简单粗暴,直接附上代码:

double scal = 1d;
private void CalculationScal(){
    var boxWidth = this.Width;
    if(MeasureText(this.FontSize).WidthIncludingTrailingWhitespace > boxWidth){
        scal = boxWidth/MeasureText(this.FontSize).WidthIncludingTrailingWhitespace;
 
    }
    else
    {
    scal = 1d;
    }
}

直接用scal乘上FontSize就OK了。。

其中WidthIncludingTrailingWhitespace 是包括所有尾随空格字符,还有一个Width是不包括任何尾随空格字符的,需要注意一下