依赖属性依赖于另一个

时间:2009-09-01 20:31:17

标签: wpf dependency-properties linkage

如何注册依赖属性,该属性的值是使用另一个依赖属性的值计算的?

因为WPF在运行时绕过了.NET属性包装器,所以不应该在getter和setter中包含逻辑。解决方案通常是使用PropertyChangedCallback s。但那些被宣布为静态。

例如,完成这项设计任务的正确方法是什么:

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));

只要依赖关系不是循环的,是否有适当的方法来实现这一点?

2 个答案:

答案 0 :(得分: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));
  }
}

答案 1 :(得分: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));