WPF擴展屬性與依賴屬性詳解
一、依賴屬性(Dependency Property)詳解
1. 什么是依賴屬性?
依賴屬性是WPF框架的核心特性之一,它允許屬性值依賴于:
- 父元素的屬性值(繼承)
- 樣式和模板
- 動畫
- 數據綁定
- 資源查找
2. 依賴屬性的特點
- ??屬性值繼承??:子元素可以繼承父元素的屬性值
- ??屬性值變更通知??:自動通知UI更新
- ??屬性值存儲優化??:只在值改變時存儲實際值
- ??支持動畫和樣式??:可直接用于動畫和樣式設置
- ??值強制轉換??:可通過驗證和強制轉換器控制值
3. 定義依賴屬性的標準模式
using System.Windows;
using System.Windows.Controls;public class CustomControl : Control
{// 1. 定義依賴屬性標識符public static readonly DependencyProperty MyPropertyProperty =DependencyProperty.Register(nameof(MyProperty), // 屬性名稱typeof(string), // 屬性類型typeof(CustomControl), // 所屬類型new PropertyMetadata("默認值")); // 屬性元數據// 2. 定義CLR包裝屬性public string MyProperty{get => (string)GetValue(MyPropertyProperty);set => SetValue(MyPropertyProperty, value);}
}
4. 依賴屬性元數據選項
new PropertyMetadata(defaultValue: "默認值", // 默認值propertyChangedCallback: OnMyPropertyChanged, // 值改變回調coerceValueCallback: CoerceMyProperty, // 值強制回調isAnimationProhibited: false // 是否禁止動畫
);// 值改變回調示例
private static void OnMyPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{var control = (CustomControl)d;// 處理屬性變化邏輯
}// 值強制回調示例
private static object CoerceMyProperty(DependencyObject d, object baseValue)
{var control = (CustomControl)d;if (baseValue is string str && str.Length > 10){return str.Substring(0, 10); // 限制最大長度為10}return baseValue;
}
5. 附加屬性(Attached Property)
public class GridHelper
{// 定義附加屬性public static readonly DependencyProperty ColumnProperty =DependencyProperty.RegisterAttached("Column", // 屬性名稱typeof(int), // 屬性類型typeof(GridHelper), // 所屬類型new PropertyMetadata(0)); // 默認值// CLR包裝器 - 獲取方法public static int GetColumn(DependencyObject obj){return (int)obj.GetValue(ColumnProperty);}// CLR包裝器 - 設置方法public static void SetColumn(DependencyObject obj, int value){obj.SetValue(ColumnProperty, value);}
}
XAML中使用:
<Grid><Button GridHelper.Column="1" Content="附加屬性示例"/>
</Grid>
二、擴展屬性(Attached Property)詳解
1. 什么是擴展屬性?
擴展屬性(Attached Property)是一種特殊的依賴屬性,它:
- 可以附加到任何DependencyObject上
- 由非所有者類型定義
- 通常用于提供附加功能
2. 擴展屬性的應用場景
- ??布局控制??:如Grid.Row、Canvas.Left等
- ??行為附加??:為現有控件添加新功能
- ??樣式定制??:在不修改原有控件的情況下添加新屬性
3. 擴展屬性實現示例
示例1:簡單擴展屬性
public class DragDropHelper
{// 定義擴展屬性