WPF: Getting TreeViewItem's constituent contro

2019-08-17 05:59发布

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

4条回答
SAY GOODBYE
2楼-- · 2019-08-17 06:41

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楼-- · 2019-08-17 06:43

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; 
} 
查看更多
看我几分像从前
4楼-- · 2019-08-17 06:45

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);
查看更多
劳资没心,怎么记你
5楼-- · 2019-08-17 06:46

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")
查看更多
登录 后发表回答