参考文章:https://blog.csdn.net/ljz_1985/article/details/17141087
实现的效果如下所示:(不使用ViewBox)当窗体变大或者缩小时,计算字体大小,然后绑定
前台代码如下:
MainWindow.xaml
:
<Window x:Class="WPF自动调整FontSize.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WPF自动调整FontSize"
mc:Ignorable="d"
Title="MainWindow" Height="100" WindowStartupLocation="CenterScreen" SizeChanged="Window_SizeChanged" Width="100" d:DataContext="{d:DesignInstance local:MainWindowViewModel}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid x:Name="gridRow0">
<TextBlock HorizontalAlignment="Center" Text="{Binding Text1}" FontSize="{Binding Text1FontSize}" VerticalAlignment="Center">Hello World</TextBlock>
<TextBlock Text="{Binding Text1FontSize}" HorizontalAlignment="Right" VerticalAlignment="Bottom"></TextBlock>
</Grid>
<Grid x:Name="gridRow1" Grid.Row="1">
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="{Binding Text2FontSize}" Text="{Binding Text2}">WPF</TextBlock>
<TextBlock Text="{Binding Text2FontSize}" HorizontalAlignment="Right" VerticalAlignment="Bottom"></TextBlock>
</Grid>
</Grid>
</Window>
MainWindow.xaml.cs
:
namespace WPF自动调整FontSize
{
///
/// MainWindow.xaml 的交互逻辑
///
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new MainWindowViewModel(this);
}
private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
{
(this.DataContext as MainWindowViewModel)?.RaiseSizeChanged();
}
}
}
MainWindowViewModel.cs
:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;
namespace WPF自动调整FontSize
{
public class MainWindowViewModel : INotifyPropertyChanged
{
private MainWindow _view;
public MainWindowViewModel(MainWindow view)
{
this._view = view;
}
///
/// Measures the size of the text.
///
/// The text.
/// The font family.
/// The font style.
/// The font weight.
/// The font stretch.
/// Size of the font.
///
private static Size MeasureTextSize(
string text, FontFamily fontFamily,
FontStyle fontStyle,
FontWeight fontWeight,
FontStretch fontStretch,
double fontSize)
{
FormattedText ft = new FormattedText(text,
CultureInfo.CurrentCulture,
System.Windows.FlowDirection.LeftToRight,
new Typeface(fontFamily, fontStyle, fontWeight, fontStretch),
fontSize,
Brushes.Black);
return new Size(ft.Width, ft.Height);
}
///
/// Get the required height and width of the specified text. Uses Glyph's
///
private static Size MeasureText(string text, FontFamily fontFamily,
FontStyle fontStyle, FontWeight fontWeight,
FontStretch fontStretch, double fontSize)
{
Typeface typeface = new Typeface(fontFamily, fontStyle, fontWeight, fontStretch);
GlyphTypeface glyphTypeface;
if (!typeface.TryGetGlyphTypeface(out glyphTypeface))
{
return MeasureTextSize(text, fontFamily, fontStyle, fontWeight, fontStretch, fontSize);
}
double totalWidth = 0;
double height = 0;
for (int n = 0; n < text.Length; n++)
{
ushort glyphIndex = glyphTypeface.CharacterToGlyphMap[text[n]];
double width = glyphTypeface.AdvanceWidths[glyphIndex] * fontSize;
double glyphHeight = glyphTypeface.AdvanceHeights[glyphIndex] * fontSize;
if (glyphHeight > height)
{
height = glyphHeight;
}
totalWidth += width;
}
return new Size(totalWidth, height);
}
private static int minFontSize = 1;
private static int maxFontSize = 500;
///
/// Limits the size of the control font.
///
/// The text.
/// The font family.
/// The font style.
/// The font weight.
/// The font stretch.
private double GetFontSize(
string text,
FontFamily fontFamily,
FontStyle fontStyle,
FontWeight fontWeight,
FontStretch fontStretch,
double width, double height)
{
for (int i = minFontSize; i <= maxFontSize; i++)
{
Size size = MeasureText(text, fontFamily, fontStyle,
fontWeight, fontStretch, i);
if (width - 20 <= size.Width ||
height - 10 <= size.Height)
{
return i;
}
}
return maxFontSize;
}
private string text1 = "Hello World";
public string Text1
{
get { return text1; }
set { text1 = value; this.RaisePropertyChanged(nameof(Text1)); }
}
private string text2 = "WPF";
public string Text2
{
get { return text2; }
set { text2 = value; this.RaisePropertyChanged(nameof(Text2)); }
}
public double Text1FontSize
{
get { return GetFontSize(this.Text1, this._view.FontFamily, this._view.FontStyle, this._view.FontWeight, this._view.FontStretch, this._view.gridRow0.ActualWidth, this._view.gridRow0.ActualHeight); }
}
public double Text2FontSize
{
get { return GetFontSize(this.Text2, this._view.FontFamily, this._view.FontStyle, this._view.FontWeight, this._view.FontStretch, this._view.gridRow1.ActualWidth, this._view.gridRow1.ActualHeight); }
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string name)
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
internal void RaiseSizeChanged()
{
this.RaisePropertyChanged(nameof(Text1FontSize));
this.RaisePropertyChanged(nameof(Text2FontSize));
}
}
}