2012-05-14 4 views
6

In parole semplici, posso creare 2 proprietà di dipendenza in un controllo WPF e inserire il codice in ogni notifica di modifica delle proprietà per modificare l'altra proprietà (ad esempio PropA set di modifiche PropB e PropB cambia set PropA).Re-entrancy delle proprietà dipendenti (o: perché funziona?)

Mi aspetto che questo scompaia da solo, ma WPF sembra gestirlo bene. Questo è in realtà molto utile per i miei scopi ma non riesco a trovare questo comportamento documentato da nessuna parte.

Quindi cosa sta succedendo? La proprietà di dipendenza WPF cambia la guardia del sistema di notifica contro la rientranza?

codice Rappresentante segue:

XAML:

<Window x:Class="WPFReentrancy1.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525"> 
    <Grid> 
     <TextBox Text="{Binding PropB, UpdateSourceTrigger=PropertyChanged}"/> 

    </Grid> 
</Window> 

codice dietro:

public partial class MainWindow : Window 
    { 

     public string PropA 
     { 
      get { return (string)GetValue(PropAProperty); } 
      set { SetValue(PropAProperty, value); } 
     } 
     public static readonly DependencyProperty PropAProperty = 
         DependencyProperty.Register("PropA", typeof (string), typeof (MainWindow),new UIPropertyMetadata("0", PropAChanged)); 


     public string PropB 
     { 
      get { return (string)GetValue(PropBProperty); } 
      set { SetValue(PropBProperty, value); } 
     } 

     public static readonly DependencyProperty PropBProperty = 
      DependencyProperty.Register("PropB", typeof (string), typeof (MainWindow), new UIPropertyMetadata("", PropBChanged)); 

     private static void PropBChanged(DependencyObject lDependencyObject, DependencyPropertyChangedEventArgs lDependencyPropertyChangedEventArgs) 
     { 
      ((MainWindow) lDependencyObject).PropA = (string) lDependencyPropertyChangedEventArgs.NewValue; 
     } 


     private static void PropAChanged(DependencyObject lDependencyObject, DependencyPropertyChangedEventArgs lDependencyPropertyChangedEventArgs) 
     { 
      ((MainWindow) lDependencyObject).PropB = 
       double.Parse((string) lDependencyPropertyChangedEventArgs.NewValue).ToString("0.000"); 
     } 


     public MainWindow() 
     { 
      InitializeComponent(); 
      DataContext = this; 
      PropA = "1.123"; 
     } 
    } 
+0

non hanno risposta concreta, ma supponiamo che: considerando il WPF fanno flusso ricorsivo lungo albero dell'elemento e le proprietà associate anche, solo che "salva "(per evento concreto) che ha già passato e notificato, quindi saltateli se li incontrate un'altra volta. – Tigran

risposta

3

Quei callback vengono sparati solo se la proprietà cambiato, il codice fa non creare un ciclo infinito di valori diversi.

Prova questo e si otterrà un SO eccezione:

private static readonly Random _random = new Random(); 
private static void PropBChanged(DependencyObject lDependencyObject, DependencyPropertyChangedEventArgs lDependencyPropertyChangedEventArgs) 
{ 
    ((MainWindow)lDependencyObject).PropA = _random.Next().ToString(); 
} 
private static void PropAChanged(DependencyObject lDependencyObject, DependencyPropertyChangedEventArgs lDependencyPropertyChangedEventArgs) 
{ 
    ((MainWindow)lDependencyObject).PropB = _random.Next().ToString(); 
} 
+0

Immagino che l'indizio sia nel nome! Stavo assumendo che la notifica sarebbe stata licenziata a prescindere, ma ho appena fatto un test rapido e sembra che questo sia esattamente ciò che sta accadendo. – MarcE