csharp:wpf控件和模板

WPF 控件与模板深度指南

WPF (Windows Presentation Foundation) 的核心哲学是 UI 与逻辑分离 以及 Lookless Control(无外观控件)。这意味着控件的行为(如点击)与它的外观(长方形还是圆形)是完全解耦的。

本指南将详细讲解常用控件分类,并深入剖析核心机制:模板 (Templates)

理解控件的父类有助于理解如何使用它们的内容属性。

用于管理子元素的位置和大小。

控件名 用途 关键属性
Grid 最强大的布局,通过行(Row)和列(Column)定位 `RowDefinitions`, `ColumnDefinitions`
StackPanel 简单的堆叠布局(水平或垂直) `Orientation` (Horizontal/Vertical)
WrapPanel 流式布局,空间不足时自动换行 `Orientation`
DockPanel 停靠布局,将元素停靠在上下左右 `DockPanel.Dock` (LastChildFill)
<!-- Grid 示例 -->
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/> <!-- 自适应高度 -->
        <RowDefinition Height="*"/>    <!-- 占用剩余空间 -->
    </Grid.RowDefinitions>
 
    <Button Grid.Row="0" Content="顶部按钮"/>
    <StackPanel Grid.Row="1">
        <TextBlock Text="列表内容..."/>
    </StackPanel>
</Grid>

特点:只能包含一个子元素。 基类:`System.Windows.Controls.ContentControl` 核心属性:`Content`

  • 常见控件:`Button`, `CheckBox`, `Label`, `ScrollViewer`, `Window`, `UserControl`。
  • 用法:`Content` 属性不仅可以是字符串,还可以是复杂的布局面板。
<Button>
    <Button.Content>
        <!-- 按钮内部包含图片和文字 -->
        <StackPanel Orientation="Horizontal">
            <Image Source="icon.png" Width="16"/>
            <TextBlock Text="提交订单" Margin="5,0,0,0"/>
        </StackPanel>
    </Button.Content>
</Button>

点击这里查看 wpf控件的基本信息

特点:包含多个子元素,通常用于显示集合数据。 基类:`System.Windows.Controls.ItemsControl` 核心属性:`ItemsSource` (绑定数据源) 或 `Items` (手动添加)。

* 常见控件:`ListBox`, `ListView`, `ComboBox`, `DataGrid`, `TreeView`。

这是 WPF 最强大也是最难的部分。模板决定了控件“长什么样”。

定义:决定数据对象如何显示在 UI 上。 适用场景:当你绑定一个 `List<Person>` 到 `ListBox` 时,默认显示的是 `Person.ToString()`。使用 DataTemplate 可以将其显示为“姓名+头像”。

关键属性

  • `ItemTemplate` (用于 ItemsControl)
  • `ContentTemplate` (用于 ContentControl)
<!-- 假设数据源是 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>

定义:决定控件本身的结构和外观。 适用场景:将方形按钮改成圆形按钮,或者重写 CheckBox 的勾选样式。

核心概念

  1. TargetType:指定模板应用于哪个控件。
  2. TemplateBinding:将模板内的属性绑定到控件对外的属性(如将模板内的矩形颜色绑定到 Button 的 Background)。
  3. ContentPresenter至关重要。它是占位符,用来显示控件的 `Content`。如果不写它,按钮上的文字就会消失。
  4. Triggers (触发器):在模板内部处理交互(如鼠标悬停变色)。
<!-- 定义一个圆角按钮样式 -->
<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"/>

定义:决定 ItemsControl 内部用来排列子元素的容器。 适用场景:`ListBox` 默认是垂直排列的,如果你想让它横向排列(像相册一样),就需要修改 ItemsPanel。

<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>

模板通常包裹在 `Style` 中以便复用。

类似于 HTML 的 CSS。用于批量设置属性。

<Style TargetType="TextBlock" x:Key="HeaderStyle">
    <Setter Property="FontSize" Value="24"/>
    <Setter Property="FontWeight" Value="Bold"/>
    <Setter Property="Foreground" Value="#333333"/>
</Style>

WPF 的触发器允许你在不写 C# 代码的情况下响应 UI 变化。

  • PropertyTrigger: 当某个属性值变化时触发(如 `IsMouseOver`)。
  • DataTrigger: 当绑定的数据值变化时触发(如 `Binding Status` == “Error”)。
  • EventTrigger: 当事件发生时触发(通常用于动画)。
<!-- 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>
你的需求 你需要修改的属性 对应的模板类型
我想改变列表里每一行数据显示的样子(加图片、改排版) `ItemTemplate` DataTemplate
我想改变按钮的形状(圆角、不规则)或交互特效 `Template` ControlTemplate
我想改变列表项的排列方式(从垂直变成横向流式) `ItemsPanel` ItemsPanelTemplate
我想改变按钮里内容的显示方式(不只是文字,要加图标) `ContentTemplate` DataTemplate
请输入您的评论. 可以使用维基语法:
 

该主题尚不存在

您访问的页面并不存在。如果允许,您可以使用创建该页面按钮来创建它。

  • csharp/wpf控件和模板.txt
  • 最后更改: 2025/12/15 14:49
  • 张叶安