0

I customed my TreeViewItem to be a StackPanel with image and textblock inside; I'd like to get a reference to the TextBlock inside. For the codes below node is of type TreeviewItem and I am surechildrenCound =3 which could be StackPanel image textblock! But it can not find any TextBlock inside. I never see any console output and object _itemToMovereturns null

TreeViewItem node = UIHelper.FindVisualParent<TreeViewItem>(e.OriginalSource as FrameworkElement);
var child = VisualTreeHelper.GetChild(node, 0);
int childrenCount = VisualTreeHelper.GetChildrenCount(child);
for (int i = 0; i < childrenCount; i++)
{
    TextBlock vc = VisualTreeHelper.GetChild(child, i) as TextBlock;
    if (vc != null)
    {
        Console.WriteLine("ggggggggggggggggggggggggggggggggggggggggggggggg");

        _itemToMove = vc.Text as object;
    }

}
Console.WriteLine(childrenCount+";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;");
baozi
  • 679
  • 10
  • 30

2 Answers2

1

It may be that your TextBlock is buried deeper than you think. I've always had success using the following helper which is generic enough to be used elsewhere in the app.

public static T FindVisualChild<T>(DependencyObject obj) where T : DependencyObject
{
    if (obj != null)
    {
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
        {
            var child = VisualTreeHelper.GetChild(obj, i);
            if (child is T)
            {
               return (T)child;
            }

            T childItem = FindVisualChild<T>(child);
            if (childItem != null) return childItem;
        }
    }
    return null;
}

I think I got this from a similar question from StackOverflow.

  • Nice job! Solved my problem! – baozi Nov 09 '14 at 13:48
  • Sorry about replying on this old question. I just ran across this. It works, but I was thinking that a TreeViewItem is also a child of a TreeViewItem, and thought that performing a depth first search here would be dangerous, because you could end up getting the child control of a different TreeViewItem. Realize that a breath first search is even more dangerous. It basically comes down to the child items being in a grid, and the order of those items could maybe change without them changing visually. – Michael T Aug 31 '18 at 11:11
-1

As Michael T said, TreeViewItem is also a child of a TreeViewItem. I ran into this old question because I wanted only the visualtree elements of a single TreeViewItem and the so many times used by me FindVisualChild function wasn't this time useful. So I modified this function to retrieve elements of TreeVieItem excluding the TreeViewItems inside. The function is based on the fact that any hierarchy is defined by nodes, and asumed that a node has a NodeType that is not the type of the children. However, you can go deep in the tree as many levels as you want (HierachyLevels param). The function also search for specific type and name of the elements.

 Public Sub FindChildGroup(Of T As DependencyObject, H As DependencyObject)(Parent As DependencyObject _
     , ChildName As String _
     , ByRef OutputList As List(Of T) _
     , Optional HierachyLevels As Integer = 0)

  Dim childrenCount As Integer = VisualTreeHelper.GetChildrenCount(Parent)

  For i As Integer = 0 To childrenCount - 1

     'Analyze child
     Dim child = VisualTreeHelper.GetChild(Parent, i)

     'Is node?
     Dim IsNode = TypeOf child Is H

     If IsNode And HierachyLevels > 0 Or TypeOf child IsNot H Then

        Dim child_Test As T = TryCast(child, T)

        If child_Test IsNot Nothing Then

           'should be included in the list?
           Dim child_Element As FrameworkElement = TryCast(child_Test, FrameworkElement)

           If child_Element.Name Like ChildName Then
              OutputList.Add(child_Test)
           End If

        End If

        'Go down next level
        If TypeOf child Is H Then HierachyLevels -= 1
        FindChildGroup(Of T, H)(child, ChildName, OutputList, HierachyLevels)
        If TypeOf child Is H Then HierachyLevels += 1

     End If
  Next

End Sub