2.3 属性与事件
属性系统:依赖属性与CLR属性
依赖属性(Dependency Properties)
- 定义:WPF特有的属性系统,支持数据绑定、动画、样式等高级功能
- 特点:
- 通过
DependencyProperty.Register()静态方法注册 - 属性值继承(如字体设置)
- 自动处理资源引用和样式应用
- 通过
- 示例:
public static readonly DependencyProperty IsHighlightedProperty = DependencyProperty.Register("IsHighlighted", typeof(bool), typeof(MyControl)); public bool IsHighlighted { get { return (bool)GetValue(IsHighlightedProperty); } set { SetValue(IsHighlightedProperty, value); } }
CLR属性
- 传统.NET属性,适合简单场景
- 与依赖属性对比:
特性 依赖属性 CLR属性 数据绑定支持 完整支持 有限支持 动画支持 是 否 默认值 可设置 需手动初始化
事件系统:路由事件
路由事件类型
- 冒泡事件(Bubbling)
- 从子元素向父元素传递(如
MouseDown)
- 从子元素向父元素传递(如
- 隧道事件(Tunneling)
- 从父元素向子元素传递(前缀
Preview,如PreviewMouseDown)
- 从父元素向子元素传递(前缀
- 直接事件(Direct)
- 仅触发在源元素(类似WinForms事件)
事件处理示例
<StackPanel Button.Click="StackPanel_Click">
<Button Content="按钮1" Name="btn1"/>
<Button Content="按钮2" Name="btn2"/>
</StackPanel>
private void StackPanel_Click(object sender, RoutedEventArgs e)
{
var sourceButton = e.Source as Button;
MessageBox.Show($"点击了 {sourceButton?.Name}");
}
属性与事件的XAML语法
属性设置方式
- 直接赋值:
<Button Content="确定" Background="LightBlue"/> - 属性元素语法:
<Button> <Button.Background> <LinearGradientBrush>...</LinearGradientBrush> </Button.Background> </Button> - 标记扩展:
<Button Content="{Binding UserName}"/>
事件绑定
- 标准事件处理:
<Button Click="Button_Click"/> - 命令绑定(MVVM模式):
<Button Command="{Binding SaveCommand}"/>
最佳实践
- 优先使用依赖属性实现自定义控件属性
- 合理选择路由事件策略(冒泡/隧道)
- 避免在XAML中编写复杂逻辑,使用ValueConverter转换数据
- 事件处理中注意
e.Handled属性的使用
常见问题
Q:为什么属性更改没有触发UI更新?
A:检查是否实现了INotifyPropertyChanged接口(CLR属性)或正确使用SetValue()(依赖属性)Q:如何阻止事件继续传递?
A:在事件处理中设置e.Handled = true
专家提示:WPF的属性系统通过
PropertyMetadata可以定义属性变更回调,这是实现复杂交互逻辑的关键机制。
