wpf dependency property binding



PropertyChangedCallback des propriétés de dépendance n'est pas appelé (1)

Si vous avez un propre contrôle utilisateur avec DependencyProperty et la méthode de rappel correspondante comme ci-dessous:

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

Lorsque j'utilise ce contrôle utilisateur, je lie une ObservableCollection appelée "Rates" à RatesProperty. Les tarifs et les méthodes associées ressemblent à ceci:

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

Quand je change les ObservableCollection Rates (par exemple avec this.Rates = new ObservableCollection<double>() { 1.0, 2.0 } ) la méthode OnRatesChanged () du contrôle utilisateur est appelée comme attendue. Mais quand j'exécute ce qui suit, il n'est pas appelé:

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

Je m'attendais à ce que lorsque je déclenche l'événement PropertyChanged avec le nom de propriété correct, le rappel correspondant dans le contrôle utilisateur est toujours appelé. Est-ce faux? J'ai trouvé ce fil: Obtenir PropertyChangedCallback d'une propriété de dépendance toujours - Silverlight qui couvre silverlight mais je pense alors que la même chose est vraie dans WPF.

Ainsi, le Framework en arrière-plan vérifie si la propriété liée (dans mon exemple "Rates") a changé et seulement si elle a changé, elle appelle le callback associé, correct? Changer les éléments de ma collection n'a donc aucun effet, je dois toujours changer la collection complète?

Je vous remercie!


Votre conclusion est correcte, votre rappel OnRatesChanged ne sera appelé que lorsque la propriété de dépendance Rates est définie sur une nouvelle collection (ou null).

Pour être averti des modifications apportées à la collection, vous devez également enregistrer 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();
}