views:

580

answers:

1

Hi,

I have a problem with DataContextChanged not being raised on a logical child of my custom Panel control. I've narrowed it down to this:

Starting from a wizard-generated WPF application I add:

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

As I understand, this works because the DataContext is an inheritable dependency property.

Now, I add event handlers for DataContextChanged both on the Window (this) and its logical child:

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

If I run this, only the first event handler will execute. Why is this? If instead of AddLogicalChild( elt ) I do the following:

this.Content = elt;

both handlers will execute. But this is not an option in my case - I'm adding FrameworkContentElements to my control which aren't supposed to be visual children.

What's going on here? Should I do something more besides AddLogicalChild() to make it work?

(Fortunately, there is a rather simple workaround - just bind the DataContext of the element to the DataContext of the window)

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

Thank you.

+1  A: 

You need to override the LogicalChildren property too:

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

Of course, you'll want to return any logical children defined by the base implementation, too.

HTH, Kent

Kent Boogaart
Yes, that's it! Thanks, Kent!
Danko Durbić