XAML:button控件模板
2026/7/5 3:10:22 网站建设 项目流程

1、

<!-- ====== 窗口声明 ====== --> <Window x:Class="WpfApp1.MainWindow" <!-- 绑定到 MainWindow.xaml.cs 中的 MainWindow 类 --> xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" <!-- WPF 核心命名空间(控件、布局等) --> xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" <!-- XAML 语言命名空间(x:Key、x:Name 等) --> Title="WPF 控件模板学习" Height="700" Width="1000" <!-- 窗口标题和尺寸 --> WindowStartupLocation="CenterScreen"> <!-- 启动时居中显示 --> <!-- ====== Window.Resources:定义可复用的样式和模板 ====== --> <Window.Resources> <!-- ========================================================== 示例 1:最简单的按钮模板 核心概念: - ControlTemplate 替换按钮的默认视觉树 - ContentPresenter 是"内容的占位符",显示 Button.Content - Trigger 根据按钮状态(悬停/按下)切换外观 ========================================================== --> <Style x:Key="SimpleButtonStyle" TargetType="Button"> <!-- x:Key 是资源键名,TargetType 指定应用到 Button --> <Setter Property="Template"> <!-- 要设置的属性是 Template(即 ControlTemplate) --> <Setter.Value> <ControlTemplate TargetType="Button"> <!-- 定义模板,TargetType 必须与 Style 一致 --> <!-- 1. Button 初始状态 --> <!-- Border 作为按钮的背景和边框容器 --> <Border x:Name="border" <!-- x:Name 让 Trigger 能通过 TargetName 定位它 --> Background="DodgerBlue" <!-- 默认背景:道奇蓝 --> CornerRadius="8" <!-- 圆角半径 8px --> BorderBrush="DarkBlue" <!-- 边框颜色 --> BorderThickness="2"> <!-- 边框宽度 2px --> <!-- ContentPresenter:核心占位符,自动渲染 Button.Content 属性里的内容 --> <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" TextElement.Foreground="White" <!-- 文字颜色:白 --> TextElement.FontWeight="Bold" /> <!-- 文字粗细:粗体 --> </Border> <!-- 2. Button “触发”状态 --> <!-- 触发器:根据属性值变化自动切换视觉效果 --> <ControlTemplate.Triggers> <!-- 鼠标悬停时:背景变橙红色 --> <Trigger Property="IsMouseOver" Value="True"> <Setter TargetName="border" Property="Background" Value="OrangeRed" /> </Trigger> <!-- 按下时:背景变暗红色 --> <Trigger Property="IsPressed" Value="True"> <Setter TargetName="border" Property="Background" Value="DarkRed" /> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> <!-- ========================================================== 示例 2:霓虹灯按钮模板(带动画) 新增概念: - Trigger.EnterActions / ExitActions:进入/离开状态时播放 Storyboard 动画 - DoubleAnimation:double 类型的属性动画 ========================================================== --> <Style x:Key="NeonButtonStyle" TargetType="Button"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="Button"> <!-- 1. Button初始状态 --> <!-- Grid 叠加两层 Border:下层发光层(glow),上层边框层(border) --> <Grid> <!-- 发光层:初始 Opacity="0"(不可见),鼠标悬停时渐变为 0.6 --> <!-- 发光层: 比按钮大一圈 + 模糊效果,悬停时从边缘透出霓虹光晕 --> <!-- x:Name="glow" 定义一个名为 glow 的边框,用作发光光晕层。Background="#FF00FF"背景色为亮粉色(品红),即发光颜色。圆角半径为 8 像素,让光晕边缘柔和。--> <!-- Opacity="0" 不透明度为 0,初始完全透明(隐藏),等待动画触发显示 --> <!-- Margin="-6" 负外边距 -6 像素,向四周撑开,比父容器大一圈,制造光晕从内部溢出的效果 --> <Border x:Name="glow" Background="#FF00FF" CornerRadius="8" Opacity="0" Margin="-6"> <!-- 高斯模糊特效,模糊半径为 10,将纯色背景涂抹成柔和的雾状光晕 --> <Border.Effect> <BlurEffect Radius="10" /> </Border.Effect> </Border> <!-- 边框层:深色背景 + 霓虹色边框 --> <Border x:Name="border" Background="#222" CornerRadius="6" BorderBrush="#FF00FF" BorderThickness="2"> <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" TextElement.Foreground="#FF00FF" TextElement.FontWeight="Bold" /> </Border> </Grid> <!-- 2. Button “触发”状态 --> <ControlTemplate.Triggers> <!-- 触发器1:鼠标悬停:进入时发光层淡入,离开时发光层淡出 --> <Trigger Property="IsMouseOver" Value="True"> <!-- 进入悬停状态时,执行的操作(这里是 一个动画) --> <Trigger.EnterActions> <!-- 播放指令/动作(这里是播放一个动画剧本Storyboard) --> <BeginStoryboard> <!-- 动画剧本/时间线容器Storyboard,作用:定义了“让谁的哪个属性,在几秒内,变到多少” --> <Storyboard> <!-- 目标:glow 的 Opacity 属性,从当前值动画到 0.6 --> <DoubleAnimation Storyboard.TargetName="glow" Storyboard.TargetProperty="Opacity" To="0.6" Duration="0:0:0.3" /> <!-- 动画时长 0.3 秒 --> </Storyboard> </BeginStoryboard> </Trigger.EnterActions> <!-- 离开悬停状态时执行的动画 --> <Trigger.ExitActions> <BeginStoryboard> <Storyboard> <DoubleAnimation Storyboard.TargetName="glow" Storyboard.TargetProperty="Opacity" To="0" Duration="0:0:0.3" /> </Storyboard> </BeginStoryboard> </Trigger.ExitActions> </Trigger> <!-- 按下时:边框变白色,文字也变白 --> <Trigger Property="IsPressed" Value="True"> <Setter TargetName="border" Property="BorderBrush" Value="White" /> <Setter Property="Foreground" Value="White" /> <!-- 不指定 TargetName 就是控件本身 --> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> <!-- ========================================================== 示例 3:ToggleButton 滑动开关模板 新增概念: - ToggleButton:有 Checked/Unchecked 两种状态 - ThicknessAnimation:对 Margin/Thickness 做动画 - ColorAnimation:对 Color 类型的属性做动画 ========================================================== --> <Style x:Key="ToggleSwitchStyle" TargetType="ToggleButton"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="ToggleButton"> <!-- 外框:灰色圆角矩形,作为开关轨道 --> <Border x:Name="outer" Width="60" Height="30" CornerRadius="15" Background="#555" Cursor="Hand"> <!-- 滑块:白色圆形,初始靠左 --> <Border x:Name="thumb" Width="26" Height="26" CornerRadius="13" Background="White" HorizontalAlignment="Left" Margin="2,0"> <!-- RenderTransform 用来做位移动画(虽然本例直接用 Margin 动画) --> <Border.RenderTransform> <TranslateTransform /> </Border.RenderTransform> </Border> </Border> <ControlTemplate.Triggers> <!-- IsChecked=True → 开关"打开" --> <Trigger Property="IsChecked" Value="True"> <Trigger.EnterActions> <BeginStoryboard> <Storyboard> <!-- 轨道从灰色变绿色 --> <ColorAnimation Storyboard.TargetName="outer" Storyboard.TargetProperty="Background.Color" To="#00CC66" Duration="0:0:0.2" /> <!-- 滑块从左边滑到右边(Margin.Left 从 2 → 32) --> <ThicknessAnimation Storyboard.TargetName="thumb" Storyboard.TargetProperty="Margin" To="32,0,0,0" Duration="0:0:0.2" /> </Storyboard> </BeginStoryboard> </Trigger.EnterActions> <Trigger.ExitActions> <BeginStoryboard> <Storyboard> <!-- 恢复:轨道变灰、滑块返回左边 --> <ColorAnimation Storyboard.TargetName="outer" Storyboard.TargetProperty="Background.Color" To="#555" Duration="0:0:0.2" /> <ThicknessAnimation Storyboard.TargetName="thumb" Storyboard.TargetProperty="Margin" To="2,0,0,0" Duration="0:0:0.2" /> </Storyboard> </BeginStoryboard> </Trigger.ExitActions> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> <!-- ========================================================== 示例 4:圆形进度条模板(ProgressBar) 新增概念: - PART_ 命名约定:模板中命名如 PART_Track,控件内部代码通过 Template.FindName("PART_Track", this) 查找此元素 - StrokeDashArray:虚线数组,用来画"圆弧进度" - RotateTransform:旋转,让椭圆从顶部开始画 ========================================================== --> <Style x:Key="CircleProgressStyle" TargetType="ProgressBar"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="ProgressBar"> <Grid Width="120" Height="120"> <!-- 底层灰色圆环:总长度(100% 的背景环) --> <Ellipse Stroke="#333" StrokeThickness="10" /> <!-- 上层绿色圆环(进度环):PART_Track 是约定名称,C# 代码通过它找到此元素 --> <Ellipse x:Name="PART_Track" Stroke="#00CC66" StrokeThickness="10" StrokeDashArray="0 1000" <!-- 初始虚线:0 可见,1000 不可见→全不可见即 0% --> RenderTransformOrigin="0.5,0.5"> <!-- 旋转中心在椭圆中心 --> <Ellipse.RenderTransform> <RotateTransform Angle="-90" /> <!-- 旋转-90°,让进度从 12 点方向开始 --> </Ellipse.RenderTransform> </Ellipse> <!-- 中间百分比文字 --> <TextBlock x:Name="txtPercent" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="24" FontWeight="Bold" Text="0%" Foreground="#00CC66" /> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style> <!-- ========================================================== 示例 5:ListBox 卡片项模板 新增概念: - ListBoxItem 的模板控制每一条的外观 - IsSelected + IsMouseOver 多状态切换 - ItemContainerStyle 将模板应用到所有项 ========================================================== --> <Style x:Key="CardListBoxItemStyle" TargetType="ListBoxItem"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="ListBoxItem"> <!-- 卡片容器 --> <Border x:Name="card" Background="#2a2a2a" CornerRadius="10" BorderBrush="#444" BorderThickness="1" Padding="12" Margin="4"> <ContentPresenter /> <!-- 显示 ListBoxItem 的 Content --> </Border> <ControlTemplate.Triggers> <!-- 选中时:蓝色背景 + 亮蓝边框 --> <Trigger Property="IsSelected" Value="True"> <Setter TargetName="card" Property="Background" Value="#3a5a8a" /> <Setter TargetName="card" Property="BorderBrush" Value="#6a9ada" /> <Setter TargetName="card" Property="BorderThickness" Value="2" /> </Trigger> <!-- 悬停时:浅灰色背景 --> <Trigger Property="IsMouseOver" Value="True"> <Setter TargetName="card" Property="Background" Value="#353535" /> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> </Window.Resources> <!-- ========================================================== 以下是页面布局——展示【上述5 个模板】的实际效果 布局结构:Grid → ScrollViewer → StackPanel → 多个区域 ========================================================== --> <Grid Background="#1a1a2e"> <!-- 深蓝紫色背景 --> <ScrollViewer VerticalScrollBarVisibility="Auto"> <!-- 允许垂直滚动 --> <StackPanel Margin="20"> <!-- 外层垂直排列,四周留 20px 边距 --> <!-- 标题 --> <TextBlock Text="🎯 WPF 控件模板 (ControlTemplate) 学习示例" FontSize="28" FontWeight="Bold" Foreground="White" HorizontalAlignment="Center" Margin="0,10,0,10" /> <!-- ====== 第一节:展示简单按钮模板 ====== --> <Border Background="#252540" CornerRadius="12" Padding="16" Margin="0,0,0,16"> <StackPanel> <TextBlock Text="1️⃣ 基础按钮模板 —— 自定义外观 + 鼠标悬停/按下触发器" FontSize="16" FontWeight="Bold" Foreground="#FFD700" Margin="0,0,0,10" /> <StackPanel Orientation="Horizontal" HorizontalAlignment="Center"> <!-- 左边:默认样式的按钮,作对比 --> <Button Content="默认按钮" Width="120" Height="40" /> <!-- 右边:应用 SimpleButtonStyle 的自定义按钮 --> <Button Content="自定义模板" Width="140" Height="42" Margin="12,0,0,0" Style="{StaticResource SimpleButtonStyle}" /> </StackPanel> </StackPanel> </Border> <!-- ====== 第二节:展示霓虹灯按钮 ====== --> <Border Background="#252540" CornerRadius="12" Padding="16" Margin="0,0,0,16"> <StackPanel> <TextBlock Text="2️⃣ 动画触发器 —— 鼠标悬停发光效果" FontSize="16" FontWeight="Bold" Foreground="#FFD700" Margin="0,0,0,10" /> <Button Content="✨ 霓虹按钮" Width="160" Height="50" Style="{StaticResource NeonButtonStyle}" /> <TextBlock Foreground="#888" FontSize="12" Margin="0,6,0,0" Text="💡 关键:Trigger.EnterActions / ExitActions + Storyboard" /> </StackPanel> </Border> <!-- ====== 第三节:展示 ToggleButton 开关 ====== --> <Border Background="#252540" CornerRadius="12" Padding="16" Margin="0,0,0,16"> <StackPanel> <TextBlock Text="3️⃣ ToggleButton 模板 —— 滑动开关" FontSize="16" FontWeight="Bold" Foreground="#FFD700" Margin="0,0,0,10" /> <StackPanel Orientation="Horizontal" HorizontalAlignment="Center"> <ToggleButton Style="{StaticResource ToggleSwitchStyle}" /> <!-- 状态文字,x:Name 让 C# 代码可以通过 FindName 找到它 --> <TextBlock x:Name="toggleStatus" Text="关闭" Foreground="#888" FontSize="16" VerticalAlignment="Center" Margin="20,0,0,0" /> </StackPanel> <TextBlock Foreground="#888" FontSize="12" Margin="0,6,0,0" Text="💡 关键:IsChecked 触发动画 + ThicknessAnimation 滑块位移" /> </StackPanel> </Border> <!-- ====== 第四节:展示圆形进度条 ====== --> <Border Background="#252540" CornerRadius="12" Padding="16" Margin="0,0,0,16"> <StackPanel> <TextBlock Text="4️⃣ ProgressBar 模板 —— 圆形进度条 (PART_Track)" FontSize="16" FontWeight="Bold" Foreground="#FFD700" Margin="0,0,0,10" /> <StackPanel Orientation="Horizontal" HorizontalAlignment="Center"> <ProgressBar Style="{StaticResource CircleProgressStyle}" Width="120" Height="120" Value="0" Minimum="0" Maximum="100" /> </StackPanel> <!-- 加减按钮,Click 事件绑定到 C# 代码 --> <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,8,0,0"> <Button Content="-10" Width="60" Height="30" Click="BtnMinus" Background="#ff4444" Foreground="White" BorderThickness="0" /> <Button Content="+10" Width="60" Height="30" Click="BtnPlus" Background="#44cc44" Foreground="White" BorderThickness="0" Margin="8,0" /> </StackPanel> <TextBlock Foreground="#888" FontSize="12" Margin="0,6,0,0" Text="💡 关键:PART_Track + StrokeDashArray 实现圆弧进度" /> </StackPanel> </Border> <!-- ====== 第五节:展示 ListBox 卡片模板 ====== --> <Border Background="#252540" CornerRadius="12" Padding="16" Margin="0,0,0,16"> <StackPanel> <TextBlock Text="5️⃣ ListBoxItem 模板 —— 卡片列表" FontSize="16" FontWeight="Bold" Foreground="#FFD700" Margin="0,0,0,10" /> <!-- ItemContainerStyle 将 CardListBoxItemStyle 应用到所有 ListBoxItem --> <ListBox ItemContainerStyle="{StaticResource CardListBoxItemStyle}" Background="Transparent" BorderThickness="0" Height="140"> <ListBoxItem Content="📁 项目一:了解 ControlTemplate 基本结构" /> <ListBoxItem Content="📁 项目二:掌握 Trigger 和动画" /> <ListBoxItem Content="📁 项目三:PART_ 命名约定" /> </ListBox> <TextBlock Foreground="#888" FontSize="12" Margin="0,6,0,0" Text="💡 关键:在 ListBoxItem 的模板中定制卡片样式" /> </StackPanel> </Border> <!-- ====== 知识点总结区域 ====== --> <Border Background="#1a1a3a" CornerRadius="12" Padding="16" Margin="0,0,0,16" BorderBrush="#FFD700" BorderThickness="1"> <StackPanel> <TextBlock Text="📖 ControlTemplate 核心知识" FontSize="18" FontWeight="Bold" Foreground="#FFD700" Margin="0,0,0,10" /> <TextBlock Foreground="#ccc" FontSize="14" TextWrapping="Wrap"> • ControlTemplate 定义控件的 视觉结构 和 行为(替换 WPF 控件的默认外观) • Template 通过 Style 的 Setter 或直接在控件上设置 Template 属性来应用 • ContentPresenter —— 用于显示 Button/ContentControl 中 Content 属性的占位符 • ItemsPresenter —— 用于 ItemsControl(如 ListBox)显示项集合 • PART_ 命名约定 —— 模板中的关键元素命名(如 PART_Track),控件代码会通过此名称查找 • Trigger / DataTrigger / MultiTrigger —— 根据属性值切换视觉效果 • Trigger.EnterActions / ExitActions —— 运行动画 Storyboard • TemplateBinding —— 将模板元素的属性绑定到控件的依赖属性 </TextBlock> </StackPanel> </Border> </StackPanel> </ScrollViewer> </Grid> </Window>

