viernes, julio 18, 2008

Use VisualTreeHelper to Navigate Through Objects Hierarchy - Part 2

Yesterday I wrote about the VisualTreeHelper class, today, I will present a class with extension methods useful to search for objects in a more convenient way. You can download the code here.

It's a static class with extension methods like GetChild, GetChildrenCount and GetParent, similar to the VisualTreeHelper methods, but cleaner to use. Compare:

VisualTreeHelper.GetChild(myControl, 0);

myControl.GetChild(0);

Ok, it's cleaner, but really doesn't add much value, but what about getting an Item by name instead of only by index (as provided by the VisualTreeHelper method):

myControl.GetChild("childrenName");

Or better yet doing recursive searches through all the object hierarchy:

myControl.GetChild("childrenName", true);

Methods like that would make scenarios like the one presented yesterday really easy to solve, for example to get an Item of a ListBox using VisualTreeHelper you would have to do something like this:

DependencyObject grid = VisualTreeHelper.GetChild(listBox, 0);
DependencyObject stack = VisualTreeHelper.GetChild(grid,0);
DependencyObject scrollViewer= VisualTreeHelper.GetChild(stack, 0);
DependencyObject scrollPresenter = VisualTreeHelper.GetChild(scrollViewer,0);
DependencyObject border= VisualTreeHelper.GetChild(scrollPresenter ,0);
DependencyObject grid2 = VisualTreeHelper.GetChild(border,0);
DependencyObject etc = VisualTreeHelper.GetChild(grid2, 0);
DependencyObject itemIReallyCareAbout = VisualTreeHelper.GetChild(etc,1);

Using extension methods you could nest calls and made it a bit simpler in one line of code, but not necessarily simpler.

//       Grid,          Stack,       ScrollViewer,ScrollPresenter,Border,Grid,etc,etc, MyItem
listBox.GetChild(0).GetChild(0).GetChild(0).GetChild(0).GetChild(0).GetChild(0).GetChild(1);

Not only that looks horrible, but the worst part is than if the designer decides to change the ItesmPanel or the ListBox Template, you would probably have to change your code, with recursive searches you would simply do something like:

listBox.GetChild("innerControlName", true);

Another useful method is GetChildren wich return an IEnumerable<DependencyObject>.

Tomorrow I will talk about the Visual State Manager.

3 comentarios:

Ranu dijo...

Miguel contactate conmigo por mail. Por lo de DI. Mi usario de mi mail es: elranu en el mail de google.

Saludos,
Ranu

Kris Peeters dijo...

Thanks. Just what I was looking for. Works great for me! A bit of JQuery power in Silverlight. :-)

Miguel Madero dijo...

I'm glad you liked it :)
I keep using it project after project. Those are some really useful Helper Classes. I've a newer version with some other useful helpers, but all built on top of the same concept. Ping me if you would like the update.