显示页面讨论反向链接回到顶部 本页面只读。您可以查看源文件,但不能更改它。如果您觉得这是系统错误,请联系管理员。 ====== WPF 控件与模板深度指南 ====== WPF (Windows Presentation Foundation) 的核心哲学是 **UI 与逻辑分离** 以及 **Lookless Control(无外观控件)**。这意味着控件的行为(如点击)与它的外观(长方形还是圆形)是完全解耦的。 本指南将详细讲解常用控件分类,并深入剖析核心机制:**模板 (Templates)**。 ===== 1. 常用控件分类体系 ===== 理解控件的父类有助于理解如何使用它们的内容属性。 ==== 1.1 布局控件 (Layout Controls) ==== 用于管理子元素的位置和大小。 ^ 控件名 ^ 用途 ^ 关键属性 ^ | **Grid** | 最强大的布局,通过行(Row)和列(Column)定位 | `RowDefinitions`, `ColumnDefinitions` | | **StackPanel** | 简单的堆叠布局(水平或垂直) | `Orientation` (Horizontal/Vertical) | | **WrapPanel** | 流式布局,空间不足时自动换行 | `Orientation` | | **DockPanel** | 停靠布局,将元素停靠在上下左右 | `DockPanel.Dock` (LastChildFill) | <code xml> <!-- Grid 示例 --> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <!-- 自适应高度 --> <RowDefinition Height="*"/> <!-- 占用剩余空间 --> </Grid.RowDefinitions> <Button Grid.Row="0" Content="顶部按钮"/> <StackPanel Grid.Row="1"> <TextBlock Text="列表内容..."/> </StackPanel> </Grid> </code> ==== 1.2 内容控件 (Content Controls) ==== **特点**:只能包含**一个**子元素。 **基类**:`System.Windows.Controls.ContentControl` **核心属性**:`Content` * **常见控件**:`Button`, `CheckBox`, `Label`, `ScrollViewer`, `Window`, `UserControl`。 * **用法**:`Content` 属性不仅可以是字符串,还可以是复杂的布局面板。 <code xml> <Button> <Button.Content> <!-- 按钮内部包含图片和文字 --> <StackPanel Orientation="Horizontal"> <Image Source="icon.png" Width="16"/> <TextBlock Text="提交订单" Margin="5,0,0,0"/> </StackPanel> </Button.Content> </Button> </code> 点击[[https://www.tutorialspoint.com/wpf/wpf_datagrid.htm|这里]]查看 wpf控件的基本信息 ==== 1.3 条目控件 (Items Controls) ==== **特点**:包含**多个**子元素,通常用于显示集合数据。 **基类**:`System.Windows.Controls.ItemsControl` **核心属性**:`ItemsSource` (绑定数据源) 或 `Items` (手动添加)。 * **常见控件**:`ListBox`, `ListView`, `ComboBox`, `DataGrid`, `TreeView`。 ===== 2. 核心机制:模板 (Templates) ===== 这是 WPF 最强大也是最难的部分。模板决定了控件“长什么样”。 ==== 2.1 DataTemplate (数据模板) ==== **定义**:决定**数据对象**如何显示在 UI 上。 **适用场景**:当你绑定一个 `List<Person>` 到 `ListBox` 时,默认显示的是 `Person.ToString()`。使用 DataTemplate 可以将其显示为“姓名+头像”。 **关键属性**: * `ItemTemplate` (用于 ItemsControl) * `ContentTemplate` (用于 ContentControl) <code xml> <!-- 假设数据源是 List<Student>,包含 Name 和 Score 属性 --> <ListBox ItemsSource="{Binding Students}"> <ListBox.ItemTemplate> <DataTemplate> <!-- 这里定义每一行数据的视觉结构 --> <Border BorderBrush="LightGray" BorderThickness="0,0,0,1" Padding="5"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"/> <ColumnDefinition Width="Auto"/> </Grid.ColumnDefinitions> <!-- 绑定 Name 属性 --> <TextBlock Text="{Binding Name}" FontWeight="Bold" FontSize="14"/> <!-- 绑定 Score 属性,并根据分数变色(通常配合 Converter,此处简化) --> <TextBlock Grid.Column="1" Text="{Binding Score}" Foreground="Red"/> </Grid> </Border> </DataTemplate> </ListBox.ItemTemplate> </ListBox> </code> ==== 2.2 ControlTemplate (控件模板) ==== **定义**:决定**控件本身**的结构和外观。 **适用场景**:将方形按钮改成圆形按钮,或者重写 CheckBox 的勾选样式。 **核心概念**: - **TargetType**:指定模板应用于哪个控件。 - **TemplateBinding**:将模板内的属性绑定到控件对外的属性(如将模板内的矩形颜色绑定到 Button 的 Background)。 - **ContentPresenter**:**至关重要**。它是占位符,用来显示控件的 `Content`。如果不写它,按钮上的文字就会消失。 - **Triggers (触发器)**:在模板内部处理交互(如鼠标悬停变色)。 <code xml> <!-- 定义一个圆角按钮样式 --> <Style x:Key="RoundButtonStyle" TargetType="Button"> <Setter Property="Background" Value="#007ACC"/> <Setter Property="Foreground" Value="White"/> <Setter Property="Template"> <Setter.Value> <!-- 重写控件模板 --> <ControlTemplate TargetType="Button"> <!-- 1. 外观结构:一个圆角矩形 --> <Border x:Name="border" Background="{TemplateBinding Background}" CornerRadius="20" BorderThickness="0" Padding="10,5"> <!-- 2. 内容占位符:显示按钮上的文字 --> <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/> </Border> <!-- 3. 触发器:处理交互状态 --> <ControlTemplate.Triggers> <!-- 当鼠标悬停时,改变 Border 的背景色 --> <Trigger Property="IsMouseOver" Value="True"> <Setter TargetName="border" Property="Background" Value="#005A9E"/> </Trigger> <!-- 当按钮被按下时 --> <Trigger Property="IsPressed" Value="True"> <Setter TargetName="border" Property="Background" Value="#004578"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> <!-- 使用该样式 --> <Button Content="点击我" Style="{StaticResource RoundButtonStyle}" Width="100" Height="40"/> </code> ==== 2.3 ItemsPanelTemplate (面板模板) ==== **定义**:决定 ItemsControl 内部用来**排列**子元素的容器。 **适用场景**:`ListBox` 默认是垂直排列的,如果你想让它横向排列(像相册一样),就需要修改 ItemsPanel。 <code xml> <ListBox ItemsSource="{Binding Images}"> <!-- 修改布局容器为 WrapPanel (自动换行) --> <ListBox.ItemsPanel> <ItemsPanelTemplate> <WrapPanel Orientation="Horizontal" IsItemsHost="True"/> </ItemsPanelTemplate> </ListBox.ItemsPanel> <!-- 定义每一项长什么样 --> <ListBox.ItemTemplate> <DataTemplate> <Image Source="{Binding Path}" Width="100" Height="100" Margin="5"/> </DataTemplate> </ListBox.ItemTemplate> </ListBox> </code> ===== 3. 样式与触发器 (Styles & Triggers) ===== 模板通常包裹在 `Style` 中以便复用。 ==== 3.1 Style (样式) ==== 类似于 HTML 的 CSS。用于批量设置属性。 <code xml> <Style TargetType="TextBlock" x:Key="HeaderStyle"> <Setter Property="FontSize" Value="24"/> <Setter Property="FontWeight" Value="Bold"/> <Setter Property="Foreground" Value="#333333"/> </Style> </code> ==== 3.2 Triggers (触发器) ==== WPF 的触发器允许你在不写 C# 代码的情况下响应 UI 变化。 * **PropertyTrigger**: 当某个属性值变化时触发(如 `IsMouseOver`)。 * **DataTrigger**: 当绑定的数据值变化时触发(如 `Binding Status` == "Error")。 * **EventTrigger**: 当事件发生时触发(通常用于动画)。 <code xml> <!-- DataTrigger 示例:根据数据状态改变颜色 --> <DataTemplate> <TextBlock Text="{Binding Status}"> <TextBlock.Style> <Style TargetType="TextBlock"> <Setter Property="Foreground" Value="Green"/> <!-- 默认绿色 --> <Style.Triggers> <DataTrigger Binding="{Binding Status}" Value="Error"> <Setter Property="Foreground" Value="Red"/> <!-- 出错变红 --> </DataTrigger> </Style.Triggers> </Style> </TextBlock.Style> </TextBlock> </DataTemplate> </code> ===== 4. 总结:模板选择指南 ===== | 你的需求 | 你需要修改的属性 | 对应的模板类型 | | 我想改变列表里**每一行数据显示的样子**(加图片、改排版) | `ItemTemplate` | **DataTemplate** | | 我想改变按钮的**形状**(圆角、不规则)或交互特效 | `Template` | **ControlTemplate** | | 我想改变列表项的**排列方式**(从垂直变成横向流式) | `ItemsPanel` | **ItemsPanelTemplate** | | 我想改变按钮里**内容的显示方式**(不只是文字,要加图标) | `ContentTemplate` | **DataTemplate** | 登录 Detach Close 该主题尚不存在 您访问的页面并不存在。如果允许,您可以使用创建该页面按钮来创建它。 csharp/wpf控件和模板.txt 最后更改: 2025/12/15 14:49由 张叶安 登录