内容控件
单一内容控件的核心是通过
Content属性承载单个内容(文本、UI 元素、自定义对象),并可通过ContentTemplate自定义渲染逻辑。下面结合实际开发场景,讲解最常用的 8 种单一内容控件的具体用法、核心特性和最佳实践。
一、Button(按钮)—— 最常用的交互型内容控件
核心特性
- 支持点击事件、命令绑定;
- Content 可放任意内容(文本、图标 + 文本、复杂 UI);
- 内置视觉状态(Hover/Press/Disabled)。
实战用法
1. 基础文本按钮
1 <!-- 最简用法:仅文本 --> 2 <Button 3 Width="100" 4 Height="36" 5 Content="确定" 6 Click="BtnConfirm_Click" 7 Margin="5"/> 8 9 <!-- 带样式的文本按钮(Fluent Design风格) --> 10 <Button 11 Width="100" 12 Height="36" 13 Content="取消" 14 Background="#F5F5F5" 15 BorderBrush="#E0E0E0" 16 CornerRadius="8" 17 Margin="5"> 18 <Button.Style> 19 <Style TargetType="Button"> 20 <Style.Triggers> 21 <Trigger Property="IsMouseOver" Value="True"> 22 <Setter Property="Background" Value="#E8E8E8"/> 23 </Trigger> 24 </Style.Triggers> 25 </Style> 26 </Button.Style> 27 </Button>
2. 图标 + 文本按钮(实际开发高频)
1 <!-- 引用MaterialDesignInXAML库(NuGet安装) --> 2 <Button Width="120" Height="36" CornerRadius="8" Margin="5"> 3 <!-- Content:StackPanel包含图标+文本 --> 4 <StackPanel Orientation="Horizontal" HorizontalAlignment="Center"> 5 <materialDesign:PackIcon Kind="Save" Width="16" Height="16" Margin="0 0 5 0"/> 6 <TextBlock Text="保存文件"/> 7 </StackPanel> 8 </Button>
3. 绑定命令(MVVM 模式)
1 // ViewModel中定义命令(使用CommunityToolkit.MVVM) 2 public ICommand SaveCommand => new RelayCommand(SaveAction); 3 private void SaveAction() 4 { 5 // 保存逻辑 6 }
1 <Button 2 Content="保存" 3 Command="{Binding SaveCommand}" 4 CommandParameter="{Binding SelectedFile}"/>
二、Label(标签)—— 带关联功能的文本控件
核心特性
- 轻量文本展示,支持
Target关联输入控件(点击 Label 聚焦对应控件); - 支持访问键(如
_用户名,按 Alt+U 聚焦目标)。
实战用法
1. 基础标签 + 关联输入控件
1 <Grid Width="300" Margin="5" ColumnDefinitions="80,*"> 2 <!-- Label关联TextBox,点击Label聚焦TextBox --> 3 <Label 4 Grid.Column="0" 5 Content="_用户名:" <!-- 访问键:Alt+U --> 6 Target="{Binding ElementName=txtUserName}" 7 HorizontalAlignment="Right" 8 VerticalAlignment="Center"/> 9 10 <TextBox 11 x:Name="txtUserName" 12 Grid.Column="1" 13 Margin="5 0 0 0" 14 PlaceholderText="请输入用户名"/> 15 </Grid>
2. 带样式的标签(区分必填项)
1 <Label Content="密码:" Margin="5"> 2 <Label.Style> 3 <Style TargetType="Label"> 4 <Setter Property="Foreground" Value="Black"/> 5 <Style.Triggers> 6 <!-- 绑定ViewModel的IsRequired属性,标记必填项 --> 7 <DataTrigger Binding="{Binding IsPwdRequired}" Value="True"> 8 <Setter Property="Foreground" Value="Red"/> 9 <Setter Property="Content" Value="密码*:"/> 10 </DataTrigger> 11 </Style.Triggers> 12 </Style> 13 </Label.Style> 14 </Label>
三、GroupBox(分组容器)—— 带标题的内容分组控件
核心特性
- 继承
HeaderedContentControl,有Header(标题)+Content(内容)双分区; - 自带边框,适合表单分组。
实战用法
1 <GroupBox 2 Width="350" 3 Height="200" 4 Header="用户基本信息" <!-- 标题 --> 5 Margin="5"> 6 <!-- Content:表单布局 --> 7 <StackPanel Padding="10"> 8 <Grid ColumnDefinitions="80,*" Margin="0 0 0 5"> 9 <Label Content="姓名:" Grid.Column="0" VerticalAlignment="Center"/> 10 <TextBox Grid.Column="1" PlaceholderText="请输入姓名"/> 11 </Grid> 12 <Grid ColumnDefinitions="80,*" Margin="0 5 0 0"> 13 <Label Content="年龄:" Grid.Column="0" VerticalAlignment="Center"/> 14 <TextBox Grid.Column="1" PlaceholderText="请输入年龄"/> 15 </Grid> 16 <Button Content="保存" Width="80" Margin="0 10 0 0" HorizontalAlignment="Left"/> 17 </StackPanel> 18 </GroupBox>
四、Expander(可展开 / 折叠容器)—— 动态展示内容
核心特性
- 继承
HeaderedContentControl,支持IsExpanded控制展开 / 折叠; - 适合展示 “可选看” 的内容(如高级筛选、详情信息)。
实战用法
1 <Expander 2 Width="350" 3 Header="高级筛选条件" 4 IsExpanded="False" <!-- 默认折叠 --> 5 Margin="5"> 6 <!-- Content:折叠/展开的内容 --> 7 <StackPanel Padding="10"> 8 <CheckBox Content="仅显示已完成" Margin="0 0 0 5"/> 9 <CheckBox Content="按时间排序" Margin="0 5 0 0"/> 10 <DatePicker Margin="0 5 0 0" PlaceholderText="开始时间"/> 11 <DatePicker Margin="0 5 0 0" PlaceholderText="结束时间"/> 12 </StackPanel> 13 </Expander>
五、Window(窗口)—— 顶级内容控件
核心特性
- 应用的顶级控件,Content 为窗口主体内容;
- 支持标题、大小、样式、窗口状态(最大化 / 最小化)。
实战用法
1 <Window 2 x:Class="WpfDemo.MainWindow" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 Title="WPF内容控件示例" 6 Width="800" 7 Height="600" 8 WindowStartupLocation="CenterScreen"> 9 10 <!-- Window的Content:整个窗口的内容(Grid布局) --> 11 <Grid> 12 <Grid.RowDefinitions> 13 <RowDefinition Height="Auto"/> 14 <RowDefinition Height="*"/> 15 </Grid.RowDefinitions> 16 17 <!-- 标题栏 --> 18 <StackPanel Grid.Row="0" Orientation="Horizontal" Background="#0078D7" Padding="10"> 19 <TextBlock Text="系统管理" FontSize="16" Foreground="White"/> 20 </StackPanel> 21 22 <!-- 主体内容 --> 23 <Grid Grid.Row="1" Padding="10"> 24 <!-- 放置其他控件 --> 25 <Button Content="操作按钮" HorizontalAlignment="Left" VerticalAlignment="Top"/> 26 </Grid> 27 </Grid> 28 </Window>
六、UserControl(自定义复合控件)—— 业务控件容器
核心特性
- 作为自定义业务控件的载体,Content 为控件内部布局;
- 可封装复用性高的业务组件(如表单、列表项、工具栏)。
实战用法
1. 创建 UserControl(UserInfoControl.xaml)
1 <UserControl 2 x:Class="WpfDemo.UserInfoControl" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 Width="300" 6 Height="150"> 7 8 <!-- UserControl的Content:内部布局 --> 9 <Border Background="#F8F8F8" CornerRadius="8" Padding="10"> 10 <StackPanel> 11 <TextBlock x:Name="txtName" FontSize="14" FontWeight="Bold"/> 12 <TextBlock x:Name="txtAge" Margin="0 5 0 0"/> 13 <TextBlock x:Name="txtPhone" Margin="0 5 0 0"/> 14 </StackPanel> 15 </Border> 16 </UserControl>
2. 后台绑定数据(UserInfoControl.xaml.cs)
1 public partial class UserInfoControl : UserControl 2 { 3 // 定义依赖属性,支持数据绑定 4 public static readonly DependencyProperty UserProperty = 5 DependencyProperty.Register( 6 nameof(User), 7 typeof(UserInfo), 8 typeof(UserInfoControl), 9 new PropertyMetadata(null, OnUserChanged)); 10 11 public UserInfo User 12 { 13 get => (UserInfo)GetValue(UserProperty); 14 set => SetValue(UserProperty, value); 15 } 16 17 private static void OnUserChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 18 { 19 var control = (UserInfoControl)d; 20 var user = (UserInfo)e.NewValue; 21 if (user != null) 22 { 23 control.txtName.Text = user.Name; 24 control.txtAge.Text = $"年龄:{user.Age}"; 25 control.txtPhone.Text = $"电话:{user.Phone}"; 26 } 27 } 28 29 public UserInfoControl() 30 { 31 InitializeComponent(); 32 } 33 }
3. 使用 UserControl
1 <!-- 在窗口中引用自定义UserControl --> 2 <Window ...> 3 <Grid> 4 <local:UserInfoControl 5 User="{Binding SelectedUser}" <!-- 绑定数据 --> 6 HorizontalAlignment="Center" 7 VerticalAlignment="Center"/> 8 </Grid> 9 </Window>
七、ScrollViewer(滚动容器)—— 包裹超出尺寸的内容
核心特性
- 当 Content 超出容器尺寸时,自动显示滚动条;
- 支持水平 / 垂直滚动,可控制滚动条可见性。
实战用法
1 <!-- 包裹长列表,仅垂直滚动 --> 2 <ScrollViewer 3 Width="300" 4 Height="200" 5 VerticalScrollBarVisibility="Auto" <!-- 内容超出时显示垂直滚动条 --> 6 HorizontalScrollBarVisibility="Disabled" <!-- 禁用水平滚动 --> 7 Margin="5"> 8 9 <!-- Content:长内容(StackPanel包含多个项) --> 10 <StackPanel> 11 <TextBlock Text="列表项1" Margin="5"/> 12 <TextBlock Text="列表项2" Margin="5"/> 13 <TextBlock Text="列表项3" Margin="5"/> 14 <TextBlock Text="列表项4" Margin="5"/> 15 <TextBlock Text="列表项5" Margin="5"/> 16 <TextBlock Text="列表项6" Margin="5"/> 17 <TextBlock Text="列表项7" Margin="5"/> 18 <TextBlock Text="列表项8" Margin="5"/> 19 <TextBlock Text="列表项9" Margin="5"/> 20 <TextBlock Text="列表项10" Margin="5"/> 21 </StackPanel> 22 </ScrollViewer>
八、ContentControl(基础内容控件)—— 通用内容展示
核心特性
- 最基础的单一内容控件,无额外交互逻辑;
- 适合纯展示型内容(如数据详情、动态模板切换)。
实战用法(展示自定义数据对象)
1 // 数据模型 2 public class ProductInfo 3 { 4 public string Name { get; set; } 5 public decimal Price { get; set; } 6 public string Description { get; set; } 7 } 8 9 // 窗口后台赋值 10 public MainWindow() 11 { 12 InitializeComponent(); 13 productContentControl.Content = new ProductInfo 14 { 15 Name = "WPF实战教程", 16 Price = 99.9m, 17 Description = "详细讲解WPF内容控件的使用技巧" 18 }; 19 }
1 <!-- 通用ContentControl展示数据对象 --> 2 <ContentControl 3 x:Name="productContentControl" 4 Width="350" 5 Height="200" 6 Background="#F5F5F5" 7 Padding="10" 8 Margin="5"> 9 10 <!-- ContentTemplate:定义数据渲染方式 --> 11 <ContentControl.ContentTemplate> 12 <DataTemplate> 13 <StackPanel> 14 <TextBlock 15 Text="{Binding Name}" 16 FontSize="16" 17 FontWeight="Bold" 18 Foreground="#0078D7"/> 19 <TextBlock 20 Text="{Binding Price, StringFormat='价格:¥{0:F2}'}" 21 Margin="0 5 0 0"/> 22 <TextBlock 23 Text="{Binding Description}" 24 Margin="0 5 0 0" 25 TextWrapping="Wrap"/> 26 </StackPanel> 27 </DataTemplate> 28 </ContentControl.ContentTemplate> 29 </ContentControl>
九、单一内容控件通用最佳实践
1. 内容嵌套规则
- 单一内容控件只能放一个直接子元素,但这个子元素可以是
Grid/StackPanel等布局控件(包含多个元素); - 错误示例:
<Button><TextBlock>1</TextBlock><TextBlock>2</TextBlock></Button>(多个直接子元素,编译报错); - 正确示例:
<Button><StackPanel><TextBlock>1</TextBlock><TextBlock>2</TextBlock></StackPanel></Button>。
2. 性能优化
- 纯文本展示优先用
TextBlock(轻量),而非Label/Button; - 复杂 Content(如包含多个控件)尽量通过
ContentTemplate绑定数据,而非手动拼接 UI; - 避免过度嵌套(如 Button→Grid→StackPanel→TextBlock,可简化为 Button→TextBlock)。
3. 样式统一
- 通过
Style定义全局样式,确保同类型控件外观一致:
<Window.Resources>
<Style TargetType="Button" x:Key="DefaultButton">
<Setter Property="Width" Value="100"/>
<Setter Property="Height" Value="36"/>
<Setter Property="CornerRadius" Value="8"/>
<Setter Property="Background" Value="#0078D7"/>
<Setter Property="Foreground" Value="White"/>
</Style>
</Window.Resources>
<!-- 使用全局样式 -->
<Button Style="{StaticResource DefaultButton}" Content="确定"/>
总结
- 单一内容控件(ContentControl)核心是
Content属性,可承载文本、UI 元素、自定义对象,不同控件有专属特性(Button 支持点击、Expander 支持折叠、Window 是顶级容器); - 高频用法:Button(图标 + 文本 / 命令绑定)、GroupBox(表单分组)、Expander(折叠内容)、UserControl(自定义业务控件)、ContentControl(通用数据展示);
- 通用规则:单一内容控件仅支持一个直接子元素(可嵌套布局控件),优先通过模板绑定数据,避免过度嵌套以优化性能。
掌握这些常用单一内容控件的用法,就能覆盖 WPF 桌面应用中 80% 以上的内容展示和交互场景。
浙公网安备 33010602011771号