wpf user-controls dependency-properties propertychanged

wpf - PropertyChangedCallback de Dependency Properties no se llama



user-controls dependency-properties (1)

Si tiene un control de usuario propio con DependencyProperty y el método de devolución de llamada correspondiente, como a continuación:

public partial class PieChart : UserControl { public static readonly DependencyProperty RatesProperty = DependencyProperty.Register("Rates", typeof(ObservableCollection<double>), typeof(PieChart), new PropertyMetadata(new ObservableCollection<double>() { 1.0, 1.0 }, new PropertyChangedCallback(OnRatesChanged))); [...] public static void OnRatesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { ((PieChart)d).drawChart(); }

Cuando utilizo este control de usuario, ato una ObservableCollection llamada "Rates" a RatesProperty. Las tasas y los métodos relacionados se ven así:

private ObservableCollection<double> rates; public ObservableCollection<double> Rates { get { return this.rates; } set { if (this.rates != value) { this.rates = value; OnPropertyChanged("Rates"); } } } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged(string propertyName) { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); }

Cuando cambio las tasas de ObservableCollection (por ejemplo, con this.Rates = new ObservableCollection<double>() { 1.0, 2.0 } ) el método OnRatesChanged () del control de usuario se llama como se esperaba. Pero cuando ejecuto lo siguiente, no se llama:

this.Rates[0] = (double)1; this.Rates[1] = (double)2; OnPropertyChanged("Rates");

Esperé que cuando activara el evento PropertyChanged con el nombre de propiedad correcto, siempre se llamara a la devolución de llamada correspondiente en el control de usuario. ¿Es eso incorrecto? Encontré este hilo: Obtener PropertyChangedCallback de una propiedad de dependencia siempre: Silverlight que cubre Silverlight, pero creo que lo mismo es cierto en WPF.

Entonces, el Framework en segundo plano comprueba si la propiedad enlazada (en mi ejemplo, "Rates") cambió y solo si cambió, llama a la devolución de llamada asociada, ¿correcto? Por lo tanto, cambiar los elementos de mi colección no tiene ningún efecto, ¿siempre tengo que cambiar la colección completa?

¡Gracias!


Su conclusión es correcta, su OnRatesChanged llamada OnRatesChanged solo se OnRatesChanged cuando la propiedad de dependencia de Rates esté configurada en una nueva colección (o null).

Para recibir notificaciones sobre cambios en la colección, también debe registrar NotifyCollectionChangedEventHandler :

private static void OnRatesChanged( DependencyObject d, DependencyPropertyChangedEventArgs e) { var pieChart = (PieChart)d; var oldRates = e.OldValue as INotifyCollectionChanged; var newRates = e.NewValue as INotifyCollectionChanged; if (oldRates != null) { oldRates.CollectionChanged -= pieChart.OnRatesCollectionChanged; } if (newRates != null) { newRates.CollectionChanged += pieChart.OnRatesCollectionChanged; } pieChart.drawChart(); } private void OnRatesCollectionChanged( object sender, NotifyCollectionChangedEventArgs e) { switch (e.Action) { ... } drawChart(); }