2009-09-01 172 views
22

如何註冊一個依賴項屬性,其值是使用另一個依賴項屬性的值計算的?依賴屬性依賴於另一個

因爲.NET屬性包裝在運行時被WPF繞過,所以不應該在getter和setter中包含邏輯。對此的解決方案通常使用PropertyChangedCallback。但是那些聲明是靜態的。

例如,什麼是完成這一任務做作的正確方法:

public bool TestBool 
{ 
    get { return (bool)GetValue(TestBoolProperty); } 
    set 
    { 
    SetValue(TestBoolProperty, value); 
    TestDouble = ((value)?(100.0):(200.0)); // HERE IS THE DEPENDENCY 
    } 
} 
public static readonly DependencyProperty TestBoolProperty = 
    DependencyProperty.Register("TestBool", typeof(bool), typeof(ViewModel)); 

public double TestDouble 
{ 
    get { return ((double)GetValue(TestDoubleProperty)); } 
    set { SetValue(TestDoubleProperty, value); } 
} 
public static readonly DependencyProperty TestDoubleProperty = 
    DependencyProperty.Register("TestDouble", typeof(double), typeof(ViewModel)); 

只要依賴是不是圓的,有沒有辦法做到這一點適當的手段?

回答

21

嗯......我想你最好看看依賴屬性value coercion。這裏是一個強制的例子:

public class ViewModel : DependencyObject 
{ 
    public bool TestBool 
    { 
    get { return (bool)GetValue(TestBoolProperty); } 
    set { SetValue(TestBoolProperty, value); } 
    } 
    public static readonly DependencyProperty TestBoolProperty = 
    DependencyProperty.Register("TestBool", typeof(bool), typeof(ViewModel), new PropertyMetadata(false, OnTestBoolPropertyChanged)); 

    private static void OnTestBoolPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
    var vm = (ViewModel)d; 
    vm.CoerceValue(TestDoubleProperty); 
    } 

    public double TestDouble 
    { 
    get { return ((double)GetValue(TestDoubleProperty)); } 
    set { SetValue(TestDoubleProperty, value); } 
    } 
    public static readonly DependencyProperty TestDoubleProperty = 
    DependencyProperty.Register("TestDouble", typeof(double), typeof(ViewModel), new PropertyMetadata(0.0, null, OnCoerceTestDouble)); 

    private static object OnCoerceTestDouble(DependencyObject d, object baseValue) 
    { 
    var vm = (ViewModel) d; 
    var testBool = vm.TestBool; 
    return ((testBool) ? (100.0) : (200.0)); 
    } 
} 
+0

像你所做的那樣使用'CoerceValueCallback'與直接更改另一個依賴屬性的'PropertyChangedCallback'中的依賴項屬性的優點是什麼?我從你鏈接的文檔中收集到你的是更合適的方法,但我對實際的區別很好奇。 – Gregyski 2009-09-01 22:03:36

+1

那麼,爲了名字夫婦:它不打破綁定到這個屬性(即如果這個屬性是綁定表達的目標,它會在強制之後工作,但會在顯式設置後丟失);它在依賴屬性值解析中具有更高的優先級(即,如果你說PropA =「Something」並不意味着PropA ==「Something」,因爲強制可以忽略該賦值);它記住你的財產的舊值(即下次調用CoerceValue()時,你將得到TestDouble的原始值,而不是本地設置的值) – Anvaka 2009-09-01 22:38:02

1

你確實是對的,你應該使用PropertyChangedCallback。這是如何:

public bool TestBool 
{ 
    get { return (bool)GetValue(TestBoolProperty); } 
    set 
    { 
    SetValue(TestBoolProperty, value); 
    } 
} 
public static readonly DependencyProperty TestBoolProperty = 
    DependencyProperty.Register("TestBool", typeof(bool), typeof(ViewModel), 
    new PropertyMetadata(false, new PropertyChangedCallback(OnTestBoolChanged))); 

private static void OnTestBoolChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
{ 
    ViewModel vm = d as ViewModel; 
    vm.TestDouble = value ? 100.0 : 200.0; 
} 

public double TestDouble 
{ 
    get { return ((double)GetValue(TestDoubleProperty)); } 
    set { SetValue(TestDoubleProperty, value); } 
} 
public static readonly DependencyProperty TestDoubleProperty = 
    DependencyProperty.Register("TestDouble", typeof(double), typeof(ViewModel)); 
+0

謝謝opedog。在我的調查中,我愚蠢地未能檢查傳入「PropertyChangedCallback」的內容。我調整了我的測試項目,使用這種方法,它的工作。接下來我將嘗試Anvaka的解決方案。 – Gregyski 2009-09-01 22:18:21