如果文本超出Textblock的边界,请更改字体大小

时间:2011-08-18 13:47:18

标签: c# .net wpf xaml

我有一个尺寸为Width = 511,Height = 159的文本块。字号= 28。如果文本超出文本块的尺寸,我想更改字体大小,以便显示所有文本。有办法做到这一点吗?一个公式可能?

5 个答案:

答案 0 :(得分:2)

这个解决方案意味着使用ViewBox,我认为使用Wpf转换功能不需要更改文本的字体大小,几乎可以使用转换(在这种情况下为ViewBox)来实现相同的结果。

不要将TextBlock放在ViewBox中,而是修改它的模板并将控件放在ViewBox中的文本所在位置,如:

<ControlTemplate TargetType="{x:Type TextBox}">                     
    <Microsoft_Windows_Themes:ListBoxChrome x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderFocused="{TemplateBinding IsKeyboardFocusWithin}" SnapsToDevicePixels="true">
        <Viewbox HorizontalAlignment="Left">
            <ScrollViewer x:Name="PART_ContentHost" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
        </Viewbox>
    </Microsoft_Windows_Themes:ListBoxChrome>

    <ControlTemplate.Triggers>
        <Trigger Property="IsEnabled" Value="false">
            <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

现在你得到一个控件来调整它的文本大小以适应可用空间,感谢WPF。

这里还有一些例子

text example

答案 1 :(得分:0)

我不太确定WPF,但是在WinForms中你可以使用MeasureString方法来测量给定字体中的字符串尺寸。因此,只要文本块的内容发生变化,您只需要使用此方法,如果文本的尺寸大于文本块的尺寸 - 减小字体大小并再次测量。

(现在,在我写完之后,我认为应该有一个更简单的方法)

答案 2 :(得分:0)

这取决于您使用的字体,例如,Courier New旨在让每个字符具有相同的宽度,因此如果您研究每个字符的宽度是什么,您可以使用字符串的get length函数(给你字符的长度)并从那里计算其宽度(以像素为单位)。如果宽度超过511px,则相应调整尺寸。

如果您使用不同的字体,如Arial,您可以这样做,如果您真的想要它准确,您可以将字母表分组为窄字母,如'i','l'等,中等字母如't '和像'o'和大写字母一样的胖子字母。然后你得到了窄,中,胖字母的数量,并根据这些数据来计算尺寸,但就个人而言,这对我来说太过分了。

希望这有用。

编辑:忽略这个,我只是读了一下measuretring函数,这比我的建议要小得多。

答案 3 :(得分:0)

这就是我想出的。请务必处理-1.0字体大小的情况。

      private static double GetFontSize(TextBox textBox)
      {
         double fontSize = textBox.FontSize;
         FormattedText ft = new FormattedText(textBox.Text, CultureInfo.CurrentCulture, System.Windows.FlowDirection.LeftToRight,
                                          new Typeface(textBox.FontFamily, textBox.FontStyle, textBox.FontWeight, textBox.FontStretch),
                                          fontSize, textBox.Foreground);
         while (textBox.Width < ft.Width)
         {
            fontSize -= 1;
            if (fontSize < 0) return -1.0;
            ft = new FormattedText(textBox.Text, CultureInfo.CurrentCulture, System.Windows.FlowDirection.LeftToRight,
                                                      new Typeface(textBox.FontFamily, textBox.FontStyle, textBox.FontWeight, textBox.FontStretch),
                                                      fontSize, textBox.Foreground);
         }

         return fontSize;
      }

答案 4 :(得分:0)

编辑:我应该在发布之前查看标签。不知道WPF可能提供什么来解决这个问题。

我没有任何证据来支持这一点,但似乎(对于可变宽度字体,至少是我机器上安装的所有字体):

  • 字体大小与给定字符串的宽度呈线性关系
  • 字体大小0导致宽度为0

这意味着您可以在允许的最大字体大小上使用MeasureString一次,然后进行插值以找到最佳字体大小。

虽然在“线性道路”上有一些“像素颠簸”,所以你可以关闭几个像素 - 但它是测量循环的一个很好的选择。