簡介: 某些場景下,我們確實需要創建新的控件。此時,理解 WPF不同控件的創建方法就顯得非常重要。 WPF 提供3個用於創建控件的方法,每個方法都提供不同的靈活度。
WPF控件可以通過數據模型(DataTemplate)、樣式(Style)、控件模板(ControlTemplate)和觸發器(Trigger)等機制減少創建新控件的需要。 但是,某些場景下,我們確實需要創建新的控件。此時,理解 WPF不同控件的創建方法就顯得非常重要。 WPF 提供3個用於創建控件的方法,每個方法都提供不同的靈活度,下面分別進行介紹。
1 基於UserControl 創建
創建控件最簡單一個方法就是基於UserControl 類進行繼承。此時,我們可以將WPF中現有組件添加到 UserControl 畫布上來,並將各組件進行命名,這樣可以在后台進行組件訪問和使用事件處理程序。 UserControl 可以利用豐富內容、樣式和觸發器的優點。 但是,繼承自 UserControl的控件,將無法使用 DataTemplate 或 ControlTemplate 來自定義UI外觀。
2 基於Control 創建
基於Control類創建自定義控件的方法 ,可以使用模板定義UI外觀。而且可以將后台邏輯和前端樣式展現上進行分離。 另外,這種方法創建的自定義控件,還支持使用命令和綁定來完成相關動作,實現類似事件的效果。最后,控件可以重新定義ControlTemplate和DataTemplate來自定義UI外觀。控件支持不同的主題。
3 基於 FrameworkElement 創建
一般來說,基於 UserControl 或 Control 創建的自定義控件即可完成業務需求,但是,在一些特殊情況下,簡單的元素組合不能滿足自定義控件的UI外觀要求。此時,基於FrameworkElement 創建自定義控件是一個很好的選擇。
基於FrameworkElement創建控件,一方面可以通過重寫的 OnRender 方法進行UI的直接繪制。 另一方面,可以通過自定義元素組合來可視化編寫組件的外觀。
4 依賴屬性
WPF 可以通過設置控件的屬性來更改其外觀和行為。其中的依賴屬性可以讓自定義控件執行以下操作:
- 在樣式中設置該屬性。
- 將該屬性綁定到數據源。
- 使用動態資源作為該屬性的值。
- 對該屬性進行動畫處理。
如果控件的屬性支持以上任一功能,應將該屬性實現為依賴屬性。 下面給出一個微軟官方文檔的示例程序:
/// <summary> /// Identifies the Value dependency property. /// </summary> public static readonly DependencyProperty ValueProperty = DependencyProperty.Register( "Value", typeof(decimal), typeof(NumericUpDown), new FrameworkPropertyMetadata(MinValue, new PropertyChangedCallback(OnValueChanged), new CoerceValueCallback(CoerceValue))); /// <summary> /// Gets or sets the value assigned to the control. /// </summary> public decimal Value { get { return (decimal)GetValue(ValueProperty); } set { SetValue(ValueProperty, value); } } private static object CoerceValue(DependencyObject element, object value) { decimal newValue = (decimal)value; NumericUpDown control = (NumericUpDown)element; newValue = Math.Max(MinValue, Math.Min(MaxValue, newValue)); return newValue; } private static void OnValueChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) { NumericUpDown control = (NumericUpDown)obj; RoutedPropertyChangedEventArgs<decimal> e = new RoutedPropertyChangedEventArgs<decimal>( (decimal)args.OldValue, (decimal)args.NewValue, ValueChangedEvent); control.OnValueChanged(e); }
此示例代碼來自官網
- 屬性的名稱Value
- 屬性的類型decimal
- 擁有屬性的類型NumericUpDown
- 屬性元數據信息(FrameworkPropertyMetadata)
其中,屬性的元數據包含屬性的默認值, CoerceValueCallback 和 PropertyChangedCallback 。 CoerceValue 確保 Value 大於或等於 MinValue 且小於或等於 MaxValue。另外,PropertyChangedCallback 回調方法為 OnValueChanged ,來處理屬性值變化的相關邏輯,后面通過RoutedPropertyChangedEventArgs創建了一個路由事件,並通過control.OnValueChanged(e)來進行觸發。
原文鏈接
本文為阿里雲原創內容,未經允許不得轉載。