views:

742

answers:

2

We have custom headers in the Silverlight DataGrid using the ContentTemplate. We've got a button in the header and need to programmatically access the button to hook up the event. We're using IronPython, so we can't statically bind the event in the xaml (plus we use the grid for many different views - so we dynamically generate the xaml).

How can we get access to controls inside a datagrid column header?

A: 

Have you tried the FrameworkElement.GetTemplateChild() method?

slugster
That looks useful. We have a reference to the DataGrid instance, how do I get access to the ControlTemplate in order to use FrameWorkElement.GetTemplateChild()?
fuzzyman
Hmmm... plus that method is protected.
fuzzyman
+2  A: 

Ok, so I solved it by walking the visual tree of the grid looking for the DataColumnHeader - and then walking the tree of the header and finding our button.

The code to walk the visual tree:

from System.Windows.Media import VisualTreeHelper

def findChildren(parent, findType):
    count = VisualTreeHelper.GetChildrenCount(parent)
    for i in range(count):
        child = VisualTreeHelper.GetChild(parent, i)
        if isinstance(child, findType):
            yield child
        else:
            for entry in findChildren(child, findType):
                yield entry

It is called like this:

from System.Windows.Controls import Button
from System.Windows.Controls.Primitives import DataGridColumnHeader

for entry in findChildren(self._gridControl, DataGridColumnHeader):
    for button in findChildren(entry, Button):
        button.Click += handler

Note that a convenient time to call this code is from the grid.Loaded event, this ensures that the headers have been created.

fuzzyman