如何覆寫相依性屬性的設值方法

Feb 18, 2019




前言

stackOverflow 看到有人問:How do i override a dependency property set in XAML to the value i need to in codebehind ,提問的苦主希望就算使用者在 XAML 中設定,也要能夠強制設定某個相依性屬性的值,苦主做過的嘗試是在建構元設定屬性值,但是仍會被使用者設定值給覆蓋。

不論為什麼苦主需要強制設定某個公開的相依性屬性的值,重要的是這篇的答覆說明了對於相依性屬性的兩個操作:

  • 如何設定相依屬性值的預設值
  • 如何在依相依屬性值進行處理

透過自訂一個 UserControl 的例子來簡單說明,例如自訂 UserControl 如下,這個使用者控制包含一個按鍵,而按鍵包含一個圖形:

<usercontrol>
    <Button>
        <Image Source="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}, Path=IconPath}"
        >
    </Button>
</usercontrol>

接著在這個使用者控制項的後置程式碼中,定義對應的 相依性屬性 IconPath 如下:

public string IconPath
    {
        get { return (string)GetValue(IconPathProperty); }
        set { SetValue(IconPathProperty, value); }
    }

private static DependencyProperty IconPathProperty =
    DependencyProperty.Register(nameof(IconPath), typeof(string),
        typeof(RibbonButton), new PropertyMetadata(default(string)));

然後在客戶端,只要適當的引用名稱空間就可以透過 XAML 方便的建立按鍵,如下所示:

<usercontrol 
    xmlns:uc="namespace.of.RebinButton" >
    <uc:RibbonButton IconPath="path.of.icon.file" />
</usercontrol>

設定相依性屬性 ( dependency property ) 預設值

若是希望在客戶端未指定 IconPath 時,自動給予預設值,讓按鍵的圖形不會因為客戶端沒有給定而開天窗,可以在使用者控制項的建構元透過 DependencyObject.SetValue 方法設定屬性值。

public MyButton()
{
    InitializeComponent();
    SetValue(IconPathProperty, "default.picture.path");
}

依據客戶端設定值進行處理

有時需要對於客戶端的設定值進行邏輯處理時,就需要透過相依性屬性的 PropertyChanged 事件來進行。

private static DependencyProperty IconPathProperty =
    DependencyProperty.Register(nameof(IconPath), typeof(object),
        typeof(RibbonButton), new PropertyMetadata(default(object), OnRecordContainerGenerationModeChanged));

private static void OnRecordContainerGenerationModeChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
    //處理自訂判斷邏輯。
}