2017-04-21 3 views
1

Dans le cas du contrôle personnalisé comme ce qui suit, comment ajouter PropertyChangedCallback pour DependencyProperty IsEnabledProperty hérité?WPF - contrôle personnalisé - Hérité DependencyProperty et PropertyChangedCallback

public class MyCustomControl : ContentControl 
{ 
     // Custom Dependency Properties 

     static MyCustomControl() 
     { 
      DefaultStyleKeyProperty.OverrideMetadata(typeof(MyCustomControl), new FrameworkPropertyMetadata(typeof(MyCustomControl))); 
      // TODO (?) IsEnabledProperty.OverrideMetadata(typeof(MyCustomControl), new PropertyMetadata(true, CustomEnabledHandler)); 
     } 

     public CustomEnabledHandler(DependencyObject d, DependencyPropertyChangedEventArgs e) 
     { 
      // Implementation 
     } 
} 

Oui, il y a une autre option comme écouter la IsEnabledChangeEvent

public class MyCustomControl : ContentControl 
{ 
     public MyCustomControl() 
     { 
      IsEnabledChanged += … 
     } 
} 

Mais je n'aime pas le gestionnaire d'événements de registre d'approche dans tous les cas. Je préfère donc la substitution des métadonnées.

+0

Qu'est-ce qui ne va pas avec OverrideMetadata? Notez cependant que cela devrait être FrameworkPropertyMetadata au lieu de PropertyMetadata. – Clemens

+0

@Clemens Si j'utilise ce contrôle dans ** XAML **, j'obtiens une erreur: _Metadata override et les métadonnées de base doivent être du même type ou du même type dérivé._ Je l'essaie aussi avec 'FrameworkPropertyMetadata'. – David

+0

Fonctionne avec FrameworkPropertyMetadata. Essaye encore. – Clemens

Répondre

2

Cela fonctionne:

static MyCustomControl() 
{ 
    DefaultStyleKeyProperty.OverrideMetadata(typeof(MyCustomControl), 
     new FrameworkPropertyMetadata(typeof(MyCustomControl))); 

    IsEnabledProperty.OverrideMetadata(typeof(MyCustomControl), 
     new FrameworkPropertyMetadata(IsEnabledPropertyChanged)); 
} 

private static void IsEnabledPropertyChanged(
    DependencyObject obj, DependencyPropertyChangedEventArgs e) 
{ 
    Debug.WriteLine("{0}.IsEnabled = {1}", obj, e.NewValue); 
} 
+0

Oui, c'est ce que je cherchais, merci. Une autre question, s'il vous plaît. Le comportement d'origine pour 'IsEnabledProperty' fonctionne toujours? Cela ajoute seulement un autre rappel, non? – David

+0

Exactement, mais cela est également bien expliqué dans la documentation en ligne ... – Clemens

1

But I don't like the approach register event handler in every instance.

Vous n'avez pas besoin de le faire dans tous les cas. Vous pouvez le faire dans le constructeur de votre classe personnalisée:

public class MyCustomControl : ContentControl 
{ 
    static MyCustomControl() 
    { 
     DefaultStyleKeyProperty.OverrideMetadata(typeof(MyCustomControl), new FrameworkPropertyMetadata(typeof(MyCustomControl))); 
    } 

    public MyCustomControl() 
    { 
     IsEnabledChanged += (s, e) => { /* do something */ }; 
    } 
} 

Une autre option est d'utiliser un DependencyPropertyDescriptor à peform toute action en réponse à une modification d'une propriété de dépendance existant: https://blog.magnusmontin.net/2014/03/31/handling-changes-to-dependency-properties/

+0

Oui, j'ai pensé cette approche. Je regarde aussi 'DependencyPropertyDescriptor' - mais quand même - je pense que pour chaque instance de' MyCustomControl' on ajoute une référence pour changer l'évènement. – David

+0

Bien sûr. De quelle autre manière chaque instance est-elle supposée être capable de gérer le changement ...? Et que pensez-vous que OverrideMetdata fait avec votre CustomEnabledHandler? – mm8

+0

Je pense que 'OverrideMetadata'" partage "l'information de la méthode de rappel entre les instances, n'est-ce pas? Par conséquent, la méthode de rappel doit connaître 'DependencyObject' -' CustomEnabledHandler (DependencyObject d, DependencyPropertyChangedEventArgs e) '. – David