2010-07-28 64 views
0

我正在使用滑塊實現用戶可調整的Effect,並且在滑塊旁邊有一個重置按鈕。這個想法是允許用戶重置爲元數據中指定的默認值Effect的屬性。如何將DependencyProperty重置爲XAML中的默認值

我認爲在XAML中做這件事可能是微不足道的。

+5

由於XAML是不是程序這個問題沒有弄懂很大。嘗試闡述你爲什麼想要這樣做? – AnthonyWJones 2010-07-28 10:25:35

+0

以及在什麼時間,基於某些條件,觸發器等? – akjoshi 2010-07-28 10:33:24

回答

4

相關屬性並沒有真正的默認值。如果依賴項屬性沒有本地值,則它將通過值繼承或強制獲取其值,具體取決於屬性的實現方式。

您無法真正擺脫屬性在XAML中的本地價值 - 這需要您在屬性上調用ClearValue,並且無法找到該對象並以聲明方式調用該對象。但只要房產通過價值繼承(而不是價值強制)來獲得價值 - 您可以通過將房產與其在適當的祖先繼承的房產相結合來實現基本上相同的功能

例如,下面是一個樣式你會用它來創建一個ListBox,設置所有項目的前景顏色選擇:

<ListBox.ItemContainerStyle> 
    <Style TargetType="ListBoxItem"> 
    <Setter Property="Foreground" Value="Red"/> 
    <Style.Triggers> 
     <Trigger Property="IsSelected" Value="True"> 
      <Setter 
       Property="Foreground" 
       Value="{Binding 
        RelativeSource={RelativeSource FindAncestor, AncestorType=ListBox}, 
        Path=Foreground}" /> 
     </Trigger> 
    </Style.Triggers> 
    </Style> 
</ListBox.ItemContainerStyle> 

這基本上明確通過結合實現價值傳承。這意味着ListBoxItem.Foreground財產現在具有本地值,並且只要您更改ListBoxForeground屬性它的綁定更新ListBoxItem.Foreground而不是依賴屬性系統。如果您的ListBox中有成千上萬個物品,這可能很重要。但是在大多數現實世界的情況下,你永遠都不會注意到這種差異。

+0

問題是隻適用於WPF和SL5。 SL4沒有RelativeSource = FindAncestor – 2011-10-03 17:47:21

+0

您不鼓勵使用ClearValue。所以我就是這麼做的。 – CyberFox 2017-08-31 07:56:26

1

爲了避免邏輯週期,WPF強烈抵制嘗試將DependencyProperty值設置爲其當前值。在初始化期間,這是一個問題,您希望觸發相關邏輯,根據記錄在元數據中的DefaultValue,爲各個相關屬性中的每一個設置第一次爲設置的所有內容。 WPF不會這樣做,因爲作爲一種特殊情況,所有這些屬性都已經獲得了它們的默認值,而沒有執行過任何這樣的邏輯。

據我所知,沒有組合InvalidateProperty,CoerceValueClearValue會說服WPF做這項工作。一個微不足道的解決辦法是以某種方式召喚一個有希望的無害的非默認值來改變它,然後在ClearValue之後重置該值。然而,這看起來很詭異,因爲確定一個「無害」價值可能並不實際。也許更糟的是,這種方法會不必要地影響依賴關係圖兩次,而不是一次。

作爲一種可能更爲優雅的解決方案,您可以在每個相關對象的構造函數中調用以下擴展方法,以手動調用每個DependencyProperty需要傳播更改的PropertyChanged邏輯。該助手將根據存儲在各個元數據中的默認值觸發後續更改。

public static void ResetValue(this DependencyObject _this, DependencyProperty dp) 
{ 
    var md = dp.GetMetadata(_this.GetType()); 
    if (_this.GetValue(dp).Equals(md.DefaultValue)) 
    { 
     var args = new DependencyPropertyChangedEventArgs(dp, DependencyProperty.UnsetValue, md.DefaultValue); 
     md.PropertyChangedCallback(_this, args); 
    } 
    else 
     _this.ClearValue(dp); 
} 

如圖所示,該功能包括檢查,看是否ClearValue實際上將是有效的,因此超越初始化場景,您也可以在一般的使用這個功能作爲替代ClearValue。爲了演示的清晰,此方法不驗證主機對象實際上是否暴露了任何屬性更改邏輯,但這將是一個簡單的更改。在C#7,例如:

 // ... 
     md.PropertyChangedCallback?.Invoke(_this, args); 

用法示例在類:

class MyClass : DependencyObject 
{ 
    public static readonly DependencyProperty MyDp = /* ... */ 

    public MyClass() 
    { 
     this.ResetValue(MyDp); 
     /* ... */ 
    } 
}; 
相關問題