And the revised version that doesn’t exhibit the excessive memory consumption issue mentioned in my previous post.
import System;
import System.Text;
import System.Windows;
import System.Windows.Controls;
import System.Windows.Media;
import System.Windows.Media.Media3D;
import System.Reflection;
import MForms;
package MForms.JScript {
class VTWalker {
public function Init(element: Object, args: Object, controller : Object, debug : Object)
{
var sbBuilder : StringBuilder = new StringBuilder(5000);
// this is a grid that appears on our panel, interestingly it doesn't include some of the higher
// level controls on the main panel
var content : Object = controller.RenderEngine.Content;
// to prove that we are indeed a Grid.
//debug.WriteLine("content object type = " + content.GetType().ToString());
var parent : Object = content;
var lastParent : Object = content;
// here we will loop UP the VisualTree seeking the top
while(null != (parent = VisualTreeHelper.GetParent(parent)))
{
lastParent = parent;
}
//debug.WriteLine(" ************ ");
//debug.WriteLine(" ************ ");
//debug.WriteLine("From Grid downwards");
// output the tree from the Grid down, if you want to
// go from the very highest Parent, then change content to lastParent
displayChildren(sbBuilder, lastParent, 1, debug);
debug.WriteLine(sbBuilder.ToString());
// debug.WriteLine("Finished, debug object type = " + debug.GetType().ToString());
}
// displayChildren
// display information for each of the objects children
// recurse down the tree
// parent - the object whose children we want to investigate
// depth - we keep track of the depth so we can indent our output to make reading easier
// debug - so we can output our data
private function displayChildren(sbBuilder : StringBuilder, parent : Object, depth : int, debug : Object)
{
try
{
if(null != parent)
{
// get the type of our object, we do this
// so we can check if the object inherits
// from a DependencyObject
var parentobjType : Type = parent.GetType();
if(parentobjType.IsSubclassOf(DependencyObject) == true)
{
// loop through the children of this object
for(var i=0; i < VisualTreeHelper.GetChildrenCount(parent);i++)
{
// retrieve the child object
var current : Object = VisualTreeHelper.GetChild(parent,i);
if(null != current)
{
// here we shall deterine the type of the new object
var objType = current.GetType();
// we're looking for the Name property, because
// this is what I am interested in
var objPropertyInfo = objType.GetProperty("Name");
var objPropertyVisible = objType.GetProperty("Visibility");
// strPadding allows us to indent
var strPadding : String = "";
for(var j = 0; j < (depth * 4); j++)
{
strPadding += " ";
}
// if objPropertyInfo is null then
// we couldn't find the Name property
if(null != objPropertyInfo)
{
// output the name of the object
//debug.WriteLine(strPadding + "Object name: " + objPropertyInfo.GetValue(current));
sbBuilder.Append(strPadding + "Object name: " + objPropertyInfo.GetValue(current));
sbBuilder.Append(Environment.NewLine);
}
else
{
//debug.WriteLine(strPadding + "Object name: Unknown");
}
// output the objects type
//debug.WriteLine(strPadding + "Object Type: " + objType.ToString());
sbBuilder.Append(strPadding + "Object Type: " + objType.ToString());
sbBuilder.Append(Environment.NewLine);
if(null != objPropertyVisible)
{
//debug.WriteLine(strPadding + "Object Visibility: " + objPropertyVisible.GetValue(current).ToString());
sbBuilder.Append(strPadding + "Object Visibility: " + objPropertyVisible.GetValue(current).ToString());
sbBuilder.Append(Environment.NewLine);
}
// does the current object have any children?
if(VisualTreeHelper.GetChildrenCount(current) >= 1)
{
// recurse down
displayChildren(sbBuilder, current, depth+1, debug);
}
}
}
}
}
}
catch(ex)
{
debug.WriteLine("!-! Exception: " + ex.Message + " " + ex.StackTrace);
}
}
}
}