26 votes

Propriété de dépendance dépendante d'une autre

Comment peut-on enregistrer une propriété de dépendance dont la valeur est calculée en utilisant la valeur d'une autre propriété de dépendance ?

Comme les wrappers de propriétés .NET sont contournés par WPF à l'exécution, il ne faut pas inclure de logique dans les accesseurs et les mutateurs. La solution à cela est généralement d'utiliser des PropertyChangedCallback. Mais ceux-ci sont déclarés comme statiques.

Par exemple, quelle est la bonne façon d'accomplir cette tâche artificielle :

public bool TestBool
{
  get { return (bool)GetValue(TestBoolProperty); }
  set 
  { 
    SetValue(TestBoolProperty, value);
    TestDouble = ((value)?(100.0):(200.0)); // ICI EST LA DÉPENDANCE
  }
}
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));

Tant que la dépendance n'est pas circulaire, existe-t-il un moyen approprié d'accomplir ceci ?

26voto

Anvaka Points 9296

Hmmm... Je pense que vous feriez mieux de regarder les propriétés de dépendance coercition de valeur. Voici un exemple avec coercition :

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

1voto

mbello Points 172

Vous avez en fait raison, vous devriez utiliser PropertyChangedCallback. Voici comment :

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X