WPF 入门教程(二)

23 次查看
# 四.内容控件
## 1.Control基类
WPF中的Control类是构建交互式控件(如Button、TextBox等)的核心基类,支持模板化和样式主题。

### 1.1 Control类的核心特性
#### ​1.1.1 模板化

通过ControlTemplate自定义控件外观(如圆角按钮)

#### 1.1.2 内容模型

Content属性支持任意对象(如Button可包含图像或文本)

#### 1.1.3 样式与主题

集成系统主题,支持Style和Trigger实现动态样式

#### 1.1.4 基础属性

Background/Foreground(画刷)、FontFamily/FontSize(文本格式)、BorderThickness(边框)

### 1.2 简单使用

```xml
<Window x:Class="TestWpfApp.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:TestWpfApp"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Control>
            <Control.Template>
                <ControlTemplate>
                    <Border Width="200" Height="42" CornerRadius="5" BorderThickness="1" BorderBrush="Gray" Padding="5">
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition/>
                                <ColumnDefinition Width="Auto"/>
                            </Grid.ColumnDefinitions>
                            <TextBox BorderThickness="0" VerticalContentAlignment="Center"/>
                            <TextBlock Text="🔍" Grid.Column="1" VerticalAlignment="Center"/>
                        </Grid>
                    </Border>
                </ControlTemplate>
            </Control.Template>
        </Control>
    </Grid>
  
</Window>
```
![](https://www.diandiandidi.club:12346/api/note/getImage/10/c487e926-e725-41a9-87a8-b1ad11b0ca9b-.png)
## 2.ContentControl基类
用于承载和显示单一内容对象,作为Control的直接子类,它扩展了内容模型能力,是按钮(Button)、标签(Label)等交互控件的基类。

## 3.Button按钮
### 3.1 基础概念
用于点击的用户交互控件

​​继承关系​​:DispatcherObject → DependencyObject → Visual → UIElement → FrameworkElement → Control → ButtonBase → Button

核心功能​​:

- 用户交互触发操作
- 支持内容自定义
- 支持命令绑定(MVVM模式) *

### 3.2 基本用法

```xml
<Button Content="按钮一" Width="80" Height="36" Click="Button_Click"/>
<Button Width="80" Height="36">
      <StackPanel Orientation="Horizontal">
           <TextBlock Text="📂"/>
           <Separator Width="1" Margin="5,0"/>
           <TextBlock Text="打开"/>
      </StackPanel>
</Button>
```




```c#
using System.Windows;

namespace TestWpfApp
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            MessageBox.Show("Hello, World!");
        }
    }
}
```


### 3.3 核心属性
#### 3.3.1 内容属性
|属性	|说明	|示例|
|-|-|-|
|Content|	按钮显示内容|	`<Button Content="提交"/>`|
|ContentTemplate	|内容显示模板	|`<Button.ContentTemplate><DataTemplate>...</DataTemplate></Button.ContentTemplate>`|

#### 3.3.2 外观属性
|属性	|说明	|常用值|
|-|-|-|
|Background	|背景色	|"Red", "#FFFF0000"|
|Foreground	|前景色	|"White", "#FFFFFFFF"|
|BorderBrush	|边框颜色|	"Black"|
|BorderThickness	|边框粗细|	"1", "2,2,2,2"|
|Padding	|内边距	|"5", "10,5,10,5"|
|Font系列	|字体设置	|FontSize="14", FontWeight="Bold"|

#### 3.3.3 交互属性
|属性	|说明	|示例|
|-|-|-|
|IsEnabled	|是否可用	|IsEnabled="False"|
|IsDefault	|默认按钮(响应Enter)	|IsDefault="True"|
|IsCancel	|取消按钮(响应Esc)	|IsCancel="True"|
|ClickMode	|点击触发方式	|Press/Release/Hover|

### 3.4 事件处理
|事件	|类型	|说明|
|-|-|-|
|Click|路由事件|	按钮点击事件|
|PreviewMouseDown	|隧道事件|	鼠标按下前触发|
|MouseDown	|冒泡事件|	鼠标按下时触发|
|PreviewMouseUp	|隧道事件	|鼠标释放前触发|
|MouseUp	|冒泡事件	|鼠标释放时触发|

### 3.5 高级用法 *
带有圆角、状态改变、图标的按钮

```xml
<Button Width="120" Height="36" Padding="5" Click="OpenFolder_Click">
    <Button.Template>
        <ControlTemplate TargetType="Button">
            <Border Cursor="Hand" Padding="{TemplateBinding Padding}" CornerRadius="5" BorderThickness="1" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}">
                <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
            </Border>
        </ControlTemplate>
    </Button.Template>
    <Button.Style>
        <Style TargetType="Button">
            <Setter Property="Background" Value="White"/>
            <Setter Property="BorderBrush" Value="Black"/>
            <Setter Property="Foreground" Value="Black"/>
            <Setter Property="FontSize" Value="16"/>
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="Background" Value="LightGray"/>
                </Trigger>
                <Trigger Property="IsPressed" Value="True">
                    <Setter Property="Background" Value="Gray"/>
                </Trigger>
            </Style.Triggers>
        </Style>
    </Button.Style>
    <Button.Content>
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <Image Source="/Resources/Images/icon_folder.png"/>
            <TextBlock Text="打开目录" Grid.Column="1" VerticalAlignment="Center" Margin="5,0,0,0"/>
        </Grid>
    </Button.Content>
</Button>
```
![](https://www.diandiandidi.club:12346/api/note/getImage/10/9f1f7308-dc2e-49c6-aa31-74a6630639ee-.png)
![](https://www.diandiandidi.club:12346/api/note/getImage/10/a4f77013-8a9a-4e8c-aa97-83c3275a6231-.png)

### 3.6 MessageBox 使用
MessageBox 是 WPF 中用于显示简单对话框的系统组件,常用于提示、确认和获取用户简单反馈。

#### 3.6.1 基础用法
简单消息提示

```c#
MessageBox.Show("操作已完成!");
```

带标题的消息框


```c#
MessageBox.Show("文件保存成功", "系统提示");
```

带按钮的消息框


```c#
MessageBox.Show("确定要删除吗?", "确认删除", MessageBoxButton.YesNo);
```

#### 3.6.2 MessageBoxButton 枚举
|值	|显示的按钮|
|-|-|
|OK	|确定|
|OKCancel|	确定/取消|
|YesNo|	是/否|
|YesNoCancel|	是/否/取消|

#### 3.6.3 MessageBoxImage 枚举

```c#
MessageBox.Show("磁盘空间不足", "警告", 
                MessageBoxButton.OK, 
                MessageBoxImage.Warning);
```

常用图标类型:

- None - 无图标
- Error - 错误(红色X)
- Question - 问号
- Warning - 感叹号
- Information - 信息(i图标)

#### 3.6.4 MessageBoxResult 返回值

```c#
MessageBoxResult result = MessageBox.Show("继续操作吗?", 
                                         "确认",
                                         MessageBoxButton.YesNoCancel);

switch(result)
{
    case MessageBoxResult.Yes:
        // 用户点击"是"
        break;
    case MessageBoxResult.No:
        // 用户点击"否"
        break;
    case MessageBoxResult.Cancel:
        // 用户点击"取消"
        break;
}
```

#### 3.6.5 设置默认按钮

```c#
MessageBox.Show("确认提交吗?", 
               "请确认",
               MessageBoxButton.YesNo,
               MessageBoxImage.Question,
               MessageBoxResult.No); // 默认选中"否"
```

#### 3.6.6 自定义窗口所有者

```c#
// 确保消息框显示在主窗口上方
MessageBox.Show(Application.Current.MainWindow,
               "这是一个重要提示",
               "系统消息");
```

## 4.CheckBox 复选框
CheckBox 是 WPF 中常用的选择控件,允许用户在两种或三种状态间切换。

### 4.1 核心属性
|属性|	类型|	说明	|示例值|
|-|-|-|-|
|IsChecked	|bool?	|选中状态(true/false/null)|	True, False, Null|
|IsThreeState|	bool|	是否允许第三种状态	|True, False|
|Content	|object|	显示内容|	"选项1", <Image>等|
|ContentTemplate	|DataTemplate	|内容模板	|自定义数据模板|

### 4.2 状态类型
- 选中(true)
- 未选中(false)
- 不确定(null)

### 4.3 简单使用

```xml
<Window x:Class="TestWpfApp.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:TestWpfApp"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <StackPanel Orientation="Vertical" HorizontalAlignment="Center" VerticalAlignment="Center">
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="请选择爱好:"/>
                <StackPanel Orientation="Horizontal" x:Name="hobbyStackPanel">
                    <CheckBox Content="唱歌" IsChecked="True" Checked="CheckBox_Checked"/>
                    <CheckBox Content="跳舞" Checked="CheckBox_Checked"/>
                    <CheckBox Content="打篮球" IsChecked="{x:Null}" Checked="CheckBox_Checked"/>
                </StackPanel>
            </StackPanel>
            <StackPanel Orientation="Horizontal">
                <Button Content="确定" Click="Confirm_Click"/>
                <Button Content="清空" Click="Clear_Click"/>
            </StackPanel>
        </StackPanel>
        
    </Grid>
</Window>
```


```c#
using System.Text;
using System.Windows;
using System.Windows.Controls;

namespace TestWpfApp
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void CheckBox_Checked(object sender, RoutedEventArgs e)
        {
           if(sender is CheckBox checkBox)
            {
                if (checkBox.IsChecked==true && checkBox.Content.Equals("打篮球"))
                {
                    MessageBox.Show("这个不让选。");
                    checkBox.IsChecked = false;
                }
            }
        }

        private void Confirm_Click(object sender, RoutedEventArgs e)
        {
            StringBuilder sb = new StringBuilder();
            foreach (var item in hobbyStackPanel.Children)
            {
                if (item is CheckBox checkBox && checkBox.IsChecked == true)
                {
                    sb.AppendLine(checkBox.Content.ToString());
                }
            }
            MessageBox.Show("你选择的爱好是:"+sb.ToString());
        }

        private void Clear_Click(object sender, RoutedEventArgs e)
        {
            foreach (var item in hobbyStackPanel.Children)
            {
                if (item is CheckBox checkBox && checkBox.IsChecked == true)
                {
                    checkBox.IsChecked = false;
                }
            }
        }
    }
}

```
![](https://www.diandiandidi.club:12346/api/note/getImage/10/38e629e8-201d-4bcd-a86f-6c2897fe875e-.png)

## 5.RadioButton 单选框
WPF中用于实现单选功能的控件,通常用于一组互斥的选项选择。

### 5.1 基础特性与用法
基本结构


```xml
<RadioButton Content="选项1" IsChecked="True"/>
<RadioButton Content="选项2"/>
<RadioButton Content="选项3"/>
```

核心属性

|属性|	类型|	说明	|示例值|
|-|-|-|-|
|IsChecked|	bool	|是否选中	|True, False|
|GroupName|string	|分组名称	|"Group1", "Group2"|
|Content	|object	|显示内容	|"男", `<Image>`等|
|ContentTemplate|	DataTemplate|	内容模板|	自定义数据模板|

### 5.2 分组机制
**1). 隐式分组(同父容器)**


```xml
<StackPanel>
    <RadioButton Content="选项A"/>
    <RadioButton Content="选项B"/> <!-- 与选项A互斥 -->
</StackPanel>
```

**2). 显式分组(GroupName)**


```xml
<RadioButton Content="红色" GroupName="Color"/>
<RadioButton Content="绿色" GroupName="Color"/> <!-- 颜色组 -->

<RadioButton Content="大号" GroupName="Size"/>
<RadioButton Content="小号" GroupName="Size"/> <!-- 尺寸组 -->
```

**3).复杂分组示例**


```xml
<StackPanel>
    <GroupBox Header="颜色选择">
        <RadioButton Content="红色" GroupName="Color"/>
        <RadioButton Content="蓝色" GroupName="Color"/>
    </GroupBox>
    
    <GroupBox Header="尺寸选择">
        <RadioButton Content="大号" GroupName="Size"/>
        <RadioButton Content="小号" GroupName="Size"/>
    </GroupBox>
</StackPanel>
```

### 5.3 事件处理
|事件|	触发时机|
|-|-|
|Checked	|被选中时触发|
|Unchecked	|取消选中时触发|
|Click|	点击时触发|

## 6.RepeatButton 重复按钮
RepeatButton 是 WPF 中的一个特殊按钮控件,它在用户按住按钮时会重复触发点击事件,适合实现增减按钮、滚动控制等需要连续操作的功能。

### 6.1 与普通 Button 的区别
|特性	|Button	|RepeatButton|
|-|-|-|
|触发方式	|点击一次触发一次	|按住时重复触发|
|首次触发延迟|	无|	有初始延迟|
|重复间隔	|无	|可配置间隔|

继承关系:DispatcherObject → DependencyObject → Visual → UIElement → FrameworkElement → Control → ButtonBase → RepeatButton

### 6.2 基础用法

```xml
<RepeatButton Content="+" Width="30" Height="30" Click="Increase_Click"/>
```




```c#
private int _value = 0;

private void Increase_Click(object sender, RoutedEventArgs e)
{
    _value++;
    txtValue.Text = _value.ToString();
}
```

### 6.3 关键属性
|属性	|类型	|默认值|	说明|
|-|-|-|-|
|Delay	|int	|300(ms)	|首次触发前的延迟时间|
|Interval	|int|	100(ms)	|重复触发的时间间隔|


<RepeatButton Content="加速+" 
              Delay="200" 
              Interval="50"
              Click="Accelerate_Click"/>
### 6.4 事件处理
|事件	|描述|
|-|-|
|Click	|每次触发时发生|
|PreviewMouseDown	|鼠标按下时(首次触发前)|
|PreviewMouseUp	|鼠标释放时|

# 7.Label标签
Label 是 WPF 中用于显示文本内容的轻量级控件,相比 TextBlock 提供了更多与表单输入控件协作的功能。。

## 7.1 基础特性与用法
基本结构


```xml
<Label Content="用户名:" Target="{Binding ElementName=txtUserName}"/>
<TextBox x:Name="txtUserName"/>
```

核心属性

|属性	|类型	|说明	|示例值|
|-|-|-|-|
|Content	|object|	显示内容	|"密码:", `<Image>`等|
|Target	|UIElement	|关联的焦点目标控件|	{Binding ElementName=txtBox}|
|ContentTemplate|	DataTemplate	|内容显示模板	|自定义数据模板|

### 7.2 与输入控件协作
#### 7.2.1  快捷键支持(AccessText)

```xml
<Label Content="_Username:" Target="{Binding ElementName=txtUser}"/>
<TextBox x:Name="txtUser"/>

<!-- 按Alt+U将聚焦到文本框 -->
```

#### 7.2.2 多目标关联

```xml
<StackPanel>
    <Label x:Name="lblGroup" Content="个人资料"/>
    <CheckBox Content="姓名" Target="{Binding ElementName=lblGroup}"/>
    <CheckBox Content="年龄" Target="{Binding ElementName=lblGroup}"/>
</StackPanel>
```

### 7.3 内容呈现

```xml
<Label Content="静态文本标签"/>

<Label>
    <StackPanel Orientation="Horizontal">
        <Image Source="warning.png" Width="16"/>
        <TextBlock Text="重要提示" FontWeight="Bold"/>
    </StackPanel>
</Label>
```
## 8.TextBlock文字块
TextBlock 是 WPF 中最基础且功能强大的文本显示控件,相比 Label 控件更轻量且专注于文本呈现。

### 8.1 基础文本显示
文本设置方式


```xml
<!-- 直接文本 -->
<TextBlock Text="Hello World"/>

<!-- 内容属性语法 -->
<TextBlock>直接内容</TextBlock>

<!-- 多行文本 -->
<TextBlock>
    <Run Text="123"/>
    <LineBreak/>
    <Run Text="456"/>
</TextBlock>
```

基础属性配置

|属性|	类型	|说明	|示例|
|-|-|-|-|
|TextWrapping	|TextWrapping	|换行控制	|Wrap, NoWrap|
|TextTrimming	|TextTrimming	|溢出处理	|CharacterEllipsis, WordEllipsis|
|TextAlignment	|TextAlignment	|对齐方式	|Left, Center, Right|
|LineHeight	|double	|行间距	|20|
|LineStackingStrategy	|enum	|行高计算	|BlockLineHeight, MaxHeight|

### 8.2 高级文本格式化
内联元素类型


```xml
<TextBlock>
    <Run Text="普通文本 "/>
    <LineBreak/>
    <Bold>加粗文本</Bold>
    <Italic>斜体文本</Italic>
    <Underline>
        <Span>组合</Span>
    </Underline>
    <Hyperlink NavigateUri="https://example.com">超链接</Hyperlink>
</TextBlock>
```

### 8.3 视觉样式控制
字体控制属性

|属性|	说明|	示例值|
|-|-|-|
|FontFamily	|字体	|"Arial", "微软雅黑"|
|FontSize|	字号|	14, 18|
|FontWeight	|字重	|Normal, Bold|
|FontStyle|	样式	|Normal, Italic|
|TextDecorations|	装饰线	|Underline, Strikethrough|

高级渲染控制


```xml
<!-- 抗锯齿优化 -->
<TextBlock TextOptions.TextFormattingMode="Display"
           TextOptions.TextRenderingMode="Auto"/>

<!-- 文本阴影 -->
<TextBlock Text="特效文本">
    <TextBlock.Effect>
        <DropShadowEffect BlurRadius="4" ShadowDepth="3" Color="#88000000"/>
    </TextBlock.Effect>
</TextBlock>
```

### 8.4 渲染性能优化

```xml
<!-- 启用硬件渲染 -->
<TextBlock CacheMode="BitmapCache"/>

<!-- 大量文本优化 -->
<TextBlock Text="{Binding LogContent}" 
           TextOptions.TextFormattingMode="Display"
           IsTextSelectionEnabled="False"/>
```

### 8.5 超链接

```xml
<TextBlock>
    <Hyperlink NavigateUri="https://www.baidu.com" RequestNavigate="Hyperlink_RequestNavigate">
        点击访问
    </Hyperlink>
</TextBlock>
```


```c#
private void Hyperlink_RequestNavigate(object sender, System.Windows.Navigation.RequestNavigateEventArgs e)
{
    Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri) { UseShellExecute = true });
}
```
## 9.TextBox输入框
TextBox 是 WPF 中用于文本输入的基本控件

### 9.1 主要特点
- 支持单行和多行文本输入
- 提供文本选择、复制、粘贴等基本编辑功能
- 支持数据绑定和格式化
- 可自定义外观和行为

### 9.2 基本用法

```xml
<Window x:Class="TestWpfApp.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:TestWpfApp"
        mc:Ignorable="d"
        Title="MainWindow" Height="400" Width="350">
    <Grid>
        <GroupBox Header="笔记编辑" Margin="10" Padding="5">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition/>
                    <RowDefinition Height="Auto"/>
                </Grid.RowDefinitions>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition/>
                    </Grid.ColumnDefinitions>
                    <TextBlock Text="标题:" VerticalAlignment="Center"/>
                    <!--单行文本框-->
                    <TextBox Grid.Column="1" FontSize="16" FontWeight="Bold"/>
                </Grid>
                <Grid Grid.Row="1" Margin="0,5">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition/>
                    </Grid.RowDefinitions>
                    <TextBlock Text="笔记描述:"/>
                    <!--多行文本框-->
                    <TextBox Grid.Row="1" FontSize="16" TextWrapping="Wrap" AcceptsReturn="True" VerticalScrollBarVisibility="Auto"/>
                </Grid>
                <Grid Grid.Row="2" Margin="0,5">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition/>
                    </Grid.ColumnDefinitions>
                    <TextBlock Text="链接:" VerticalAlignment="Center"/>
                    <!--只读可复制文本框-->
                    <TextBox Text="www.diandiandidi.club" IsReadOnly="True" BorderThickness="0"  Grid.Column="1" />
                </Grid>
            </Grid>
        </GroupBox>
    </Grid>
</Window>
```
![](https://www.diandiandidi.club:12346/api/note/getImage/10/4f577601-97a2-413d-a9a7-0dda656c0790-.png)

### 9.3 常用属性
文本相关

- Text: 获取或设置文本框中的文本内容
- TextAlignment: 文本对齐方式 (Left, Right, Center, Justify)
- TextWrapping: 文本换行方式 (NoWrap, Wrap, WrapWithOverflow)
- LineHeight: 行高
- MaxLength: 最大输入字符数


外观相关

- Background: 背景色
- oreground: 前景色(文本颜色)
- BorderBrush: 边框颜色
- BorderThickness: 边框粗细
- FontFamily: 字体
- FontSize: 字体大小
- FontWeight: 字体粗细
- FontStyle: 字体样式 (Normal, Italic, Oblique)


行为相关

- IsReadOnly: 是否只读
- IsEnabled: 是否启用
- AcceptsReturn: 是否接受回车键(用于多行输入)
- AcceptsTab: 是否接受 Tab 键
- SpellCheck.IsEnabled: 是否启用拼写检查
- HorizontalScrollBarVisibility: 水平滚动条可见性
- VerticalScrollBarVisibility: 垂直滚动条可见性
- SelectionBrush: 文本选中时的背景色
- SelectionOpacity: 文本选中时背景色的透明度
- CaretBrush: 光标颜色

### 9.4 水印

```xml
<TextBox>
    <TextBox.Style>
        <Style TargetType="TextBox">
            <Setter Property="Foreground" Value="Gray"/>
            <Setter Property="Text" Value="请输入内容..."/>
            <Style.Triggers>
                <Trigger Property="IsFocused" Value="True">
                    <Setter Property="Foreground" Value="Black"/>
                    <Setter Property="Text" Value=""/>
                </Trigger>
            </Style.Triggers>
        </Style>
    </TextBox.Style>
</TextBox>
```

### 9.5 事件处理
- TextChanged: 文本内容改变时触发
- GotFocus: 获得焦点时触发
- LostFocus: 失去焦点时触发
- PreviewTextInput: 文本输入前触发
- KeyDown: 按键按下时触发
- KeyUp: 按键释放时触发

## 10.PasswordBox密码输入框
PasswordBox 是 WPF 中专门用于密码输入的控件,不支持密码属性绑定。

主要特点:

- 专为密码输入设计,输入字符默认显示为掩码(圆点或星号)
- 不直接暴露密码文本,提供安全属性访问密码
- 不支持数据绑定 Password 属性(出于安全考虑)
- 提供密码强度控制功能
- 可自定义密码显示字符和外观

### 10.1 简单用法

```xml
<PasswordBox Password="123456" PasswordChar="*"/>
```
![](https://www.diandiandidi.club:12346/api/note/getImage/10/aafba1a1-5a28-4fa3-9996-b858083b5ba3-.png)

### 10.2 常用属性
密码相关

•Password: 获取或设置密码框中包含的密码(不直接绑定)
•PasswordChar: 获取或设置用于屏蔽密码的字符(默认是圆点●)
外观相关

- Background: 背景色
- Foreground: 前景色(文本颜色)
- BorderBrush: 边框颜色
- BorderThickness: 边框粗细
- FontFamily: 字体
- FontSize: 字体大小
- FontWeight: 字体粗细
- SelectionBrush: 文本选中时的背景色
- SelectionOpacity: 文本选中时背景色的透明度
- CaretBrush: 光标颜色
行为相关

- MaxLength: 最大输入字符数
- IsEnabled: 是否启用
- PasswordChanged: 密码更改时触发的事件

### 10.3 密码安全处理
安全获取密码


```c#
// 不安全方式(字符串会留在内存中)
string password = pwdBox.Password; 

// 安全方式(推荐)
System.Security.SecureString securePwd = pwdBox.SecurePassword;
// 将 SecureString 转换为字符串

string ConvertToUnsecureString(SecureString securePassword)
{
    if (securePassword == null)
        return string.Empty;

    IntPtr unmanagedString = IntPtr.Zero;
    try
    {
        unmanagedString = Marshal.SecureStringToGlobalAllocUnicode(securePassword);
        return Marshal.PtrToStringUni(unmanagedString);
    }
    finally
    {
        Marshal.ZeroFreeGlobalAllocUnicode(unmanagedString);
    }
}
```
## 11.RichTextBox富文本框
RichTextBox 是 WPF 中用于显示和编辑富文本内容的控件,支持多种文本格式、段落样式、嵌入对象等高级功能。

### 11.1 核心特点
- 支持富文本格式(RTF)
- 可包含多种字体、颜色、样式混合的文本
- 支持段落、列表、表格等复杂排版
- 允许嵌入图像、超链接等非文本元素
- 提供文本选择、格式查询等高级功能
- 基于 FlowDocument 文档模型

### 11.2 与TextBox对比
|特性|	TextBox|	RichTextBox|
|-|-|-|
|文本格式	|纯文本|	富文本|
|性能	|高	|较低|
|内存占用|	少|	较多|
|功能|	基础编辑	|高级排版|
|使用场景	|简单输入	|复杂文档|

[RichTextBox介绍](https://learn.microsoft.com/zh-cn/dotnet/desktop/wpf/controls/richtextbox?view=netframeworkdesktop-4.8)

## 12.Tooltip 提示
ToolTip 是 WPF 中用于显示额外信息的弹出式控件,当用户将鼠标悬停在元素上时显示提示内容。

### 12.1 核心特点
- 轻量级信息展示​​:不干扰主界面布局
- ​​悬停触发​​:默认鼠标悬停时显示
- 富内容支持​​:可包含任意可视化元素
- ​​高度可定制​​:完全控制外观和行为
- ​​自动定位​​:智能避开屏幕边缘

### 12.2 基本使用
简单文本提示


```xml
<Button Content="提交" ToolTip="点击提交表单数据"/>
```

通过属性设置


```xml
<Button Content="保存">
    <Button.ToolTip>
        <ToolTip Content="保存当前文档"/>
    </Button.ToolTip>
</Button>
```

多行文本提示


```xml
<TextBox>
    <TextBox.ToolTip>
        <ToolTip>
            <StackPanel>
                <TextBlock Text="用户名输入要求:" FontWeight="Bold"/>
                <TextBlock Text="1. 长度6-20个字符"/>
                <TextBlock Text="2. 只能包含字母和数字"/>
            </StackPanel>
        </ToolTip>
    </TextBox.ToolTip>
</TextBox>
```

### 12.3 核心属性
内容属性

- Content:基础内容属性
- ContentTemplate:定义内容模板
- ContentStringFormat:内容字符串格式化


显示行为

- Placement:定位方式 (Bottom, Top, Left, Right, Mouse等)
- HorizontalOffset/VerticalOffset:显示偏移量
- PlacementRectangle:相对定位矩形区域
- PlacementTarget:指定相对定位的元素
- StaysOpen:是否保持打开状态
- IsOpen:控制打开/关闭状态
- InitialShowDelay:初始显示延迟(ms)
- ShowDuration:显示持续时间(ms)
- BetweenShowDelay:两次显示间隔(ms)


视觉样式

- Background:背景色
- Foreground:前景色
- BorderBrush:边框颜色
- BorderThickness:边框粗细
- FontFamily/FontSize:字体设置
- Padding:内边距
- HasDropShadow:是否显示阴影




### 12.5 交互控制
编程控制显示


```c#
// 创建ToolTip实例
ToolTip customTip = new ToolTip();
customTip.Content = "自定义提示";
customTip.Placement = PlacementMode.Right;

// 关联到元素
Button btn = new Button();
btn.Content = "测试按钮";
btn.ToolTip = customTip;

// 手动控制显示
customTip.IsOpen = true;

// 5秒后自动关闭
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(5);
timer.Tick += (s, e) => { customTip.IsOpen = false; timer.Stop(); };
timer.Start();
```

处理ToolTip事件


```xml
<Button Content="事件测试">
    <Button.ToolTip>
        <ToolTip x:Name="testToolTip" 
                 Opened="ToolTip_Opened" 
                 Closed="ToolTip_Closed"
                 Content="事件演示ToolTip"/>
    </Button.ToolTip>
</Button>
```




```c#
private void ToolTip_Opened(object sender, RoutedEventArgs e)
{
    Debug.WriteLine("ToolTip已显示");
}

private void ToolTip_Closed(object sender, RoutedEventArgs e)
{
    Debug.WriteLine("ToolTip已关闭");
}
```



### 12.6 多元素共享ToolTip

```xml
<StackPanel>
    <StackPanel.ToolTip>
        <ToolTip x:Name="sharedToolTip" Content="共享提示信息"/>
    </StackPanel.ToolTip>
    
    <Button Content="按钮1" ToolTip="{Binding ElementName=sharedToolTip}"/>
    <TextBox Text="文本框" ToolTip="{Binding ElementName=sharedToolTip}"/>
</StackPanel>
```

## 13.Popup浮窗
Popup 是 WPF 中用于创建浮动窗口的控件,它可以在主窗口上方显示内容,常用于下拉菜单、提示框、上下文菜单等场景。

### 13.1 基本概念与特性
核心特点

- 独立于主窗口的浮动层​​:显示在主窗口内容之上
- 灵活定位​​:可相对于任意元素或屏幕位置定位
- 非模态交互​​:不阻止与其他窗口元素的交互
- 自动隐藏​​:默认点击外部区域自动关闭
- 富内容支持​​:可包含任意可视化元素
- ​​动画支持​​:可添加显示/隐藏动画效果
与类似控件对比

|特性	|Popup|	ToolTip	|ContextMenu|
|-|-|-|-|
|触发方式	|编程控制	|悬停	|右键点击|
|交互性	|完全交互|	只读|	菜单交互|
|显示控制	|IsOpen属性	|自动|	自动|
|定位方式|	灵活定位|	跟随鼠标	|跟随鼠标|

### 13.2 基本使用
1.简单Popup声明


```xml
<Popup x:Name="simplePopup" Placement="Mouse">
    <Border Background="White" BorderBrush="Gray" BorderThickness="1">
        <TextBlock Margin="10" Text="这是一个简单的Popup"/>
    </Border>
</Popup>
```

2.通过代码控制显示


```c#
// 显示Popup
simplePopup.IsOpen = true;

// 关闭Popup
simplePopup.IsOpen = false;
```

3.绑定触发按钮


```xml
<StackPanel>
    <CheckBox x:Name="popupButton" Content="显示Popup"/>
    <Popup IsOpen="{Binding IsChecked, ElementName=popupButton}" 
   PlacementTarget="{Binding ElementName=popupButton}">
        <Border Background="LightYellow" Padding="10">
            <TextBlock Text="绑定按钮状态的Popup"/>
        </Border>
    </Popup>
</StackPanel>
```



### 13.3 核心属性
 定位属性

- Placement:定位方式 (Absolute, Relative, Mouse, Bottom, Top等12种)
- PlacementTarget:定位参考元素
- PlacementRectangle:相对定位的矩形区域
- HorizontalOffset/VerticalOffset:偏移量


显示行为

- IsOpen:控制显示/隐藏状态
- StaysOpen:是否在失去焦点时自动关闭
- AllowsTransparency:是否允许透明背景
- PopupAnimation:内置动画效果 (None, Fade, Scroll, Slide)
- IsHitTestVisible:是否响应鼠标事件


视觉样式

- Child:Popup内容
- Width/Height:尺寸设置
- MaxWidth/MaxHeight:最大尺寸
- Background:背景色
- Padding:内边距


### 13.4 交互控制
处理Popup事件


```xml
<Popup x:Name="eventPopup" Opened="Popup_Opened" Closed="Popup_Closed">
    <!-- 内容 -->
</Popup>
```

保持焦点控制


```xml
<Popup x:Name="focusPopup" StaysOpen="True">
    <StackPanel>
        <TextBox x:Name="popupTextBox"/>
        <Button Content="关闭" Click="ClosePopup_Click"/>
    </StackPanel>
</Popup>
```
## 14.Image 图像
Image 是 WPF 中用于显示图像的控件,支持多种图像格式和高级图像处理功能。

### 14.1 基本概念与特性
核心特点

- 多格式支持​​:BMP、PNG、JPEG、GIF、TIFF等
- 多种加载方式​​:文件路径、URI、内存流、资源
- ​​显示控制​​:拉伸、裁剪、旋转、透明度
- 高性能渲染​​:硬件加速支持
- ​​动画支持​​:不支持GIF动画播放
支持的图像格式

|格式	|特性|	适用场景|
|-|-|-|
|PNG	|无损压缩、透明通道|	高质量图像、透明背景|
|JPEG	|有损压缩、小文件	|照片、实景图像|
|BMP|	无压缩、大文件	|需要无损编辑的图像|
|GIF	|256色、支持动画	|简单动画、小图标|
|TIFF	|高质量、多页|	专业图像处理|

14.2 基本使用方式
从文件加载


```xml
<Image Source="C:\Users\luyuanwen\Desktop\图片\111.gif"/>
```

从项目资源加载


```xml
<!-- 添加图像到项目Resources文件夹 -->
<Image Source="Resources/icon.png"/>
```

 从URI加载


```xml
<Image Source="https://www.diandiandidi.club/favicon.ico"/>
```

代码加载


```c#
BitmapImage bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.UriSource = new Uri("pack://application:,,,/Resources/image.png");
bitmap.EndInit();
imageControl.Source = bitmap;
```

### 14.3 核心属性
图像源属性

- Source:图像源(BitmapImage、DrawingImage等)
- Stretch:拉伸方式(None、Fill、Uniform、UniformToFill)
- StretchDirection:拉伸方向(UpOnly、DownOnly、Both)

视觉属性

- Opacity:透明度(0.0-1.0)
- OpacityMask:不透明蒙版
- RenderTransform:渲染变换(旋转、缩放等)
- Clip:裁剪区域

布局属性

- Width/Height:显式尺寸
- MaxWidth/MaxHeight:最大尺寸
- MinWidth/MinHeight:最小尺寸

### 14.4 高级用法
 图像裁剪


```xml
<Image Source="photo.jpg">
    <Image.Clip>
        <EllipseGeometry Center="100,100" RadiusX="80" RadiusY="80"/>
    </Image.Clip>
</Image>
```

 图像变换


```xml
<Image Source="photo.jpg">
    <Image.RenderTransform>
        <TransformGroup>
            <RotateTransform Angle="15"/>
            <ScaleTransform ScaleX="0.8" ScaleY="0.8"/>
        </TransformGroup>
    </Image.RenderTransform>
</Image>
```

 图像蒙版


```xml
<Image Source="https://www.diandiandidi.club/favicon.ico">
    <Image.OpacityMask>
        <LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
            <GradientStop Color="Black" Offset="0"/>
            <GradientStop Color="Transparent" Offset="1"/>
        </LinearGradientBrush>
    </Image.OpacityMask>
</Image>
```

### 14.5 性能优化
解码像素大小


```c#
BitmapImage bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.UriSource = new Uri("large_image.jpg");
bitmap.DecodePixelWidth = 800; // 限制解码宽度
bitmap.DecodePixelHeight = 600; // 限制解码高度
bitmap.EndInit();
imageControl.Source = bitmap;
```

 缓存选项

```c#
bitmap.CacheOption = BitmapCacheOption.OnLoad; // 立即加载并缓存,可以防止锁定图像
```

## 15.GroupBox分组
GroupBox 是 WPF 中用于将相关控件分组并提供视觉分隔的容器控件,继承自 System.Windows.Controls.HeaderedContentControl

### 15.1 基本概念与特性
核心特点

- 分组容器​​:将相关控件组织在一起
- 标题显示​​:带有可自定义的标题区域
- 视觉分隔​​:提供边框和背景区分不同组
- ​​布局控制​​:作为内容控件,可包含任意子元素
- ​​键盘导航​​:支持通过标题快速导航到内容。按下Tab键后,优先导航到GroupBox,之后方向键选择可以聚焦的内容。

与类似控件对比

|特性	|GroupBox	|Expander	|TabControl|	Border|
|-|-|-|-|-|
|标题	|有	|有	|有(标签页)|	无|
|折叠功能	|无	|有	|无	|无|
|边框	|有	|有	|有	|有|
|内容切换|	无	|展开/折叠	|标签页切换	|无|


### 15.2 基本使用
简单 GroupBox


```xml
<GroupBox Header="用户信息">
    <StackPanel>
        <TextBox Margin="5" Text="姓名"/>
        <TextBox Margin="5" Text="年龄"/>
    </StackPanel>
</GroupBox>
```

 带复杂标题


```xml
<GroupBox>
    <GroupBox.Header>
        <StackPanel Orientation="Horizontal">
            <Image Source="user.png" Width="16"/>
            <TextBlock Text="用户信息" Margin="5,0"/>
        </StackPanel>
    </GroupBox.Header>
    <!-- 内容 -->
</GroupBox>
```

### 15.3 核心属性
标题相关

- Header:标题内容(字符串或任意对象)
- HeaderTemplate:标题内容的数据模板

外观属性

- BorderBrush:边框颜色
- BorderThickness:边框粗细
- Background:背景色
- Foreground:前景色(影响标题文本)
- Padding:内边距

行为属性

- IsEnabled:是否启用(禁用时内容也会禁用)
- Focusable:是否可获取焦点
- HorizontalContentAlignment:内容水平对齐
- VerticalContentAlignment:内容垂直对齐

## 16.ScrollViewer 滚动视图
功能​​:内容滚动容器,当内容超出可视区域时提供滚动条

​继承关系​​:ContentControl → Control → FrameworkElement → UIElement

典型用途​​:显示大型内容、长列表、图片查看器等

基本用法:


```xml
<Window x:Class="TestWpfApp.MainWindow"
    
        Title="MainWindow" Height="400" Width="350">
    <Grid>
        <Border Width="180" Height="180" BorderBrush="Black" BorderThickness="1">
            <!--HorizontalScrollBarVisibility:水平滚动条的可见性
            VerticalScrollBarVisibility:垂直滚动条的可见性
            ScrollChanged:滚动条的变化事件-->
            <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
                <Grid Width="160" Height="200" Background="Red"/>
            </ScrollViewer>
        </Border>
    </Grid>
</Window>

```
![](https://www.diandiandidi.club:12346/api/note/getImage/13/14455231-5443-4eaf-9fbb-bedd0adc51d2-.png)
核心属性:

|属性	|说明	|常用值|
|-|-|-|
|VerticalScrollBarVisibility	|垂直滚动条可见性	|Auto, Visible, Hidden, Disabled|
|HorizontalScrollBarVisibility|	水平滚动条可见性|	同上|
|CanContentScroll	|启用逻辑滚动(虚拟化)|true/false|
|IsDeferredScrollingEnabled	|延迟滚动(性能优化)	|true/false|
|PanningMode	|触摸屏滚动模式	|None, VerticalOnly, HorizontalOnly, Both|

常用方法


```c#
// 滚动控制
ScrollToVerticalOffset(double offset)  // 垂直滚动到指定位置
ScrollToHorizontalOffset(double offset) // 水平滚动到指定位置
ScrollToEnd()    // 滚动到底部
ScrollToHome()   // 滚动到顶部
LineUp()/LineDown() // 单行滚动
PageUp()/PageDown() // 整页滚动
```
## 17.ScrollBar 滚动条
功能​​:独立的滚动条控件,用于控制内容滚动位置

​​继承关系​​:RangeBase → Control → FrameworkElement → UIElement

​​与ScrollViewer关系​​:ScrollViewer内部使用两个ScrollBar实现滚动

## 18.Slider 滑块
### 18.1 基本概念与特性
核心特点:

- 范围选择​​:允许用户在最小值和最大值之间选择数值
- 方向灵活​​:支持水平和垂直两种布局方向
- 精度控制​​:通过TickFrequency和IsSnapToTickEnabled实现精确取值
- ​​可视化标记​​:支持刻度线(Tick)显示
- ​​丰富交互​​:支持鼠标、键盘和触摸操作
继承关系:

Slider → RangeBase → Control → FrameworkElement → UIElement

### 18.2 基本使用

```xml
<!-- 水平滑块 -->
<Slider Minimum="0" Maximum="100" Value="50"/>

<!-- 垂直滑块 -->
<Slider Orientation="Vertical" Minimum="0" Maximum="1" Value="0.5" Height="100"/>


<Slider Minimum="0" Maximum="100" Value="50" SmallChange="1" LargeChange="10" 
        TickPlacement="BottomRight" IsSnapToTickEnabled="True" 
        IsMoveToPointEnabled="True"  TickFrequency="1" 
        AutoToolTipPlacement="BottomRight"  AutoToolTipPrecision="1"/>
```
![](https://www.diandiandidi.club:12346/api/note/getImage/13/9abf9542-9d86-4c65-9a17-f6af6f313bac-.png)
### 18.3 核心属性
值范围属性

|属性	|说明	|默认值|
|-|-|-|
|Minimum	|最小值|	0|
|Maximum|	最大值|	10|
|Value	|当前值|	0|
|SmallChange	|小步长变化量	|0.1|
|LargeChange	|大步长变化量	|1|

外观属性

|属性|	说明|
|-|-|
|Orientation	|方向(Horizontal/Vertical)|
|TickPlacement	|刻度线位置(None/TopLeft/BottomRight/Both)|
|TickFrequency|	刻度间隔频率|
|IsDirectionReversed	|是否反转方向|
|AutoToolTipPlacement|	工具提示位置|
|AutoToolTipPrecision	|工具提示小数位数|

行为属性

|属性	|说明|
|-|-|
|IsSnapToTickEnabled	|是否吸附到刻度|
|IsMoveToPointEnabled	|点击轨道是否直接跳转|
|Delay	|重复按钮延迟时间(ms)|
|Interval	|重复按钮间隔时间(ms)|

## 19.ProgressBar进度条
ProgressBar(进度条)是 WPF 中用于显示操作进度的控件,它能够直观地展示任务的完成情况。

### 19.1 基本使用
基本声明


```xml
<!-- 确定进度模式 -->
<ProgressBar Minimum="0" Maximum="100" Value="50" Height="20"/>

<!-- 不确定进度模式 -->
<ProgressBar IsIndeterminate="True" Height="20"/>
```

### 19.2 核心属性
进度控制属性

|属性	|说明|默认值|
|-|-|-|
|Minimum	|最小值	|0|
|Maximum	|最大值	|100|
|Value	|当前进度值|	0|
|IsIndeterminate	|是否为不确定模式	|false|

外观属性

|属性	|说明|
|-|-|
|Orientation	|方向(Horizontal/Vertical)|
|Foreground|	进度条填充色|
|Background|	进度条背景色|
|BorderBrush	|边框颜色|
|BorderThickness	|边框粗细|

行为属性

|属性	|说明|
|-|-|
|IsEnabled	|是否启用|
|Visibility	|可见性|
### 19.3 圆角进度条

```xml
<ProgressBar>
    <ProgressBar.Template>
        <ControlTemplate TargetType="ProgressBar">
            <Grid>
                <Border CornerRadius="5" Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}"/>
                <Border CornerRadius="5" Name="PART_Track">
                    <Rectangle Name="PART_Indicator" 
                               Fill="{TemplateBinding Foreground}"
                               HorizontalAlignment="Left"/>
                </Border>
            </Grid>
        </ControlTemplate>
    </ProgressBar.Template>
</ProgressBar>

```
![](https://www.diandiandidi.club:12346/api/note/getImage/13/19af10de-ac8b-4cd4-a01f-e3ee0b82d6b6-.png)


## 20.Calendar日历
提供日期选择功能的可视化日历控件

基本使用

   
```xml
 <Calendar 
DisplayDate="2025-5-5"
DisplayDateStart="2025-1-1"
DisplayDateEnd="2025-5-5"

SelectionMode="SingleDate"
FirstDayOfWeek="Monday"/>
```
![](https://www.diandiandidi.club:12346/api/note/getImage/13/c998d81e-1047-491a-80c7-dbef9c6afdf2-.png)

核心属性

|属性	|说明|	常用值|
|-|-|-|
|SelectedDate	|选中的日期	|DateTime对象|
|SelectedDates	|多个选中日期集合	|DateTime集合|
|DisplayDate	|当前显示的月份	|DateTime对象|
|DisplayDateStart|	可显示的最早日期|	DateTime对象|
|DisplayDateEnd|	可显示的最晚日期	|DateTime对象|
|SelectionMode|	选择模式	|SingleDate, SingleRange, MultipleRange, None|
|FirstDayOfWeek|	每周的第一天	|Sunday, Monday等DayOfWeek枚举值|
|IsTodayHighlighted	|是否高亮今天	|true/false|
|BlackoutDates	|不可选日期集合|	CalendarDateRange集合|

常用方法


```c#
// 添加不可选日期
calendar.BlackoutDates.Add(new CalendarDateRange(startDate, endDate));

// 清除所有选择
calendar.SelectedDates.Clear();

// 导航到特定月份
calendar.DisplayDate = new DateTime(2023, 7, 1);
```

事件处理

|事件	|触发时机|
|-|-|
|SelectedDatesChanged	|选中日期变化时|
|DisplayDateChanged	|显示月份变化时|


```c#
calendar.SelectedDatesChanged += (sender, e) => {
    var selectedDates = ((Calendar)sender).SelectedDates;
    // 处理选中日期
};
```
## 21.DatePicker日期选择
提供日期选择功能的输入控件

使用


```xml
<DatePicker
    SelectedDate="{Binding SelectedDate}"
    DisplayDateStart="2025-01-01"
    DisplayDateEnd="2025-12-31"
    FirstDayOfWeek="Monday"
    IsTodayHighlighted="True"
    Text="选择日期"/>
```
![](https://www.diandiandidi.club:12346/api/note/getImage/13/94eea958-90b4-490a-9245-8f08b2020944-.png)
核心属性

|属性	|说明|	类型|	默认值|
|-|-|-|-|
|SelectedDate	|选中的日期|	DateTime?	null|
|DisplayDate	|日历打开时显示的日期	|DateTime	|当前日期|
|DisplayDateStart|	可选择的最早日期	|DateTime?	|null|
|DisplayDateEnd	|可选择的最晚日期|	DateTime?	|null|
|FirstDayOfWeek	|每周的第一天	|DayOfWeek	|CurrentCulture|
|IsTodayHighlighted	|是否高亮今天|	bool	|true|
|SelectedDateFormat	|日期显示格式	|DatePickerFormat|	Short|
|Text	|文本框显示的文本|	string	|""|
|IsDropDownOpen|	日历是否展开|	bool|	false|
|BlackoutDates|	不可选日期集合	|CalendarBlackoutDatesCollection	|空|

常用方法


```c#
// 清空选择
datePicker.SelectedDate = null;

// 添加不可选日期
datePicker.BlackoutDates.Add(new CalendarDateRange(startDate, endDate));

// 获取格式化文本
string dateString = datePicker.Text;
```



事件处理

|事件|	触发时机|
|-|-|
|SelectedDateChanged|	选中日期变化时|
|DateValidationError|	日期验证失败时|
|CalendarOpened|	日历展开时|
|CalendarClosed	|日历关闭时|


## 22.MediaElement媒体播放



```xml
<MediaElement x:Name="mediaPlayer"
              Source="media/sample.mp4"
              LoadedBehavior="Manual"
              UnloadedBehavior="Stop"
              Volume="0.5"/>
```

|属性	|说明|
|-|-|
|Source	|媒体文件路径(URI格式)|
|LoadedBehavior|	加载后的行为(Play, Pause, Stop等)|
|Volume	|音量(0.0到1.0)|
|Balance|	声道平衡(-1.0左到1.0右)|
|SpeedRatio|	播放速度(1.0正常速度)|
|IsMuted	|是否静音|
|NaturalDuration|	媒体总时长(只读)|
|Position|	当前播放位置|

播放控制实现


```c#
// 播放
mediaPlayer.Play();

// 暂停
mediaPlayer.Pause();

// 停止
mediaPlayer.Stop();

// 定位
mediaPlayer.Position = TimeSpan.FromSeconds(30);
```

## 23.Expander 折叠控件
可展开/折叠的内容容器,带有标题和切换按钮


```xml
<Expander Header="详细信息">
    <TextBlock Text="这里是可展开的详细内容..." Padding="10"/>
</Expander>

<Expander 
    Header="高级选项"
    IsExpanded="False"
    ExpandDirection="Down"
    Padding="5">
    <!-- 内容 -->
</Expander>
```

核心属性

|属性	|说明|	常用值|
|-|-|-|
|IsExpanded	|是否展开	|true/false|
|ExpandDirection	|展开方向|	Down, Up, Left, Right|
|Header	|标题内容	|字符串或任意UI元素|
|HeaderTemplate|	标题模板	|DataTemplate|
|Content|	展开的内容|	任意UI元素|

事件处理

|事件|	触发时机|
|-|-|
|Expanded	|展开时触发|
|Collapsed	|折叠时触发|

# 五.集合控件
## 1.ListBox 列表
ListBox 是 WPF 中最常用的列表控件之一,它提供了丰富的数据展示和交互功能

### 1.1 重要属性
选择相关属性

- SelectedItem - 当前选中的项
- SelectedIndex - 当前选中项的索引
- SelectedValue - 当使用 SelectedValuePath 时获取的值
- SelectedValuePath - 指定从选中项中提取哪个属性作为 SelectedValue
- SelectionMode - 选择模式(Single-单选,Multiple-多选,Extended-扩展选择)

显示相关属性

- ItemsSource - 数据源绑定
- DisplayMemberPath - 指定显示项的哪个属性
- ItemTemplate - 自定义项的显示模板
- ItemContainerStyle - 项的容器样式
- ScrollViewer.VerticalScrollBarVisibility - 滚动条可见性

### 1.2 事件处理
- SelectionChanged - 选择项变化时触发
- MouseDoubleClick - 双击项时触发

### 1.3 虚拟化
对于大量数据,可以使用虚拟化提高性能


```xml
<ListBox VirtualizingStackPanel.IsVirtualizing="True"
         VirtualizingStackPanel.VirtualizationMode="Recycling"/>
```

### 1.4 使用
#### 14.1 简单使用
从下面选项中选择一项或者多项


```xml
<StackPanel Margin="10">
    <StackPanel Orientation="Horizontal">
        <TextBlock Text="选择:"/>
        <TextBlock x:Name="selItemValue"/>
    </StackPanel>
    <ListBox x:Name="listBox" SelectionMode="Single" SelectedIndex="1" SelectionChanged="ListBox_SelectionChanged">
        <ListBoxItem Content="语文"/>
        <ListBoxItem Content="数学"/>
        <ListBoxItem Content="英语"/>
        <ListBoxItem Content="物理"/>
        <ListBoxItem Content="化学"/>
        <ListBoxItem Content="生物"/>
    </ListBox>
</StackPanel>
```




```c#
private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if(sender is ListBox listBox)
    {
        if (listBox.SelectedItem is ListBoxItem item)
        {
            selItemValue.Text = item.Content.ToString();
        }
    }
}
```
![](https://www.diandiandidi.club:12346/api/note/getImage/14/caf54e31-161c-4f10-aa69-f8355cc8d6f4-.png)

#### 14.2 代码添加数据

```xml
<StackPanel Margin="10">
    <StackPanel Orientation="Horizontal">
        <TextBlock Text="选择:"/>
        <TextBlock x:Name="selItemValue"/>
    </StackPanel>
    <ListBox x:Name="listBox" SelectionMode="Single" SelectedIndex="1" SelectionChanged="ListBox_SelectionChanged">
    </ListBox>
</StackPanel>
```


```c#
public MainWindow()
{
    InitializeComponent();

    List<string> list = new List<string>();
    list.Add("语文");
    list.Add("数学");
    list.Add("英语");
    list.Add("物理");
    list.Add("化学");
    list.Add("生物");

    listBox.ItemsSource = list;
}

private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if(sender is ListBox listBox)
    {
        if (listBox.SelectedItem is ListBoxItem item)
        {
            selItemValue.Text = item.Content.ToString();
        }
    }
}
```
#### 14.3 使用对象作为数据项



```xml
<StackPanel Margin="10">
    <StackPanel Orientation="Horizontal">
        <TextBlock Text="选择:"/>
        <TextBlock x:Name="selItemValue"/>
    </StackPanel>
    <ListBox x:Name="listBox" DisplayMemberPath="Name" SelectedValuePath="Name" 
      SelectionMode="Single" SelectedIndex="1" SelectionChanged="ListBox_SelectionChanged">
    </ListBox>
</StackPanel>
```




```c# 
public MainWindow()
{
    InitializeComponent();

    List<Subject> list = new List<Subject>();
    list.Add(new Subject() { Index=0,Name= "语文" });
    list.Add(new Subject() { Index=1,Name= "数学" });
    list.Add(new Subject() { Index=2,Name= "英语" });

    listBox.ItemsSource = list;
}

private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if(sender is ListBox listBox)
    {
        if (listBox.SelectedItem is Subject item)
        {
            selItemValue.Text = item.Name;
        }
    }
}

class Subject
{
    public int Index { get; set; }
    public string Name { get; set; }
}

```
#### 14.4 处理数据源变更
数据源变更包括删除、增加项以及修改项。

错误变更数据源案例:


```c#
public partial class MainWindow : Window
{
    private Subject selSubject = null;
    private List<Subject> list = new List<Subject>();
    public MainWindow()
    {
        InitializeComponent();

        list.Add(new Subject() { Index=0,Name= "语文" });
        list.Add(new Subject() { Index=1,Name= "数学" });
        list.Add(new Subject() { Index=2,Name= "英语" });

        listBox.ItemsSource = list;
    }

    private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if(sender is ListBox listBox)
        {
            if (listBox.SelectedItem is Subject item)
            {
                selItemValue.Text = item.Name;
                selSubject = item;
            }
        }
    }

    class Subject
    {
        public int Index { get; set; }
        public string Name { get; set; }
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        // 通过绑定的list进行删除是无法删除的
        list.Remove(selSubject);

        // 报错:当 ItemsSource 正在使用时操作无效
        listBox.Items.Remove(selSubject);
    }
}
```

正确变更数据源案例:

使用ObservableCollection集合,该集合数据变更时会进行通知更新。


```c#
public partial class MainWindow : Window
{
    private Subject selSubject = null;
    private ObservableCollection<Subject> list = new ObservableCollection<Subject>();
    
    ``` 

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        // 
        list.Remove(selSubject);
    }
}
```

变更数据源某项属性案例:




```xml
<StackPanel Margin="10">
    <StackPanel Orientation="Horizontal">
        <TextBlock Text="选择:"/>
        <TextBlock x:Name="selItemValue"/>
        <Button Content="修改" Click="Button_Click"/>
    </StackPanel>
    <ListBox x:Name="listBox" DisplayMemberPath="Name" SelectedValuePath="Name" SelectionMode="Single" SelectedIndex="1" SelectionChanged="ListBox_SelectionChanged">
    </ListBox>
</StackPanel>
```




```c#
public partial class MainWindow : Window
{
    private Subject selSubject = null;
    private ObservableCollection<Subject> list = new ObservableCollection<Subject>();
    public MainWindow()
    {
        InitializeComponent();

        list.Add(new Subject() { Index=0,Name= "语文" });
        list.Add(new Subject() { Index=1,Name= "数学" });
        list.Add(new Subject() { Index=2,Name= "英语" });

        listBox.ItemsSource = list;
    }

    private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if(sender is ListBox listBox)
        {
            if (listBox.SelectedItem is Subject item)
            {
                selItemValue.Text = item.Name;
                selSubject = item;
            }
        }
    }

    class Subject: INotifyPropertyChanged
    {
        private int _index;
        public int Index
        {
            get { return _index; }
            set { _index = value; OnPropertyChanged(nameof(Index)); }
        }

        private string _name;
        public string Name
        {
            get { return _name; }
            set { _name = value; OnPropertyChanged(nameof(Name)); }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        // 通知属性值改变
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        if (selSubject != null)
        {
            selSubject.Name = selSubject.Name + selSubject.Index;
        }
    }
}
```



### 1.5 自定义模板

```xml
<StackPanel Margin="10">
    <StackPanel Orientation="Horizontal">
        <TextBlock Text="选择:"/>
        <TextBlock x:Name="selItemValue"/>
    </StackPanel>
    <ListBox x:Name="listBox" SelectedValuePath="Name" SelectionMode="Single" SelectedIndex="1" SelectionChanged="ListBox_SelectionChanged">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding Index}"/>
                    <TextBlock Text="{Binding Name}" Margin="10,0,0,0"/>
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</StackPanel>
```
![](https://www.diandiandidi.club:12346/api/note/getImage/14/05af13ea-650c-45d7-93af-7529eee3ab1c-.png)


## 2.ListView
ListView 是 WPF 中功能强大的列表控件,继承自 ListBox,但提供了更丰富的显示功能,特别是支持多列视图(类似表格)。


```xml
<StackPanel Margin="5">
    <TextBlock Text="友情链接"/>
    <ListView x:Name="listView">
        <ListView.View>
            <GridView>
                <GridViewColumn Header="序号" Width="40" DisplayMemberBinding="{Binding Index}"/>
                <GridViewColumn Header="Id" Width="50" DisplayMemberBinding="{Binding Id}"/>
                <GridViewColumn Header="名称" Width="120" DisplayMemberBinding="{Binding Name}"/>
                <GridViewColumn Width="160" DisplayMemberBinding="{Binding Url}">
                    <GridViewColumnHeader>
                        <GridViewColumnHeader.ContentTemplate>
                            <DataTemplate>
                                <StackPanel Orientation="Horizontal">
                                    <Image Source="/Views/web.png" Width="18" Height="18"/>
                                    <TextBlock VerticalAlignment="Center" Text="网站" />
                                </StackPanel>
                            </DataTemplate>
                        </GridViewColumnHeader.ContentTemplate>
                    </GridViewColumnHeader>
                </GridViewColumn>
                <GridViewColumn Header="操作" Width="120">
                    <GridViewColumn.CellTemplate>
                        <DataTemplate>
                                <StackPanel Orientation="Horizontal">
                                    <Button Content="编辑"/>
                                    <Button Content="删除" Margin="3,0,0,0"/>
                                </StackPanel>
                        </DataTemplate>
                    </GridViewColumn.CellTemplate>
                </GridViewColumn>
            </GridView>
        </ListView.View>
    </ListView>
</StackPanel>
```




```c#
public partial class MainWindow : Window
{
    ObservableCollection<Blogroll> blogrolls = new ObservableCollection<Blogroll>();
    public MainWindow()
    {
        InitializeComponent();
        blogrolls.Add(new Blogroll
        {
            Index = 1,
            Id = "web_01",
            Name = "Google",
            Url = "https://www.google.com"
        });
        blogrolls.Add(new Blogroll
        {
            Index = 2,
            Id = "web_02",
            Name = "Bing",
            Url = "https://www.bing.com"
        });
        blogrolls.Add(new Blogroll
        {
            Index = 3,
            Id = "web_03",
            Name = "Yahoo",
            Url = "https://www.yahoo.com"
        });
        blogrolls.Add(new Blogroll
        {
            Index = 4,
            Id = "web_04",
            Name = "DuckDuckGo",
            Url = "https://www.duckduckgo.com"
        });

        listView.ItemsSource = blogrolls;
    }
}

public class Blogroll : INotifyPropertyChanged
{
    private int _index;
    public int Index
    {
        get { return _index; }
        set
        {
            if (_index != value)
            {
                _index = value;
                OnPropertyChanged(nameof(Index));
            }
        }
    }

    private string _Id;
    public string Id
    {
        get { return _Id; }
        set
        {
            if (_Id != value)
            {
                _Id = value;
                OnPropertyChanged(nameof(Id));
            }
        }
    }

    private string _name;
    public string Name
    {
        get { return _name; }
        set
        {
            if (_name != value)
            {
                _name = value;
                OnPropertyChanged(nameof(Name));
            }
        }
    }

    private string _url;
    public string Url
    {
        get { return _url; }
        set
        {
            if (_url != value)
            {
                _url = value;
                OnPropertyChanged(nameof(Url));
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
  }
```
![](https://www.diandiandidi.club:12346/api/note/getImage/14/d2d1c707-d119-4ace-8f28-e074dabf232c-.png)

## 3.DataGrid
### 3.1 基础概念
DataGrid 简介:

- WPF 中最强大的数据展示控件
- 提供类似 Excel 的表格功能
- 支持排序、编辑、验证等高级功能
- 继承自 ItemsControl,具有 ItemsSource 绑定能力
核心组件:

- 行(Row)​​: 数据记录
- ​​列(Column)​​: 数据字段
- ​​单元格(Cell)​​: 行和列的交点
- ​​表头(Header)​​: 列标题
- ​​行头(RowHeader)​​: 行选择指示器

### 3.2 基本使用
基本语法:


```xml
<DataGrid x:Name="dataGrid">
    <DataGrid.Columns>
        <DataGridTextColumn Header="ID" Binding="{Binding Id}"/>
        <DataGridTextColumn Header="姓名" Binding="{Binding Name}"/>
    </DataGrid.Columns>
</DataGrid>
```

数据绑定方式:

​自动生成列​


```xml
<DataGrid AutoGenerateColumns="True"/>
```

手动定义列​


```xml
<DataGrid AutoGenerateColumns="False">
    <!-- 列定义 -->
</DataGrid>
```

常用列类型:

|列类型	|描述	|示例|
|-|-|-|
|DataGridTextColumn|	文本列	|`<DataGridTextColumn Binding="{Binding Name}"/>`|
|DataGridCheckBoxColumn	|复选框列|	`<DataGridCheckBoxColumn Binding="{Binding IsActive}"/>`|
|DataGridComboBoxColumn	|下拉框列	|`<DataGridComboBoxColumn ItemsSource="{Binding Departments}"/>`|
|DataGridHyperlinkColumn|	超链接列|`	<DataGridHyperlinkColumn Binding="{Binding Url}"/>`|
|DataGridTemplateColumn	|自定义模板列	|见高级用法|

### 3.3 DataGrid 核心功能
排序功能:


```xml
<DataGrid CanUserSortColumns="True">
    <DataGrid.Columns>
        <DataGridTextColumn Header="日期" 
                           Binding="{Binding Date}" 
                           SortDirection="Descending"/>
    </DataGrid.Columns>
</DataGrid>
```

编辑功能:


```xml
<DataGrid CanUserAddRows="True"    <!-- 允许添加行 -->
          CanUserDeleteRows="True" <!-- 允许删除行 -->
          CanUserEditRows="True">  <!-- 允许编辑行 -->
</DataGrid>
```

选择模式:


```xml
<DataGrid SelectionMode="Extended"  <!-- 多选模式 -->
          SelectionUnit="FullRow">  <!-- 整行选择 -->
</DataGrid>
```

行详细信息:


```xml
<DataGrid.RowDetailsTemplate>
    <DataTemplate>
        <StackPanel>
            <TextBlock Text="{Binding Description}"/>
            <Image Source="{Binding ImagePath}"/>
        </StackPanel>
    </DataTemplate>
</DataGrid.RowDetailsTemplate>
 <!--VisibleWhenSelected:只有当行被选中时才显示详细信息
 Visible:始终显示详细信息
 Collapsed:从不显示详细信息-->

<DataGrid.RowDetailsVisibilityMode>VisibleWhenSelected</DataGrid.RowDetailsVisibilityMode>
```

### 3.4 DataGrid 高级功能
自定义列模板


```xml
<DataGridTemplateColumn Header="操作">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <Button Content="编辑" Command="{Binding EditCommand}"/>
                <Button Content="删除" Command="{Binding DeleteCommand}"/>
            </StackPanel>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
```

分组显示


```xml
<DataGrid>
    <DataGrid.GroupStyle>
        <GroupStyle>
            <GroupStyle.HeaderTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Name}" FontWeight="Bold"/>
                </DataTemplate>
            </GroupStyle.HeaderTemplate>
        </GroupStyle>
    </DataGrid.GroupStyle>
</DataGrid>
```

### 3.5 DataGrid 样式与模板
行样式


```xml
<DataGrid.RowStyle>
    <Style TargetType="DataGridRow">
        <Style.Triggers>
            <Trigger Property="IsSelected" Value="True">
                <Setter Property="Background" Value="LightBlue"/>
            </Trigger>
            <Trigger Property="IsMouseOver" Value="True">
                <Setter Property="Background" Value="LightYellow"/>
            </Trigger>
        </Style.Triggers>
    </Style>
</DataGrid.RowStyle>
```

交替行颜色


```xml
<DataGrid AlternationCount="2" 
          AlternatingRowBackground="LightGray"/>
```

单元格样式


```xml
<DataGrid.CellStyle>
    <Style TargetType="DataGridCell">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="DataGridCell">
                    <Border Background="{TemplateBinding Background}">
                        <ContentPresenter VerticalAlignment="Center"/>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</DataGrid.CellStyle>
```

### 3.6 DataGrid 性能优化
虚拟化技术


```xml
<DataGrid EnableRowVirtualization="True"
          EnableColumnVirtualization="True"
          VirtualizingPanel.VirtualizationMode="Recycling"/>
```

冻结列


```xml
<DataGrid FrozenColumnCount="2">  <!-- 冻结前两列 -->
</DataGrid>
```

延迟滚动


```xml
<DataGrid ScrollViewer.IsDeferredScrollingEnabled="True"/>
```

### 3.7 常见问题
#### 3.7.1 自动生成列自定义

```c#
private void DataGrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
    // 修改列标题
    if (e.PropertyName == "FirstName")
        e.Column.Header = "名";
    
    // 隐藏某些列
    if (e.PropertyName == "SecretProperty")
        e.Cancel = true;
    
    // 自定义日期格式
    if (e.PropertyType == typeof(DateTime))
        (e.Column as DataGridTextColumn).Binding.StringFormat = "yyyy-MM-dd";
}
```

#### 3.7.2 大数据量处理

```xml
<DataGrid VirtualizingPanel.ScrollUnit="Pixel"
          VirtualizingPanel.IsVirtualizingWhenGrouping="True"
          ScrollViewer.IsDeferredScrollingEnabled="True"/>
```

#### 3.7.3 行双击事件

```xml
<DataGrid MouseDoubleClick="DataGrid_MouseDoubleClick"/>
```

#### 3.7.4 可编辑数据表格

```xml
<DataGrid ItemsSource="{Binding Products}" 
          CanUserAddRows="True"
          CanUserDeleteRows="True"
          CellEditEnding="DataGrid_CellEditEnding">
    <DataGrid.Columns>
        <DataGridTextColumn Header="名称" Binding="{Binding Name}"/>
        <DataGridTextColumn Header="价格" Binding="{Binding Price}"/>
    </DataGrid.Columns>
</DataGrid>
```


```c#
private void DataGrid_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
{
    // 验证编辑内容
    if (e.Column.Header.ToString() == "价格")
    {
        var newValue = (e.EditingElement as TextBox)?.Text;
        if (!decimal.TryParse(newValue, out _))
        {
            e.Cancel = true;
            MessageBox.Show("请输入有效的价格");
        }
    }
}
```

### 3.8 综合案例
xml:

样式在后期,这里先使用


```xml
<Window x:Class="TestWpfApp.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:TestWpfApp"
        xmlns:controls="clr-namespace:TestWpfApp.Controls"
        mc:Ignorable="d"
        Title="MainWindow" Height="400" Width="850">
    <Window.Resources>
        <!-- 颜色定义 -->
        <Color x:Key="PrimaryColor">#FF4285F4</Color>
        <Color x:Key="HoverColor">#FFE8F0FE</Color>
        <Color x:Key="SelectedColor">#FFD2E3FC</Color>
        <Color x:Key="HeaderColor">#F5F5F5</Color>
        <Color x:Key="BorderColor">#FFE0E0E0</Color>

        <!-- 转换为SolidColorBrush -->
        <SolidColorBrush x:Key="PrimaryBrush" Color="{StaticResource PrimaryColor}"/>
        <SolidColorBrush x:Key="HoverBrush" Color="{StaticResource HoverColor}"/>
        <SolidColorBrush x:Key="SelectedBrush" Color="{StaticResource SelectedColor}"/>
        <SolidColorBrush x:Key="HeaderBrush" Color="{StaticResource HeaderColor}"/>
        <SolidColorBrush x:Key="BorderBrush" Color="{StaticResource BorderColor}"/>

        <!-- 按钮样式 -->
        <Style x:Key="FlatButtonStyle" TargetType="Button">
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="Foreground" Value="{StaticResource PrimaryBrush}"/>
            <Setter Property="Padding" Value="5"/>
            <Setter Property="Margin" Value="2"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Button">
                        <Border Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="1"
                            CornerRadius="2">
                            <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="Background" Value="{StaticResource HoverBrush}"/>
                </Trigger>
                <Trigger Property="IsPressed" Value="True">
                    <Setter Property="Background" Value="{StaticResource SelectedBrush}"/>
                </Trigger>
            </Style.Triggers>
        </Style>

        <!-- DataGrid 整体样式 -->
        <Style TargetType="DataGrid">
            <Setter Property="Background" Value="White"/>
            <Setter Property="Foreground" Value="#333333"/>
            <Setter Property="BorderBrush" Value="{StaticResource BorderBrush}"/>
            <Setter Property="BorderThickness" Value="1"/>
            <Setter Property="RowDetailsVisibilityMode" Value="VisibleWhenSelected"/>
            <Setter Property="ScrollViewer.CanContentScroll" Value="True"/>
            <Setter Property="ScrollViewer.PanningMode" Value="Both"/>
            <Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
            <Setter Property="HeadersVisibility" Value="Column"/>
            <Setter Property="SelectionUnit" Value="FullRow"/>
            <Setter Property="CanUserResizeRows" Value="False"/>
            <Setter Property="ColumnHeaderHeight" Value="32"/>
            <Setter Property="RowHeight" Value="32"/>
            <Setter Property="GridLinesVisibility" Value="None"/>
            <Setter Property="FontSize" Value="14"/>
        </Style>

        <!-- DataGrid 列标题样式 -->
        <Style TargetType="DataGridColumnHeader">
            <Setter Property="Background" Value="{StaticResource HeaderBrush}"/>
            <Setter Property="Foreground" Value="#333333"/>
            <Setter Property="FontWeight" Value="SemiBold"/>
            <Setter Property="BorderBrush" Value="{StaticResource BorderBrush}"/>
            <Setter Property="BorderThickness" Value="0,0,0,1"/>
            <Setter Property="Padding" Value="10,0"/>
            <Setter Property="HorizontalContentAlignment" Value="Left"/>
            <Setter Property="Height" Value="32"/>
        </Style>

        <!-- DataGrid 行样式 -->
        <Style TargetType="DataGridRow">
            <Setter Property="Background" Value="White"/>
            <Setter Property="BorderBrush" Value="{StaticResource BorderBrush}"/>
            <Setter Property="BorderThickness" Value="0,0,0,1"/>
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="Background" Value="{StaticResource HoverBrush}"/>
                </Trigger>
                <Trigger Property="IsSelected" Value="True">
                    <Setter Property="Background" Value="{StaticResource SelectedBrush}"/>
                    <Setter Property="BorderBrush" Value="{StaticResource PrimaryBrush}"/>
                </Trigger>
                <Trigger Property="IsKeyboardFocusWithin" Value="True">
                    <Setter Property="Background" Value="{StaticResource SelectedBrush}"/>
                </Trigger>
            </Style.Triggers>
        </Style>

        <!-- DataGrid 单元格样式 -->
        <Style TargetType="DataGridCell">
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="BorderThickness" Value="0"/>
            <Setter Property="Padding" Value="10,0"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="DataGridCell">
                        <Border Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}"
                            SnapsToDevicePixels="True">
                            <ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            <Style.Triggers>
                <Trigger Property="IsSelected" Value="True">
                    <Setter Property="Foreground" Value="#333333"/>
                </Trigger>
            </Style.Triggers>
        </Style>

        <!-- 操作列按钮样式 -->
        <Style TargetType="Button" BasedOn="{StaticResource FlatButtonStyle}">
            <Setter Property="Width" Value="60"/>
            <Setter Property="Height" Value="24"/>
            <Setter Property="FontSize" Value="12"/>
        </Style>

        <!-- 标题文本样式 -->
        <Style TargetType="TextBlock" x:Key="TitleStyle">
            <Setter Property="FontSize" Value="18"/>
            <Setter Property="FontWeight" Value="Bold"/>
            <Setter Property="Foreground" Value="{StaticResource PrimaryBrush}"/>
            <Setter Property="Margin" Value="0,0,0,10"/>
        </Style>

        <!-- 提示文本样式 -->
        <Style TargetType="TextBlock" x:Key="HintStyle">
            <Setter Property="FontSize" Value="12"/>
            <Setter Property="Foreground" Value="#666666"/>
            <Setter Property="Margin" Value="0,0,0,10"/>
        </Style>
    </Window.Resources>

    <Grid>
        <Grid Margin="10">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>

            <!-- 应用标题样式 -->
            <TextBlock Text="用户管理系统" Style="{StaticResource TitleStyle}"/>

            <!-- 应用提示样式 -->
            <TextBlock Grid.Row="1" Text="操作提示:双击编辑,Del删除该用户,底部空白行添加用户" 
                  Style="{StaticResource HintStyle}"/>

            <!-- DataGrid 应用样式 -->
            <DataGrid x:Name="dataGrid" Grid.Row="2" 
                      VirtualizingPanel.ScrollUnit="Item"
                    VirtualizingPanel.IsVirtualizingWhenGrouping="True"
                    ScrollViewer.IsDeferredScrollingEnabled="True"
                      AutoGenerateColumns="False" 
                 CanUserDeleteRows="True" CanUserSortColumns="True" 
                 CanUserResizeColumns="False" CanUserAddRows="True">
                <DataGrid.Columns>
                    <DataGridCheckBoxColumn Header="选择" Binding="{Binding IsSelect}" Width="50"/>
                    <DataGridTextColumn Header="ID" Binding="{Binding Id}" Width="60"/>
                    <DataGridTextColumn Header="账号" Binding="{Binding Username}" Width="120"/>
                    <DataGridTextColumn Header="电话" Binding="{Binding Phone}" Width="120"/>
                    <DataGridComboBoxColumn x:Name="dataGridGender" Header="性别" 
                                      SelectedItemBinding="{Binding Gender}" Width="80"/>
                    <DataGridHyperlinkColumn Header="链接" Binding="{Binding Link}" Width="120">
                        <DataGridHyperlinkColumn.ElementStyle>
                            <Style TargetType="TextBlock">
                                <Setter Property="TextDecorations" Value="Underline"/>
                                <Setter Property="Foreground" Value="{StaticResource PrimaryBrush}"/>
                            </Style>
                        </DataGridHyperlinkColumn.ElementStyle>
                    </DataGridHyperlinkColumn>
                    <DataGridTextColumn Width="*" Header="备注" Binding="{Binding Remark}"/>
                    <DataGridTemplateColumn Header="操作" Width="140">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
                                    <Button Content="编辑" Command="{Binding EditCommand}"/>
                                    <Button Content="删除" Command="{Binding DeleteCommand}" Margin="5,0,0,0"/>
                                </StackPanel>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                </DataGrid.Columns>
                <DataGrid.RowDetailsTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <Image Source="/Views/web.png" Width="20" Height="20"/>
                            <TextBlock Text="当前行的详细信息" VerticalAlignment="Center"/>
                        </StackPanel>
                    </DataTemplate>
                </DataGrid.RowDetailsTemplate>
                <DataGrid.RowDetailsVisibilityMode>VisibleWhenSelected</DataGrid.RowDetailsVisibilityMode>
            </DataGrid>
        </Grid>
    </Grid>
</Window>
```


c# 


```c#
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;

namespace TestWpfApp
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        private readonly ObservableCollection<User> users = new ObservableCollection<User>();

        public MainWindow()
        {
            InitializeComponent();
            dataGrid.ItemsSource = users;
            dataGridGender.ItemsSource = Enum.GetValues(typeof(GenderType));
            for (int i = 0; i < 1000; i++)
            {
                users.Add(new User
                {
                    Username = "Username" + i,
                    Link = "https://www.diandiandidi.club",
                    Phone = "133****6666",
                    Remark = "Remark" + i,
                });
            }
        }
    }
    public class User : INotifyPropertyChanged
    {
        private bool _isSelect;
        public bool IsSelect
        {
            get { return _isSelect; }
            set
            {
                if (_isSelect != value)
                {
                    _isSelect = value;
                    OnPropertyChanged(nameof(IsSelect));
                }
            }
        }

        private int _id;
        public int Id
        {
            get { return _id; }
            set
            {
                if (_id != value)
                {
                    _id = value;
                    OnPropertyChanged(nameof(Id));
                }
            }
        }

        private string _phone;
        public string Phone
        {
            get { return _phone; }
            set
            {
                if (_phone != value)
                {
                    _phone = value;
                    OnPropertyChanged(nameof(Phone));
                }
            }
        }

        private string _username;
        public string Username
        {
            get { return _username; }
            set
            {
                if (_username != value)
                {
                    _username = value;
                    OnPropertyChanged(nameof(Username));
                }
            }
        }

        private GenderType _gender=GenderType.未知;
        public GenderType Gender
        {
            get { return _gender; }
            set
            {
                if(value != _gender)
                {
                    _gender = value;
                    OnPropertyChanged(nameof(Gender));
                }
            }
        }

        private string _link;
        public string Link
        {
            get { return _link; }
            set
            {
                if (_link != value)
                {
                    _link = value;
                    OnPropertyChanged(nameof(Link));
                }
            }
        }

        private string _remark;
        public string Remark
        {
            get { return _remark; }
            set
            {
                if (_remark != value)
                {
                    _remark = value;
                    OnPropertyChanged(nameof(Remark));
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public enum GenderType
    {
        男, 女, 未知
    }
}
```


效果:
![](https://www.diandiandidi.club:12346/api/note/getImage/14/d6e401b0-d2da-44c6-8f86-8eb1eb9acacc-.png)

## 4.ComboBox 下拉列表
下拉选择控件,继承自 ItemsControl,结合了文本框和下拉列表的功能,支持单选、数据绑定、自定义项模板等特性。

### 4.1 核心组成部分
- 下拉按钮​​:触发下拉列表
- 选择框​​:显示当前选中项
- 下拉列表​​:包含所有可选项目
- 项模板​​:定义每个选项的显示方式

### 4.2 基本用法
静态项定义


```xml
<ComboBox>
    <ComboBoxItem>选项1</ComboBoxItem>
    <ComboBoxItem>选项2</ComboBoxItem>
    <ComboBoxItem>选项3</ComboBoxItem>
</ComboBox>
```

数据绑定方式


```xml
<ComboBox DisplayMemberPath="Name"
          SelectedValuePath="Id"
          SelectedValue="{Binding SelectedId}"/>
```

### 4.3 核心属性
|属性	|描述	|示例
|-|-|-|
|ItemsSource	|数据源绑定	|ItemsSource="{Binding Products}"|
|DisplayMemberPath	|显示文本的属性	|DisplayMemberPath="ProductName"|
|SelectedValuePath|	选中项的值属性	|SelectedValuePath="ProductId"|
|SelectedItem	|当前选中项对象	|SelectedItem="{Binding SelectedProduct}"|
|SelectedValue	|当前选中项的值	|SelectedValue="{Binding SelectedProductId}"|
|SelectedIndex	|当前选中项的索引	|SelectedIndex="0"|
|IsEditable	|是否可编辑	|IsEditable="True"|
|MaxDropDownHeight	|下拉列表最大高度|	MaxDropDownHeight="200"|

### 4.4 事件处理
|事件|	描述|
|-|-|
|SelectionChanged	|选中项变化时触发|
|DropDownOpened	|下拉列表打开时触发|
|DropDownClosed	|下拉列表关闭时触发|
|PreviewKeyDown|	键盘按键按下时触发|


### 4.5 案例-搜索下拉

```xml
<ComboBox x:Name="comboBox" SelectedValuePath="Name" 
  DisplayMemberPath="Name" DropDownOpened="ComboBox_DropDownOpened" 
PreviewKeyUp="ComboBox_PreviewKeyUp" 
  IsEditable="True" IsTextSearchEnabled="False" Width="200" Height="30"/>
```
![](https://www.diandiandidi.club:12346/api/note/getImage/14/ef7c2bea-d9a8-4b13-82ca-59fe6ef8c047-.png)


```c#
public partial class TestWindow : Window
{
    ObservableCollection<User> searUsers = new ObservableCollection<User>();
    List<User> allUsers = new List<User>();
    public TestWindow()
    {
        InitializeComponent();
        for (int i = 0; i < 100; i++)
        {
            allUsers.Add(new User() { Name = "Name" + i, Age = "Age" + i, Address = "Address" + i });
        }
        comboBox.ItemsSource = searUsers;
    }

    private void ComboBox_PreviewKeyUp(object sender, KeyEventArgs e)
    {
        searUsers.Clear();
        int count = 0;
        for (int i = 0; i < allUsers.Count; i++)
        {
            var item = allUsers[i];
            if (item.Name.ToLower().Contains(comboBox.Text.ToLower()) || item.Age.Contains(comboBox.Text) || item.Address.Contains(comboBox.Text))
            {
                searUsers.Add(item);
                count++;
                if (count >= 10)
                {
                    break;
                }
            }
        }
        comboBox.IsDropDownOpen = true;
    }

    private void ComboBox_DropDownOpened(object sender, EventArgs e)
    {
        if (string.IsNullOrEmpty(comboBox.Text))
        {
            searUsers.Clear();
            for (int i = 0; i < allUsers.Count&&i<10; i++)
            {
                searUsers.Add(allUsers[i]);
            }
        }
    }
}

public class User : INotifyPropertyChanged
{
    public string Name { get; set; }
    public string Age { get; set; }
    public string Address { get; set; }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

```
![](https://www.diandiandidi.club:12346/api/note/getImage/14/66545322-85b5-49b3-a2d1-87c9f4935700-.png)

## 5.TabControl 选项卡
- 选项卡式界面容器控件
- 继承自 Selector 类,允许用户通过选项卡切换不同内容
- 每个选项卡包含一个 TabItem 作为容器

### 5.1 基本用法

```xml
<TabControl>
    <TabItem Header="首页">
        <TextBlock Text="欢迎来到首页"/>
    </TabItem>
    <TabItem Header="设置">
        <StackPanel>
            <CheckBox Content="启用通知"/>
            <Slider Maximum="100"/>
        </StackPanel>
    </TabItem>
</TabControl>
```
![](https://www.diandiandidi.club:12346/api/note/getImage/14/2fe02a8b-ec75-4c4f-b6b8-af388e0c430e-.png)

数据绑定方式


```xml
<TabControl SelectedIndex="0">
    <TabControl.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Title}"/>
        </DataTemplate>
    </TabControl.ItemTemplate>
    <TabControl.ContentTemplate>
        <DataTemplate>
            <ContentControl Content="{Binding Content}"/>
        </DataTemplate>
    </TabControl.ContentTemplate>
</TabControl>
```
### 5.2 核心属性
|属性|	描述|
|ItemsSource|	数据源绑定|
|SelectedIndex	|当前选中选项卡索引|
|SelectedItem	|当前选中选项卡项|
|TabStripPlacement|选项卡位置|
|ContentTemplate|	内容模板|
|ItemTemplate	|选项卡标题模板|
|sSynchronizedWithCurrentItem	|同步当前项|

### 5.3 TabItem 
|属性	|描述	|示例|
|-|-|-|
|Header	|选项卡标题	|Header="设置"|
|HeaderTemplate|	标题模板	||
|IsSelected	|是否选中	|IsSelected="True"|
|Content|	选项卡内容	||

### 5.4 动态添加/移除选项卡

```c#
// 添加选项卡
var newTab = new TabItem { Header = "新标签", Content = new UserControl1() };
tabControl.Items.Add(newTab);

// 移除当前选项卡
tabControl.Items.Remove(tabControl.SelectedItem);
```

### 5.5 选项卡位置控制

```xml
<TabControl TabStripPlacement="Left">
    <!-- 选项卡将显示在左侧 -->
</TabControl>
```

可选值:Top(默认)、Bottom、Left、Right

### 5.6 案例-左侧导航


```xml
<TabControl TabStripPlacement="Left">
    <TabItem>
        <TabItem.Header>
            <StackPanel Orientation="Horizontal">
                <Image Source="/Resources/Images/icon_shouye.png" Width="26" Height="26"/>
                <TextBlock Text="首页" VerticalAlignment="Center" Margin="5,0,0,0" FontSize="16"/>
            </StackPanel>
        </TabItem.Header>
        <TabItem.Content>
            <Grid>
                <TextBlock Text="这里是首页" VerticalAlignment="Center" HorizontalAlignment="Center"/>
            </Grid>
        </TabItem.Content>
    </TabItem>
    <TabItem>
        <TabItem.Header>
            <StackPanel Orientation="Horizontal">
                <Image Source="/Resources/Images/icon_kandian.png" Width="26" Height="26"/>
                <TextBlock Text="看点" VerticalAlignment="Center" Margin="5,0,0,0" FontSize="16"/>
            </StackPanel>
        </TabItem.Header>
        <TabItem.Content>
            <Grid>
                <TextBlock Text="这里是看点" VerticalAlignment="Center" HorizontalAlignment="Center"/>
            </Grid>
        </TabItem.Content>
    </TabItem>
    ······
</TabControl>
```
![](https://www.diandiandidi.club:12346/api/note/getImage/14/73222818-8eb1-4632-8a1e-3cb5cc3bad04-.png)
## 6.TreeView 树形控件
### 6.1 TreeView 基础概念
TreeView 简介

- 层次结构数据展示控件
- 继承自 ItemsControl 类
- 支持节点展开/折叠、选择、编辑等操作
- 典型应用:文件浏览器、组织结构图、分类目录

核心组成部分

- TreeViewItem​​:树节点项
- HierarchicalDataTemplate​​:层级数据模板
- ​​展开/折叠按钮​​:控制子项显示
- ​​节点选择​​:单选/多选支持

### 6.2 基本用法

```xml
<TreeView>
    <TreeViewItem Header="部门">
        <TreeViewItem Header="研发部"/>
        <TreeViewItem Header="市场部">
            <TreeViewItem Header="北方区"/>
            <TreeViewItem Header="南方区"/>
        </TreeViewItem>
    </TreeViewItem>
</TreeView>
```
![](https://www.diandiandidi.club:12346/api/note/getImage/14/d514c756-9b88-4d6a-a655-c91a2d516921-.png)
### 6.3 核心属性
|属性|	描述|	示例|
|-|-|-|
|ItemsSource|	数据源绑定	|后期mvvm讲解|
|SelectedItem	|当前选中项	|SelectedItem="{Binding SelectedNode}"|
|SelectedValue|选中项的值	|SelectedValue="{Binding SelectedId}"|
|SelectedValuePath	|值路径	|SelectedValuePath="Id"|
|ItemTemplate	|项模板	|见模板部分|
|BorderThickness	|边框粗细|	BorderThickness="1"|
|AllowDrop	|允许拖放	|AllowDrop="True"|

### 6.4 TreeViewItem 属性

|属性	|描述	|示例|
|-|-|-|
|Header	|节点标题	|Header="研发部"|
|IsExpanded	|是否展开	|IsExpanded="True"|
|IsSelected	|是否选中	|IsSelected="True"|
|ItemsSource	|子项数据源	|ItemsSource="{Binding Children}"|

### 6.5 案例-Html文档大纲查看

```xml
<Grid Margin="10">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="36"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <TextBlock Text="Html文件大纲" FontSize="16" FontWeight="Bold"/>
    <Grid Grid.Row="1" Margin="0,5,0,0">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>
        <TextBox x:Name="htmlFilePathTextBox" IsReadOnly="True" VerticalContentAlignment="Center" Padding="5,0">
            <TextBox.Style>
                <Style TargetType="TextBox">
                    <Setter Property="Foreground" Value="Gray"/>
                    <Setter Property="Text" Value="点击按钮打开html文件..."/>
                    <Style.Triggers>
                        <Trigger Property="IsFocused" Value="True">
                            <Setter Property="Foreground" Value="Black"/>
                            <Setter Property="Text" Value=""/>
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </TextBox.Style>
        </TextBox>
        <Button Grid.Column="1" Click="OpenHtmlFile_Click" Content="打开" Margin="5,0,0,0" Width="75"/>
    </Grid>
    <TreeView x:Name="treeView" Grid.Row="2" Margin="0,5,0,0">
        <TreeView.Resources>
        <HierarchicalDataTemplate DataType="{x:Type local:HtmlHeadingNode}" 
                                  ItemsSource="{Binding Children}">
            <TextBlock Text="{Binding Title}" FontWeight="Bold"/>
        </HierarchicalDataTemplate>
    </TreeView.Resources>
    </TreeView>
</Grid>

```



```c#
public partial class TestWindow : Window
{
    private ObservableCollection<HtmlHeadingNode> headingNodes = new ObservableCollection<HtmlHeadingNode>();
    public TestWindow()
    {
        InitializeComponent();
        treeView.ItemsSource = headingNodes;
    }

    private void OpenHtmlFile_Click(object sender, RoutedEventArgs e)
    {
        OpenFileDialog openFileDialog = new OpenFileDialog();
        openFileDialog.Filter = "HTML文件 (*.html;*.htm)|*.html;*.htm|所有文件 (*.*)|*.*";
        openFileDialog.FilterIndex = 1;
        openFileDialog.RestoreDirectory = true;
        if (openFileDialog.ShowDialog() == true)
        {
            try
            {
                htmlFilePathTextBox.Text = openFileDialog.FileName;
                string htmlContent = File.ReadAllText(htmlFilePathTextBox.Text);
                headingNodes.Clear();
                ParseHtmlHeadings(htmlContent);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"读取文件时出错: {ex.Message}");
            }
        }
    }


    /// <summary>
    /// 该代码由ai生成
    /// </summary>
    private void ParseHtmlHeadings(string htmlContent)
    {
        try
        {
            // 使用正则表达式匹配所有h1-h6标签
            var regex = new Regex(@"<h([1-6])[^>]*>(.*?)<\/h[1-6]>", RegexOptions.IgnoreCase);
            var matches = regex.Matches(htmlContent);

            // 用于跟踪当前层级
            Stack<HtmlHeadingNode> nodeStack = new Stack<HtmlHeadingNode>();

            foreach (Match match in matches)
            {
                int level = int.Parse(match.Groups[1].Value);
                string title = match.Groups[2].Value;

                // 清理标题文本(移除HTML标签)
                title = Regex.Replace(title, "<.*?>", string.Empty).Trim();

                var newNode = new HtmlHeadingNode
                {
                    Title = title,
                    Level = level
                };

                // 处理层级关系
                while (nodeStack.Count > 0 && nodeStack.Peek().Level >= level)
                {
                    nodeStack.Pop();
                }

                if (nodeStack.Count == 0)
                {
                    headingNodes.Add(newNode);
                }
                else
                {
                    nodeStack.Peek().Children.Add(newNode);
                }

                nodeStack.Push(newNode);
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show($"解析HTML标题时出错: {ex.Message}");
        }
    }
}
public class HtmlHeadingNode
{
    public string Title { get; set; }
    public int Level { get; set; }
    public ObservableCollection<HtmlHeadingNode> Children { get; set; } = new ObservableCollection<HtmlHeadingNode>();
}
```
![](https://www.diandiandidi.club:12346/api/note/getImage/14/d590ac57-7b11-4999-9c2d-7babf8a64f50-.png)

## 7.Menu 菜单
Menu(菜单)是WPF中用于构建应用程序导航系统的重要控件,主要作用包括:

1.​​提供命令访问入口​​:集中展示应用程序功能命令
2.​​组织功能分类​​:通过层级结构合理组织功能模块
3.​​节省界面空间​​:通过下拉/弹出方式隐藏非活动命令
4.​​标准化交互​​:遵循操作系统菜单交互规范
5.​​支持快捷键​​:提供键盘快捷操作方式

典型应用场景:

- 应用程序主菜单(顶部水平菜单)
- 上下文菜单(右键弹出菜单)
- 工具栏下拉菜单
- 导航菜单系统

### 7.1 Menu 控件的结构
逻辑结构:

```language
Menu (根容器)
├── MenuItem (菜单项)
│   ├── MenuItem (子菜单项)
│   ├── Separator (分隔线)
│   └── ...更多子项
├── MenuItem 
└── ...更多菜单项
```

视觉结构组成:

1.​​菜单栏​​:水平容器,承载顶级菜单项
2.​​菜单项​​:文本标签(Header),图标(Icon),快捷键提示(InputGestureText),子菜单箭头指示器
3.​​子菜单面板​​:弹出式容器,承载子菜单项
4.​​分隔线​​:视觉分组线(Separator)

### 7.2 核心属性
Menu 容器属性

|属性	|类型	|默认值|	说明|
|-|-|-|-|
|ItemsSource	|object	|null	|数据绑定源|
|ItemTemplate|	DataTemplate|	null	|菜单项模板|
|Background	|Brush	|系统色	|背景色|
|Foreground	|Brush|	系统色	|文字颜色|
|IsMainMenu	|bool	|false	|是否作为主菜单(影响Alt键行为)|

MenuItem 属性

|属性|	类型|	默认值|	说明|
|-|-|-|-|
|Header|	object	|null	|菜单项显示内容|
|Command	|ICommand|	null	|关联命令|
|CommandParameter|	object|	null|	命令参数|
|InputGestureText	|string|	null	|快捷键提示文本|
|Icon	|object	|null	|菜单项图标|
|IsCheckable|	bool|	false|	是否可勾选|
|IsChecked	|bool|	false|	是否已勾选|
|StaysOpenOnClick|	bool|	false	|点击后是否保持菜单打开|
|ItemsSource	|IEnumerable	|null|	子项数据源|

### 7.3 重要事件
MenuItem 事件

|事件	|说明|
|-|-|
|Click	|点击菜单项时触发|
|Checked	|当IsCheckable=true且被勾选时触发|
|Unchecked|	当IsCheckable=true且取消勾选时触发|
|SubmenuOpened|	子菜单打开时触发|
|SubmenuClosed|	子菜单关闭时触发|

### 7.4 作为顶部菜单使用

```xml
<DockPanel>
    <Menu DockPanel.Dock="Top" IsMainMenu="True">
        <MenuItem Header="文件(_F)">
            <MenuItem Header="新建(_N)" InputGestureText="Ctrl+N"/>
            <MenuItem Header="打开(_O)" InputGestureText="Ctrl+O">
                <MenuItem.Icon>
                    <Image Source="/Resources/Images/icon_folder.png" Width="20" Height="20"/>
                </MenuItem.Icon>
            </MenuItem>
            <Separator/>
            <MenuItem Header="退出(_X)"/>
        </MenuItem>
        <MenuItem Header="编辑(_E)">
            <MenuItem Header="撤销(_Z)" InputGestureText="Ctrl+Z"/>
            <MenuItem Header="重做(_Y)" InputGestureText="Ctrl+Y"/>
        </MenuItem>
        <MenuItem Header="模式(_P)">
            <MenuItem IsChecked="True" IsCheckable="True" Header="编辑(_E)" InputGestureText="Ctrl+E"/>
            <MenuItem IsCheckable="True" Header="查看(_P)" InputGestureText="Ctrl+P"/>
        </MenuItem>
    </Menu>
    <Grid DockPanel.Dock="Left" Width="100" Background="Orange"/>
    <Grid DockPanel.Dock="Right" Width="100" Background="Green"/>
    <Grid DockPanel.Dock="Bottom" Height="100" Background="Black"/>
    <Grid/>
</DockPanel>
```
![](https://www.diandiandidi.club:12346/api/note/getImage/14/c753133e-b314-48f8-9907-5cef6823c5a8-.png)

### 7.5 作为上下文菜单使用
在 WPF 中,几乎所有可视化控件都支持上下文菜单(ContextMenu),因为 ContextMenu 属性是定义在 FrameworkElement 基类中的。因此大多数控件均可以右键更多操作。


```xml
<ListBox>
    <ListBoxItem Content="选项一"/>
    <ListBoxItem Content="选项二"/>
    <ListBoxItem Content="选项三"/>
    <ListBox.ContextMenu>
        <ContextMenu>
            <MenuItem Header="删除"/>
            <MenuItem Header="详细"/>
        </ContextMenu>
    </ListBox.ContextMenu>
</ListBox>
```
## 8.StatusBar 状态栏
StatusBar(状态栏)是WPF中用于显示应用程序状态信息的控件。

主要作用包括:

1.​​状态信息展示​​:显示应用程序当前状态、进度、操作提示等
2.​​辅助信息呈现​​:展示光标位置、缩放比例、日期时间等辅助信息
3.​​操作反馈​​:提供长时间操作的进度反馈
4.​​系统信息显示​​:内存使用、网络状态等系统信息
5.​​用户引导​​:显示当前可执行操作的提示信息

典型应用场景:

- 文本编辑器的行列号显示
- 图像处理软件的缩放比例和颜色信息
- 数据库应用的连接状态
- 应用程序的进度指示

```xml
<DockPanel>
    <Menu DockPanel.Dock="Top" IsMainMenu="True">
        <MenuItem Header="文件(_F)"/>
        <MenuItem Header="编辑(_E)"/>
        <MenuItem Header="模式(_P)"/>
    </Menu>
    <Grid DockPanel.Dock="Bottom" Height="100" Background="CadetBlue">
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <StatusBar Grid.Row="1">
            <StatusBarItem Content="版权所有©666 地址:xxxxx"/>
            <StatusBarItem Content="版本:1.0.0"/>
            <Separator/>
            <StatusBarItem Content="状态:正常"/>
            <ProgressBar Value="50" Width="200" Height="20" Margin="5,0,0,0"/>
        </StatusBar>
    </Grid>
    <Grid DockPanel.Dock="Left" Width="100" Background="Orange"/>
    <Grid DockPanel.Dock="Right" Width="100" Background="Green"/>
    <Grid>
    </Grid>
</DockPanel>
```
![](https://www.diandiandidi.club:12346/api/note/getImage/14/451be4e8-335f-47db-b96d-568b6682e9a6-.png)

## 9.ToolBar 工具栏
ToolBar(工具栏)是WPF中用于快速访问常用命令的控件,它提供了一种紧凑且高效的方式来组织应用程序的功能按钮。

### 9.1 ToolBar 的作用和特点
主要作用

1.​​快速访问​​:提供对常用功能的快速访问
2.​​命令分组​​:将相关功能组织在一起
3.​​节省空间​​:通过溢出机制自动管理空间不足的情况
4.​​用户自定义​​:允许用户自定义工具栏内容和位置

核心特点

- 自动处理布局和溢出
- 支持分隔符和分组
- 可停靠在任何边缘
- 支持工具提示和快捷键
- 可自定义外观和行为

### 9.2 ToolBar 的基本结构
1.工具栏托盘(ToolBarTray)​​:多个工具栏的容器
2.​​工具栏(ToolBar)​​:单个工具栏容器
3.​​工具栏项​​:按钮、组合框等控件
4.​​溢出区域​​:空间不足时自动隐藏的项

### 9.3 核心属性和事件
ToolBarTray 属性

|属性	|说明|
|-|-|
|Orientation|	排列方向(Horizontal/Vertical)|
|IsLocked	|是否锁定工具栏位置|

ToolBar 属性

|属性	|说明|
|-|-|
|Band	|指定工具栏所在的行/列|
|BandIndex	|指定工具栏在行/列中的位置|
|OverflowMode	|溢出行为(Always, Never, AsNeeded)|
|ToolTip	|工具栏提示|

### 9.4 使用

```xml
<DockPanel>
    <StackPanel DockPanel.Dock="Top">
        <Menu IsMainMenu="True">
            <MenuItem Header="文件(_F)"/>
            <MenuItem Header="编辑(_E)"/>
            <MenuItem Header="模式(_P)"/>
        </Menu>
        <ToolBarTray>
            <ToolBar>
                <Button Content="新建"/>
                <Button Content="打开"/>
                <Button Content="保存"/>
                <Separator/>
                <Button Content="打印"/>
                <Button Content="打印预览"/>
            </ToolBar>
            <ToolBar>
                <Button Content="还原"/>
                <Button Content="撤销"/>
            </ToolBar>
        </ToolBarTray>
    </StackPanel>
    <Grid DockPanel.Dock="Bottom" Height="100" Background="CadetBlue">
    </Grid>
    <Grid DockPanel.Dock="Left" Width="100" Background="Orange"/>
    <Grid DockPanel.Dock="Right" Width="100" Background="Green"/>
    <Grid>
    </Grid>
</DockPanel>
```
![](https://www.diandiandidi.club:12346/api/note/getImage/14/9e92349c-4b2c-4a87-ae94-345622150c58-.png)

# 六.图形控件
## 1.Shape 类
Shape 是所有 WPF 基本形状的抽象基类,提供了以下核心属性:

- Fill - 填充画刷
- Stroke - 边框画刷
- StrokeThickness - 边框粗细
- StrokeDashArray - 虚线样式

复杂场景​​:对于需要大量图形的场景,考虑使用 DrawingVisual 替代。
## 2.Ellipse 椭圆
Ellipse(椭圆)是 WPF 中用于绘制椭圆或圆形的基本形状控件

属性:

|属性	|类型|默认值|	说明|
|-|-|-|-|
|Width	|double	|0	|椭圆的宽度|
|Height	|double	0	|椭圆的高度|
|Fill	|Brush	|null	|填充椭圆的画刷|
|Stroke	|Brush|	null	椭圆边框的画刷|
|StrokeThickness|	double	|1	|边框粗细|
|StrokeDashArray	|DoubleCollection	|null	|虚线样式|
|Stretch|	Stretch	None	|填充模式|

使用:

简单使用

```xml
<Ellipse Width="100" Height="100" 
         Fill="Blue" Stroke="Black"
         StrokeThickness="2"/>
```
![](https://www.diandiandidi.club:12346/api/note/getImage/15/b6f3fc19-2546-4f8f-b72f-df8523037e87-.png)

画刷
```xml
<Ellipse Width="120" Height="120">
    <Ellipse.Fill>
        <RadialGradientBrush>
            <GradientStop Color="Yellow" Offset="0"/>
            <GradientStop Color="Red" Offset="1"/>
        </RadialGradientBrush>
    </Ellipse.Fill>
</Ellipse>
```
![](https://www.diandiandidi.club:12346/api/note/getImage/15/93303183-d8b3-4f1a-8312-3728e092063a-.png)
变换:


```xml
<Ellipse Width="60" Height="60" Fill="Purple">
    <Ellipse.RenderTransform>
        <TransformGroup>
            <RotateTransform Angle="45"/>
            <ScaleTransform ScaleX="1.5"/>
        </TransformGroup>
    </Ellipse.RenderTransform>
</Ellipse>
```
![](https://www.diandiandidi.club:12346/api/note/getImage/15/c951a600-b40a-4788-8799-d6b294164679-.png)

## 3.Line 线段
Line 是 WPF 中用于绘制直线的基本形状控件

属性:

|属性	|类型	|默认值|	说明|
|-|-|-|-|
|X1	|double|	0	|起点X坐标|
|Y1	|double|	0|	起点Y坐标|
|X2|	double|	0|	终点X坐标|
|Y2	|double	|0|	终点Y坐标|
|Stroke	|Brush	|null	|线条颜色|
|StrokeThickness	|double|	1|	线条粗细|
|StrokeStartLineCap|	PenLineCap	|Flat	|线条起点端帽样式|
|StrokeEndLineCap	|PenLineCap	|Flat	|线条终点端帽样式|
|StrokeDashArray	|DoubleCollection	|null|	虚线模式|
|StrokeDashCap|	PenLineCap	|Flat	|虚线端点样式|
|StrokeDashOffset|	double	|0	|虚线偏移量|

使用:

   
```xml
 <Line X1="10" Y1="10" X2="80" Y2="80" Stroke="Red" StrokeThickness="15" 
      StrokeStartLineCap="Round"
      StrokeEndLineCap="Triangle"
      StrokeDashArray="1,1"
      StrokeDashCap="Triangle"
      StrokeDashOffset="0"
   />
```
![](https://www.diandiandidi.club:12346/api/note/getImage/15/008be51c-2ec6-48b2-81d8-062e6f87f416-.png)

## 4.Rectangle 矩形
Rectangle(矩形)是 WPF 中用于绘制矩形或圆角矩形的基本形状控件

基本属性:

|属性|	类型|	默认值|	说明|
|-|-|-|-|
|Width|	double	|0|	矩形的宽度|
|Height	|double	|0	|矩形的高度|
|Fill	|Brush	|null|	矩形填充画刷|
|Stroke	|Brush|	null	|矩形边框画刷|
|StrokeThickness|	double|1	|边框粗细|
|RadiusX	|double	|0	|圆角X轴半径|
|RadiusY|	double	|0|	圆角Y轴半径|
|Stretch	|Stretch	|None	|填充模式|

边框样式属性:

|属性	|说明|
|-|-|
|StrokeDashArray|	虚线模式(如 "2,1" 表示2单位实线+1单位空白)|
|StrokeDashCap	|虚线端点样式(Flat, Round, Square, Triangle)|
|StrokeDashOffset	|虚线偏移量|
|StrokeLineJoin|	边框连接处样式(Miter, Bevel, Round)|
|StrokeMiterLimit	|斜接长度限制|

使用:

```xml
<Rectangle Canvas.Top="10" Canvas.Left="10" 
           StrokeThickness="3" RadiusX="10" RadiusY="10"
           Width="200" Height="100" Fill="Red" Stroke="Blue"/>
```
![](https://www.diandiandidi.club:12346/api/note/getImage/15/d650eebe-8dee-4272-942a-32ea995bc171-.png)

```xml
<Rectangle Width="150" Height="100" Canvas.Left="20" Canvas.Top="20">
    <!-- 线性渐变填充 -->
    <Rectangle.Fill>
        <LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
            <GradientStop Color="Yellow" Offset="0"/>
            <GradientStop Color="Red" Offset="1"/>
        </LinearGradientBrush>
    </Rectangle.Fill>

    <!-- 虚线边框 -->
    <Rectangle.Stroke>
        <SolidColorBrush Color="DarkOrange"/>
    </Rectangle.Stroke>
    <Rectangle.StrokeDashArray>
        <DoubleCollection>2,2</DoubleCollection>
    </Rectangle.StrokeDashArray>
</Rectangle>
```
![](https://www.diandiandidi.club:12346/api/note/getImage/15/b4714966-c67a-460c-963b-3466ef993907-.png)

## 5.Polyline 折线 
Polyline(多段线)是 WPF 中用于绘制由一系列相连直线段组成的形状控件

基本属性

|属性|	类型	|默认值|	说明|
|-|-|-|-|
|Points	|PointCollection	|null	|定义多段线各点的集合|
|Fill	|Brush	|null	|多段线封闭区域的填充画刷|
|Stroke|	Brush|	null|	多段线描边画刷|
|StrokeThickness	|double|	1|	描边粗细|
|FillRule	|FillRule	|EvenOdd|	填充规则(EvenOdd/Nonzero)|
|Stretch	|Stretch|	None	|填充模式|

边框样式属性

|属性	|说明|
|-|-|
|StrokeDashArray	|虚线模式(如 "2,1" 表示2单位实线+1单位空白)|
|StrokeDashCap	|虚线端点样式(Flat, Round, Square, Triangle)|
|StrokeLineJoin	|线段连接处样式(Miter, Bevel, Round)|
|StrokeMiterLimit|	斜接长度限制|

使用


```xml
<Polyline
    Points="10,100 100,10 200,100 300,10 400,100"
    Stroke="Black" StrokeThickness="2" />
```
![](https://www.diandiandidi.club:12346/api/note/getImage/15/c868bc1f-4f18-4272-9fcd-c26627ba0979-.png)

## 6.Polygon 多边形
Polygon(多边形)是 WPF 中用于绘制封闭多边形的形状控件

基本属性

|属性|	类型	|默认值	|说明|
|-|-|-|-|
|Points	|PointCollection	|null	|定义多边形顶点的集合|
|Fill	|Brush	|null|	多边形填充画刷|
|Stroke|	Brush|	null|	多边形边框画刷|
|StrokeThickness|	double|	1	|边框粗细|
|FillRule	|FillRule	|EvenOdd	|填充规则(EvenOdd/Nonzero)|
|Stretch|	Stretch	|None	|填充模式|

边框样式属性

|属性	|说明|
|-|-|
|StrokeDashArray	|虚线模式(如 "2,1" 表示2单位实线+1单位空白)|
|StrokeDashCap	|虚线端点样式(Flat, Round, Square, Triangle)|
|StrokeLineJoin	|线段连接处样式(Miter, Bevel, Round)|
|StrokeMiterLimit|	斜接长度限制|

使用

```xml
<Polygon
    Points="10,100 50,50 100,100 50,150"
    Fill="LightBlue"
    Stroke="Black"
    StrokeThickness="2" />
```
![](https://www.diandiandidi.club:12346/api/note/getImage/15/e7cbcbf4-fc92-40c8-88fa-2b5a25daf412-.png)
**FillRule**

EvenOdd 规则(默认),从点向任意方向发射射线,计算与多边形边相交的次数:奇数次:在内部,偶数次:在外部。

```xml
<Polygon Points="20,20 80,20 80,80 20,80 40,40 60,40 60,60 40,60"
         Fill="LightBlue" FillRule="EvenOdd"/>
```
![](https://www.diandiandidi.club:12346/api/note/getImage/15/c35879a8-db7b-461d-833b-049a623f248c-.png)

Nonzero 规则,计算环绕数:非零:在内部,零:在外部


```xml
<Polygon Points="20,20 80,20 80,80 20,80 40,40 60,40 60,60 40,60"
         Fill="LightGreen" FillRule="Nonzero"/>
```
![](https://www.diandiandidi.club:12346/api/note/getImage/15/46ec4369-26cf-4e63-9ea3-e2546e7fa4fc-.png)

对比Polyline

|特性	|Polyline	|Polygon|
|-|-|-|
|闭合	|不自动闭合|	自动闭合|
|填充|	必须手动闭合才能填充|	总是可以填充|
|用途|折线图、开放路径	|封闭形状、多边形|

## 7.Path 路径
Path(路径)是 WPF 中最强大和灵活的图形控件,继承自 Shape 类,能够绘制任意复杂的矢量图形。

### 7.1 Path 核心属性
基本属性

|属性|	类型	|默认值	|说明|
|-|-|-|-|
|Data	|Geometry|	null|	定义路径形状的几何图形|
|Fill	|Brush	|null	|路径封闭区域的填充画刷|
|Stroke|Brush	|null|	路径描边画刷|
|StrokeThickness|	double|	1	|描边粗细|
|FillRule	|FillRule	|EvenOdd|	填充规则(EvenOdd/Nonzero)|
|Stretch|Stretch|	None	|填充模式|

边框样式属性

|属性	|说明|
|-|-|
|StrokeDashArray	|虚线模式(如 "2,1" 表示2单位实线+1单位空白)|
|StrokeDashCap	|虚线端点样式(Flat, Round, Square, Triangle)|
|StrokeLineJoin|线段连接处样式(Miter, Bevel, Round)|
|StrokeMiterLimit|	斜接长度限制|

### 7.2 Path 几何数据(Data属性)
路径标记语法

```xml
<Path Data="M 起始点X,起始点Y 指令1 参数... 指令2 参数... Z"/>
```

常用指令:

- M - Move to (移动到)
- L - Line to (直线到)
- H - 水平线
- V - 垂直线
- C - 三次贝塞尔曲线
- Q - 二次贝塞尔曲线
- A - 椭圆弧
- Z - 闭合路径

几何对象类型

PathGeometry (路径几何)

```xml
<Path Fill="LightBlue">
    <Path.Data>
        <PathGeometry>
            <PathFigure StartPoint="10,50">
                <LineSegment Point="50,50"/>
                <ArcSegment Point="100,50" Size="50,50" SweepDirection="Clockwise"/>
                <BezierSegment Point1="100,100" Point2="50,100" Point3="10,50"/>
            </PathFigure>
        </PathGeometry>
    </Path.Data>
</Path>
```
![](https://www.diandiandidi.club:12346/api/note/getImage/15/a616d7f2-c1f6-4d1f-9e8e-281ba9b75c61-.png)
StreamGeometry (轻量路径几何)

```xml
<Path Fill="Red" Data="F1 M 10,10 L 100,10 100,100 10,80 Z"/>
```
![](https://www.diandiandidi.club:12346/api/note/getImage/15/feab944d-b7e9-44dc-8dac-c32a7434eb51-.png)
GeometryGroup (几何组合)


```xml
<Path Fill="Gold">
    <Path.Data>
        <GeometryGroup>
            <EllipseGeometry Center="50,50" RadiusX="40" RadiusY="40"/>
            <RectangleGeometry Rect="20,20 60,60"/>
        </GeometryGroup>
    </Path.Data>
</Path>
```
![](https://www.diandiandidi.club:12346/api/note/getImage/15/e55f8b67-359a-499a-980f-c2a3cffca692-.png)

© 2026 XyzRgb.space · 本页内容为个人学习记录,如有错漏欢迎指正。