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.