2、知识点总结部分

如果是

<!-- ====== 知识点总结区域 ====== --> <Border Background="#1a1a3a" CornerRadius="12" Padding="16" Margin="0,0,0,16" BorderBrush="#FFD700" BorderThickness="1"> <StackPanel> <TextBlock Text="📖 ControlTemplate 核心知识" FontSize="18" FontWeight="Bold" Foreground="#FFD700" Margin="0,0,0,10" /> <TextBlock Foreground="#ccc" FontSize="14" TextWrapping="Wrap"> • ControlTemplate 定义控件的 视觉结构 和 行为(替换 WPF 控件的默认外观) • Template 通过 Style 的 Setter 或直接在控件上设置 Template 属性来应用 • ContentPresenter —— 用于显示 Button/ContentControl 中 Content 属性的占位符 • ItemsPresenter —— 用于 ItemsControl(如 ListBox)显示项集合 • PART_ 命名约定 —— 模板中的关键元素命名(如 PART_Track),控件代码会通过此名称查找 • Trigger / DataTrigger / MultiTrigger —— 根据属性值切换视觉效果 • Trigger.EnterActions / ExitActions —— 运行动画 Storyboard • TemplateBinding —— 将模板元素的属性绑定到控件的依赖属性 </TextBlock> </StackPanel> </Border>

显示的是乱的:

改成:<Run Text=""/><LineBreak />

<TextBlock Foreground="#ccc" FontSize="14"> <Run Text="ControlTemplate 定义控件的视觉结构和行为(替换 WPF 控件的默认外观)" /><LineBreak /> <Run Text="Template 通过 Style 的 Setter 或直接在控件上设置 Template 属性来应用" /><LineBreak /> <Run Text="ContentPresenter: 用于显示 Button/ContentControl 中 Content 属性的占位符" /><LineBreak /> <Run Text="ItemsPresenter: 用于 ItemsControl(如 ListBox)显示项集合" /><LineBreak /> <Run Text="PART_ 命名约定: 模板中的关键元素命名(如 PART_Track),控件代码会通过此名称查找" /><LineBreak /> <Run Text="Trigger / DataTrigger / MultiTrigger: 根据属性值切换视觉效果" /><LineBreak /> <Run Text="Trigger.EnterActions / ExitActions: 运行动画 Storyboard" /><LineBreak /> <Run Text="TemplateBinding: 将模板元素的属性绑定到控件的依赖属性" /> </TextBlock>

就变成一行一行显示了

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询