2009-04-06 5 views
2

J'ai un problème avec DataContextChanged ne pas être levé sur un enfant logique de mon contrôle Panel personnalisé. Je l'ai réduit à ceci:WPF: Pourquoi DataContextChanged n'est-il pas déclenché sur un enfant logique?

A partir d'une application WPF générée par l'Assistant ajouter:

private void Window_Loaded(object sender, RoutedEventArgs e) 
    { 
     var elt = new FrameworkElement(); 
     this.AddLogicalChild(elt); 
     DataContext = 42; 
     Debug.Assert((int)elt.DataContext == 42); 
    } 

Si je comprends bien, cela fonctionne parce que le DataContext est un inheritable dependency property.

Maintenant, ajouter des gestionnaires d'événements pour DataContextChanged à la fois dans la fenêtre (ce) et son enfant logique:

this.DataContextChanged += 
     delegate { Debug.WriteLine("this:DataContextChanged"); }; 
    elt.DataContextChanged += 
     delegate { Debug.WriteLine("elt:DataContextChanged"); }; 

Si je lance ce, seul le premier gestionnaire d'événements exécutera. Pourquoi est-ce? Si au lieu de AddLogicalChild (CLNA) Je fais ce qui suit:

this.Content = elt; 

les deux gestionnaires seront exécutés. Mais ce n'est pas une option dans mon cas - j'ajoute FrameworkContentElements à mon contrôle qui ne sont pas censés être des enfants visuels.

Que se passe-t-il ici? Devrais-je faire autre chose que AddLogicalChild() pour le faire fonctionner?

(Heureusement, il existe une solution assez simple - bind DataContext de l'élément à la DataContext de la fenêtre)

BindingOperations.SetBinding(elt, FrameworkElement.DataContextProperty, 
      new Binding("DataContext") { Source = this }); 

Merci.

Répondre

5

Vous devez passer outre la propriété LogicalChildren aussi:

protected override System.Collections.IEnumerator LogicalChildren 
{ 
    get { yield return elt; } 
} 

Bien sûr, vous aurez envie de revenir des enfants logiques définies par la mise en œuvre de base aussi.

+0

Oui, c'est ça! Merci, Kent! –

Questions connexes