WPF 导入自定义字体并实现按钮悬停高亮效果
完整实现方案
1. 项目结构
FontDemo/
├── Assets/
│ └── Fonts/
│ ├── Pacifico-Regular.ttf
│ └── Roboto-Bold.ttf
├── App.xaml
├── MainWindow.xaml
└── MainWindow.xaml.cs
2. 添加字体文件到项目
- 在项目中创建
Assets/Fonts
文件夹 - 将TTF字体文件复制到此文件夹
- 在解决方案资源管理器中右键点击字体文件 → 属性
- 生成操作: Resource
- 复制到输出目录: 不复制
3. App.xaml - 全局字体资源定义
<Application x:Class="FontDemo.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
<!-- 定义自定义字体 -->
<FontFamily x:Key="PacificoFont">pack://application:,,,/Assets/Fonts/#Pacifico</FontFamily>
<FontFamily x:Key="RobotoBoldFont">pack://application:,,,/Assets/Fonts/#Roboto Bold</FontFamily>
<!-- 按钮样式 -->
<Style x:Key="CustomButtonStyle" TargetType="Button">
<Setter Property="Background" Value="#4a6fa5"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Padding" Value="20,10"/>
<Setter Property="Margin" Value="10"/>
<Setter Property="FontSize" Value="18"/>
<Setter Property="FontFamily" Value="{StaticResource PacificoFont}"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border x:Name="border"
Background="{TemplateBinding Background}"
CornerRadius="8">
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<!-- 鼠标悬停效果 -->
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#6b8fc7"/>
<Setter Property="Foreground" Value="#ffeb3b"/>
<Setter Property="RenderTransform">
<Setter.Value>
<ScaleTransform ScaleX="1.05" ScaleY="1.05"/>
</Setter.Value>
</Setter>
<Setter Property="Effect">
<Setter.Value>
<DropShadowEffect BlurRadius="10"
ShadowDepth="3"
Color="#40000000"/>
</Setter.Value>
</Setter>
</Trigger>
<!-- 按下效果 -->
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="#3a5a85"/>
<Setter Property="Foreground" Value="#ffffff"/>
<Setter Property="RenderTransform">
<Setter.Value>
<ScaleTransform ScaleX="0.98" ScaleY="0.98"/>
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Application.Resources>
</Application>
4. MainWindow.xaml - 主界面设计
<Window x:Class="FontDemo.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:FontDemo"
mc:Ignorable="d"
Title="自定义字体与悬停效果"
Height="600"
Width="800"
Background="#f5f7fa">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- 标题区域 -->
<Border Grid.Row="0" Background="#4a6fa5" Padding="20">
<TextBlock Text="自定义字体与悬停效果演示"
FontSize="28"
FontFamily="{StaticResource RobotoBoldFont}"
Foreground="White"
HorizontalAlignment="Center"/>
</Border>
<!-- 主内容区 -->
<Grid Grid.Row="1" Margin="20">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- 左侧演示区 -->
<StackPanel Grid.Column="0" Margin="0,0,10,0">
<TextBlock Text="按钮悬停效果演示"
FontSize="20"
FontFamily="{StaticResource RobotoBoldFont}"
Margin="0,0,0,20"/>
<Button Content="主要操作按钮"
Style="{StaticResource CustomButtonStyle}"
Height="60"/>
<Button Content="提交表单"
Style="{StaticResource CustomButtonStyle}"
Height="60"/>
<Button Content="删除项目"
Style="{StaticResource CustomButtonStyle}"
Background="#e74c3c"
Height="60">
<Button.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="(Button.Background).(SolidColorBrush.Color)"
To="#ff6b5b"
Duration="0:0:0.2"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="(Button.Background).(SolidColorBrush.Color)"
To="#e74c3c"
Duration="0:0:0.3"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Button.Triggers>
</Button>
<TextBlock Text="字体预览"
FontSize="20"
FontFamily="{StaticResource RobotoBoldFont}"
Margin="0,40,0,10"/>
<TextBlock Text="Pacifico 字体示例"
FontSize="24"
FontFamily="{StaticResource PacificoFont}"
Margin="0,0,0,10"/>
<TextBlock Text="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
FontSize="18"
FontFamily="{StaticResource PacificoFont}"
Margin="0,0,0,10"/>
<TextBlock Text="abcdefghijklmnopqrstuvwxyz"
FontSize="18"
FontFamily="{StaticResource PacificoFont}"
Margin="0,0,0,20"/>
</StackPanel>
<!-- 右侧演示区 -->
<StackPanel Grid.Column="1" Margin="10,0,0,0">
<TextBlock Text="高级悬停效果"
FontSize="20"
FontFamily="{StaticResource RobotoBoldFont}"
Margin="0,0,0,20"/>
<!-- 渐变按钮 -->
<Button Content="渐变按钮"
Height="70"
FontFamily="{StaticResource PacificoFont}"
FontSize="20"
Margin="0,0,0,20">
<Button.Style>
<Style TargetType="Button" BasedOn="{StaticResource CustomButtonStyle}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border x:Name="border"
CornerRadius="10"
Background="#4a6fa5">
<Border.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="#4a6fa5" Offset="0"/>
<GradientStop Color="#6b8fc7" Offset="1"/>
</LinearGradientBrush>
</Border.Background>
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="border" Property="Background">
<Setter.Value>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="#6b8fc7" Offset="0"/>
<GradientStop Color="#8da9d9" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="Foreground" Value="#fff176"/>
<Setter Property="Effect">
<Setter.Value>
<DropShadowEffect BlurRadius="15"
ShadowDepth="5"
Color="#60000000"/>
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Button.Style>
</Button>
<!-- 图标按钮 -->
<Button Height="80"
Margin="0,0,0,20">
<Button.Style>
<Style TargetType="Button" BasedOn="{StaticResource CustomButtonStyle}">
<Setter Property="Background" Value="#27ae60"/>
</Style>
</Button.Style>
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
<Path Data="M12,17.27L18.18,21L16.54,13.97L22,9.24L14.81,8.62L12,2L9.19,8.62L2,9.24L7.45,13.97L5.82,21L12,17.27Z"
Fill="White"
Width="24"
Height="24"
Margin="0,0,10,0"
Stretch="Uniform"/>
<TextBlock Text="收藏项目"
FontFamily="{StaticResource PacificoFont}"
FontSize="20"
Foreground="White"/>
</StackPanel>
<Button.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity"
To="0.9"
Duration="0:0:0.2"/>
<ColorAnimation Storyboard.TargetProperty="(Button.Background).(SolidColorBrush.Color)"
To="#2ecc71"
Duration="0:0:0.2"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity"
To="1"
Duration="0:0:0.3"/>
<ColorAnimation Storyboard.TargetProperty="(Button.Background).(SolidColorBrush.Color)"
To="#27ae60"
Duration="0:0:0.3"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Button.Triggers>
</Button>
<!-- 边框按钮 -->
<Button Content="边框按钮"
Height="60"
FontFamily="{StaticResource PacificoFont}"
FontSize="20"
Margin="0,0,0,20">
<Button.Style>
<Style TargetType="Button">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Foreground" Value="#4a6fa5"/>
<Setter Property="BorderBrush" Value="#4a6fa5"/>
<Setter Property="BorderThickness" Value="2"/>
<Setter Property="Padding" Value="20,10"/>
<Setter Property="Margin" Value="10"/>
<Setter Property="FontSize" Value="18"/>
<Setter Property="FontFamily" Value="{StaticResource PacificoFont}"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border x:Name="border"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="8">
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#4a6fa5"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="BorderBrush" Value="#4a6fa5"/>
<Setter Property="Effect">
<Setter.Value>
<DropShadowEffect BlurRadius="10"
ShadowDepth="3"
Color="#40000000"/>
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Button.Style>
</Button>
</StackPanel>
</Grid>
</Grid>
</Window>
5. MainWindow.xaml.cs - 代码后台
using System.Windows;
namespace FontDemo
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
}
关键实现说明
1. 导入TTF字体
<FontFamily x:Key="PacificoFont">pack://application:,,,/Assets/Fonts/#Pacifico</FontFamily>
- 路径格式:
pack://application:,,,/文件夹路径/#字体名称
- 注意事项:
- 字体名称不是文件名,而是字体内部名称(可通过双击字体文件查看)
- 字体文件生成操作必须设置为"Resource"
2. 按钮悬停高亮效果实现
方法1: 使用触发器(Trigger)
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#6b8fc7"/>
<Setter Property="Foreground" Value="#ffeb3b"/>
<Setter Property="RenderTransform">
<Setter.Value>
<ScaleTransform ScaleX="1.05" ScaleY="1.05"/>
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
方法2: 使用事件触发器(EventTrigger)和动画
<Button.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="(Button.Background).(SolidColorBrush.Color)"
To="#ff6b5b"
Duration="0:0:0.2"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Button.Triggers>
3. 按钮样式设计技巧
圆角按钮
<Border CornerRadius="8">
<!-- 按钮内容 -->
</Border>
渐变背景
<Border.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="#4a6fa5" Offset="0"/>
<GradientStop Color="#6b8fc7" Offset="1"/>
</LinearGradientBrush>
</Border.Background>
悬停阴影效果
<Setter Property="Effect">
<Setter.Value>
<DropShadowEffect BlurRadius="10"
ShadowDepth="3"
Color="#40000000"/>
</Setter.Value>
</Setter>
缩放动画
<Setter Property="RenderTransform">
<Setter.Value>
<ScaleTransform ScaleX="1.05" ScaleY="1.05"/>
</Setter.Value>
</Setter>
4. 字体应用方式
全局样式应用
<Style x:Key="CustomButtonStyle" TargetType="Button">
<Setter Property="FontFamily" Value="{StaticResource PacificoFont}"/>
</Style>
单个控件应用
<Button FontFamily="{StaticResource PacificoFont}"/>
文本元素应用
<TextBlock FontFamily="{StaticResource RobotoBoldFont}"/>
常见问题解决方案
1. 字体未正确加载
检查项:
- 字体文件是否包含在项目中
- 字体文件属性是否设置为"Resource"
- 字体名称拼写是否正确(区分大小写)
- 字体路径是否正确
调试方法:
// 在代码中检查字体是否加载成功
var fontUri = new Uri("pack://application:,,,/Assets/Fonts/Pacifico-Regular.ttf");
var fontFamily = new FontFamily(fontUri, "Pacifico");
2. 悬停效果不生效
可能原因:
- 触发器条件设置错误
- 样式作用域问题
- 其他样式覆盖
解决方案:
- 确保使用正确的依赖属性(IsMouseOver)
- 检查样式作用域,确保应用了自定义样式
- 使用BasedOn继承基本样式,避免覆盖
3. 字体渲染问题
- 优化技巧:
<TextBlock Text="平滑字体渲染"
TextOptions.TextFormattingMode="Display"
TextOptions.TextRenderingMode="ClearType"/>
高级技巧
1. 动态切换字体
private void ChangeFontButton_Click(object sender, RoutedEventArgs e)
{
var button = sender as Button;
button.FontFamily = (FontFamily)Application.Current.Resources["RobotoBoldFont"];
}
2. 创建字体资源字典
FontResources.xaml
:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<FontFamily x:Key="MainFont">pack://application:,,,/Assets/Fonts/#Roboto</FontFamily>
<FontFamily x:Key="HeadingFont">pack://application:,,,/Assets/Fonts/#Roboto Bold</FontFamily>
<FontFamily x:Key="DecorativeFont">pack://application:,,,/Assets/Fonts/#Pacifico</FontFamily>
</ResourceDictionary>
在App.xaml中引用:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="FontResources.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
3. 创建字体混合效果
<TextBlock Text="混合字体效果">
<TextBlock.Inlines>
<Run Text="使用" FontFamily="{StaticResource RobotoBoldFont}"/>
<Run Text="不同" FontFamily="{StaticResource PacificoFont}" Foreground="#4a6fa5"/>
<Run Text="字体" FontFamily="{StaticResource RobotoBoldFont}"/>
</TextBlock.Inlines>
</TextBlock>