问题
how can I get the constituent controls making up the TreeViewItem in code if they are inside a hierarichicaldatatemplate?
<HierarchicalDataTemplate DataType="{x:Type local:Module}" ItemsSource="{Binding Children}">
<StackPanel Orientation="Horizontal">
<Image Width="16" Height="16" Margin="3,0" Source="Images\module.ico" />
<local:RenamingNode Name="RenamableNode" Text="{Binding Name}" VstaObject="{Binding BindsDirectlyToSource=True}" OnRename="OnRenameOccured" />
</StackPanel>
</HierarchicalDataTemplate>
So programatically when I get an event with a TreeViewItem as the source, I want to be able to get the local:RenamingNode, but I can't get the TreeViewItem's descendants.
Thanks,
Ilya
回答1:
This worked for me. Doubtless there is a better way, as always, and you will doubtless add extra checks such as checking the Child(ren) count and/or getting/checking type/name of children in a loop etc. but the basic technique works, well it did in my app although I have a Grid instead of a StackPanel.
private object FindContentTemplatePart(TreeViewItem treeViewItem)
{
if (treeViewItem != null)
{
var header = (ContentPresenter)treeViewItem.Template.FindName("PART_Header", treeViewItem);
if (header != null)
{
StackPanel stackPanel = (StackPanel)VisualTreeHelper.GetChild(header,0);
return stackPanel.Children[2];
}
}
return null;
}
回答2:
You can use FrameworkTemplate.FindName to find the header content presenter in the TreeView item control template, and then again to find the part you want in the data template.
private object FindContentTemplatePart(TreeViewItem treeViewItem)
{
if (treeViewItem != null)
{
var header = treeViewItem.Template.FindName("PART_Header", treeViewItem) as ContentPresenter;
if (header != null)
{
return header.ContentTemplate.FindName("RenamableNode", header);
}
}
return null;
}
You could also walk the visual tree manually with the methods on VisualTreeHelper.
回答3:
I'm assuming that this will be the same in WPF as silverlight (this is the silverlight version)
(treeViewItem.HeaderTemplate.LoadContent() as StackPanel).FindName("RenamableNode")
回答4:
None of the above Solutions works in Silverlight but this seems to work.
<common:HierarchicalDataTemplate x:Key="myHierarchicalTemplate" ItemsSource="{Binding Children}" >
<StackPanel x:Name="spTreeItem" Height="23" Margin="0,0,0,0" HorizontalAlignment="Stretch" Orientation="Horizontal">
</StackPanel>
</common:HierarchicalDataTemplate>
Following the code
TreeViewItem item = TreeViewWorkarounds.ContainerFromItem(trtFolders, trtFolders.SelectedItem);
Grid ItemGrid = (Grid) VisualTreeHelper.GetChild(item, 0);
Button ItemGridButton = (Button)VisualTreeHelper.GetChild(ItemGrid, 2);
Grid ButtonGrid = (Grid)VisualTreeHelper.GetChild(ItemGridButton, 0);
ContentPresenter CP = (ContentPresenter)VisualTreeHelper.GetChild(ButtonGrid, 1);
ContentPresenter CPchlild = (ContentPresenter)VisualTreeHelper.GetChild(CP, 0);
StackPanel sp = (StackPanel)VisualTreeHelper.GetChild(CPchlild, 0);
来源:https://stackoverflow.com/questions/3250630/wpf-getting-treeviewitems-constituent-controls