<UserControl x:Class="HelloWorld.Controls.Widget"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:HelloWorld.Controls"
mc:Ignorable="d"
x:Name="userControl"
FontSize="30"
Foreground="#666666"
BorderBrush="#8CDDCD"
d:DesignHeight="450"
d:DesignWidth="800">
<Border BorderBrush="{Binding ElementName=userControl,Path=BorderBrush}">
<Border.Style>
<Style TargetType="Border">
<Setter Property="Padding" Value="10"/>
<Setter Property="Background" Value="White"/>
<Setter Property="BorderBrush" Value="#8CDDCD"/>
<Setter Property="BorderThickness" Value="0 3 0 0"/>
<Setter Property="Margin" Value="5"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#F7F9F9"/>
</Trigger>
</Style.Triggers>
</Style>
</Border.Style>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="{Binding Value}"
Foreground="{Binding ElementName=userControl,Path=Foreground}"
FontSize="{Binding ElementName=userControl,Path=FontSize}" />
<TextBlock Grid.Row="1" Grid.Column="0" Text="{Binding Title}"
Foreground="{Binding ElementName=userControl,Path=Foreground}"
FontSize="14" TextWrapping="Wrap"/>
<TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding Icon}"
Foreground="{Binding ElementName=userControl,Path=BorderBrush}"
FontSize="26" Grid.RowSpan="2" VerticalAlignment="Center"/>
</Grid>
</Border>
</UserControl>
元素名称/属性路径 |
属性/绑定关系 |
值/配置说明 |
UserControl |
x:Class |
HelloWorld.Controls.Widget |
|
mc:Ignorable |
d |
|
x:Name |
userControl |
|
FontSize |
30 |
|
Foreground |
#666666 |
|
BorderBrush |
#8CDDCD |
|
d:DesignHeight |
450 |
|
d:DesignWidth |
800 |
Border |
BorderBrush |
{Binding ElementName=userControl, Path=BorderBrush} |
Border.Style |
TargetType |
Border |
Style.Setter[Padding] |
Value |
10 |
Style.Setter[Background] |
Value |
White |
Style.Setter[BorderBrush] |
Value |
#8CDDCD |
Style.Setter[BorderThickness] |
Value |
0 3 0 0 |
Style.Setter[Margin] |
Value |
5 |
Style.Trigger(IsMouseOver) |
Property+Value |
Background→#F7F9F9 |
Grid |
ColumnDefinitions |
2列(第2列Width="auto") |
|
RowDefinitions |
2行均分 |
TextBlock[0] |
Grid.Row+Column |
(0,0) |
|
Text |
{Binding Value} |
|
Foreground |
{Binding ElementName=userControl.Foreground} |
|
FontSize |
{Binding ElementName=userControl.FontSize} |
TextBlock[1] |
Grid.Row+Column |
(1,0) |
|
Text |
{Binding Title} |
|
FontSize |
14 |
|
TextWrapping |
Wrap |
TextBlock[2] |
Grid.Row+Column |
(0,1) |
|
Text |
{Binding Icon} |
|
Foreground |
{Binding ElementName=userControl.BorderBrush} |
|
FontSize |
26 |
|
Grid.RowSpan |
2 |
|
VerticalAlignment |
Center |
[控件初始化]
↓
1. 加载依赖属性
├─ 设计时属性(d:*)仅在Blend中生效
└─ 运行时属性(mc:Ignorable过滤d命名空间)
↓
2. 构建视觉树
├─ 创建Border容器
│ └─ 应用动态样式
│ ├─ 默认样式配置(边距/背景/边框)
│ └─ 鼠标悬停交互逻辑
└─ 初始化Grid布局
├─ 创建2x2单元格
└─ 部署3个数据绑定TextBlock
↓
3. 数据绑定通道
├─ Value显示区:双向绑定业务数据
├─ Title显示区:单行文本绑定
└─ Icon显示区:特殊符号绑定
↓
4. 交互响应机制
└─ 当鼠标悬停时:
├─ 触发Border背景色渐变(#F7F9F9)
└─ 保持边框动画连续性(BorderThickness动态保持)
↓
5. 渲染管线
├─ 测量阶段(Measure):根据auto列宽计算图标区域
└─ 排列阶段(Arrange):保证文本换行正确布局
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace HelloWorld.Controls
{
/// <summary>
/// Widget.xaml 的交互逻辑
/// </summary>
public partial class Widget : UserControl
{
public Widget()
{
InitializeComponent();
DataContext = this;
}
public string Icon
{
get { return (string)GetValue(IconProperty); }
set { SetValue(IconProperty, value); }
}
public static readonly DependencyProperty IconProperty =
DependencyProperty.Register("Icon", typeof(string), typeof(Widget), new PropertyMetadata("☻"));
public string Title
{
get { return (string)GetValue(TitleProperty); }
set { SetValue(TitleProperty, value); }
}
public static readonly DependencyProperty TitleProperty =
DependencyProperty.Register("Title", typeof(string), typeof(Widget), new PropertyMetadata("请输入标题"));
public string Value
{
get { return (string)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
public static readonly DependencyProperty ValueProperty