WPF自定義控件的三種方式


簡介: 某些場景下,我們確實需要創建新的控件。此時,理解 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);
}

此示例代碼來自官網控件創作概述 - WPF .NET Framework | Microsoft Docs ,其中定義一個名為 ValueProperty的依賴屬性(DependencyProperty ),通過調用DependencyProperty.Register向屬性系統注冊屬性名稱Value,其中包含了三個核心信息:

  • 屬性的名稱Value
  • 屬性的類型decimal
  • 擁有屬性的類型NumericUpDown
  • 屬性元數據信息(FrameworkPropertyMetadata)

其中,屬性的元數據包含屬性的默認值, CoerceValueCallback 和 PropertyChangedCallback 。 CoerceValue 確保 Value 大於或等於 MinValue 且小於或等於 MaxValue。另外,PropertyChangedCallback 回調方法為 OnValueChanged ,來處理屬性值變化的相關邏輯,后面通過RoutedPropertyChangedEventArgs創建了一個路由事件,並通過control.OnValueChanged(e)來進行觸發。

原文鏈接
本文為阿里雲原創內容,未經允許不得轉載。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM