0

I have the following code that is supposed to find an element inside of something. The problem is that I have a DataGrid, whose first column has a CheckBox in it's header. The checkbox itself is defined in a Style, which exists in the <controls:ChildWindow.Resources> dictionary of the parent child window.

At runtime, if all elements of the binding collection of the grid are "selected", than I need to select the damn checkbox. However, since the checkbox exists in the style it is not easily accesible and thus I need to walk through the entire DOM to find the specific checkbox.

This is the code that makes the DOM Traversal. It is implemented as an extension method to FrameworkElement so I can call the FindElement or GetChildren methods from any control that inherits from FrameworkElement:

public static class FrameworkElementExtensions
{
    public static FrameworkElement FindElement(this FrameworkElement parentFrameworkElement, string childFrameworkElementNameToSearch)
    {
        FrameworkElement childFrameworkElementFound = null;
        parentFrameworkElement.SearchElements(ref childFrameworkElementFound, childFrameworkElementNameToSearch);
        return childFrameworkElementFound;
    }

    public static List<FrameworkElement> GetChildren(this FrameworkElement parentElement)
    {
        List<FrameworkElement> childFrameworkElementsFound = new List<FrameworkElement>();
        parentElement.GetChildren(childFrameworkElementsFound);
        return childFrameworkElementsFound;
    }

    public static void SearchElements(this FrameworkElement parentFrameworkElement, ref FrameworkElement childFrameworkElementToFind, string childFrameworkElementName)
    {
        int childrenCount = VisualTreeHelper.GetChildrenCount(parentFrameworkElement);
        if (childrenCount > 0)
        {
            FrameworkElement childFrameworkElement = null;
            for (int i = 0; i < childrenCount; i++)
            {
                childFrameworkElement = (FrameworkElement)VisualTreeHelper.GetChild(parentFrameworkElement, i);
                if (childFrameworkElement != null && childFrameworkElement.Name.Equals(childFrameworkElementName))
                {
                    childFrameworkElementToFind = childFrameworkElement;
                    return;
                }
                childFrameworkElement.SearchElements(ref childFrameworkElementToFind, childFrameworkElementName);
            }
        }
    }

    public static void GetChildren(this FrameworkElement parentFrameworkElement, List<FrameworkElement> allChildFrameworkElement)
    {
        int childrenCount = VisualTreeHelper.GetChildrenCount(parentFrameworkElement);
        if (childrenCount > 0)
        {
            for (int i = 0; i < childrenCount; i++)
            {
                FrameworkElement childFrameworkElement = (FrameworkElement)VisualTreeHelper.GetChild(parentFrameworkElement, i);
                    allChildFrameworkElement.Add(childFrameworkElement);
                    childFrameworkElement.GetChildren(allChildFrameworkElement);
            }
        }
    }
}

So the issue at hand is that when i call something along the lines of SomeDataGrid.FindElement("HeaderCheckBox"); it always returns a null. The assumption here is that I have a DataGrid called SomeDataGrid and a CheckBox defined within a style called HeaderCheckBox.

Upon further debugging I also found out that no matter what control I call these extension methods from, the VisualTreeHelper.GetChildrenCount method call used in the last two methods in my code always returns 0 ??? WTF?

Anyone has any idea on how to fix this? Thanks, Martin

Dave Clemmer
  • 3,741
  • 12
  • 49
  • 72
bleepzter
  • 9,607
  • 11
  • 41
  • 64
  • Hi... tested your code in a brand new project and it found everything I asked for. Even the CheckBox in the style, which I had some doubts it would be able to. By the way, my GetChildrenCount (wel... yours) always returned the real count of children. – NestorArturo Aug 03 '11 at 19:02
  • See: http://geekswithblogs.net/codingbloke/archive/2010/12/19/visual-tree-enumeration.aspx – AnthonyWJones Aug 03 '11 at 20:25
  • @NestorArturo would you mind adding code? I'd love to test someone else's implementation just to verify that I am not going crazy... Plus I'd also give you the answer points if you do write it bellow as answer. – bleepzter Aug 04 '11 at 14:11

1 Answers1

0

Sure, no problem. Here it is.

It was made with VS2010 and Silverlight 4... just in case.

NestorArturo
  • 2,476
  • 1
  • 18
  • 21