I have a ListView
that uses a custom ItemTemplate
(doesn't everyone?):
<ListView>
<!-- ... -->
<ListView.ItemTemplate>
<DataTemplate x:DataType="x:String">
<MyGreatControl Thing="{x:Bind}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
MyGreatControl
today has extensive keyboard handling code built-in, but due to some refactoring, I need to move the actual handlers to the ListView
itself. However, I don't want to move all of the code in MyGreatControl
to the ListView
(for many reasons).
If I have an arbitrary ListViewItem
(which, for example, I can get from an event handler), how can I access the MyGreatControl
instance in its DataTemplate?
MyGreatControl^ GetMyGreatControlFromListViewItem(ListViewItem^ listViewItem) {
// ???
}
Disclaimer: I work for Microsoft.
You want to use ContentTemplateRoot
!
MyGreatControl^ GetMyGreatControlFromListViewItem(ListViewItem^ listViewItem) {
return safe_cast<MyGreatControl^>(listViewItem->ContentTemplateRoot);
}
This also works for any arbitrary element—if you have a StackPanel, for example, ContentTemplateRoot
will return the StackPanel
instance you want:
<ListView.ItemTemplate>
<DataTemplate x:DataType="x:String">
<StackPanel><!-- This is what you get! -->
<TextBlock Text="{x:Bind}" />
<Button Content="Foo" IsTabStop="False" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
You can then use normal visual tree navigation to find Children, etc.