Most efficient way to find the root element?

1,417 views
Skip to first unread message

Laurent Bugnion [MVP]

unread,
Jun 17, 2009, 4:32:58 AM6/17/09
to wpf-di...@googlegroups.com

Hey guys,

 

What is the most efficient way to find the root element (for example a UserControl) from a child UI Element in code (not XAML)? Is tree walking the only option, or is there something that doesn’t imply recursion?

 

Cheers,

Laurent

--

Laurent Bugnion [Microsoft MVP, MCP]

Blog: http://blog.galasoft.ch

Web: http://www.galasoft.ch

Support children in Calcutta: http://www.calcutta-espoir.ch

 

cid:image001.png@01C9C8AA.B722DA80

My

business

card

as

Microsoft Tag

 

 

image001.png

Andrew

unread,
Jun 17, 2009, 9:11:00 AM6/17/09
to wpf-di...@googlegroups.com
I guess it depends on what you consider to be the root element. For an element within the template of a Control, you would likely use TemplatedParent. For other elements you would walk the logical tree (and fallback to the visual tree when there is no logical parent). If you wanted to just get to the root window, there is an inherited property so you could use Window.GetWindow().
-Andrew

From: Laurent Bugnion [MVP] <lau...@galasoft.ch>
To: wpf-di...@googlegroups.com
Sent: Wednesday, June 17, 2009 4:32:58 AM
Subject: [WPF Disciples] Most efficient way to find the root element?
image001.png

Eric Burke

unread,
Jun 17, 2009, 10:00:26 AM6/17/09
to wpf-di...@googlegroups.com
Attached Property will work if you're looking for a named element.
 
{
    ...
    var myChild = ...;

    Binding b = new Binding();

    b.ElementName =

"TopLevelItem";

    BindingOperations.SetBinding(myChild, ElementFinder.ElementProperty, b);

   

    var theElementIWant = ElementFinder.GetElement(myChild);

 

    ElementFinder.SetElement(myChild, null);

}
 

public class ElementFinder : DependencyObject

{

 

    public static UIElement GetElement(DependencyObject obj)

    {

        return (UIElement)obj.GetValue(ElementProperty);

    }

 

    public static void SetElement(DependencyObject obj, UIElement value)

    {

        obj.SetValue(ElementProperty, value);

    }

 

    public static readonly DependencyProperty ElementProperty =

    DependencyProperty.RegisterAttached

    (

        "Element",

        typeof(UIElement),

        typeof(ElementFinder),

        new UIPropertyMetadata

        (

            default(UIElement)

        )

    )

);

}



From: Andrew <webfl...@yahoo.com>
To: wpf-di...@googlegroups.com
Sent: Wednesday, June 17, 2009 9:11:00 AM
Subject: [WPF Disciples] Re: Most efficient way to find the root element?

Andrew

unread,
Jun 17, 2009, 12:00:06 PM6/17/09
to wpf-di...@googlegroups.com
I could be mistaken but that doesn't seem very efficient since the Binding has to create a BindingExpression, ObjectRef, etc. Also, I think in the case of a non-template contained element (e.g. an element within the Content of a Window/UserControl), the ObjectRef still has to walk up the logical/visualtree to find the namescope and then index into that to get the named element.
 
-Andrew

From: Eric Burke <ebu...@yahoo.com>
To: wpf-di...@googlegroups.com
Sent: Wednesday, June 17, 2009 10:00:26 AM

Eric Burke

unread,
Jun 17, 2009, 1:59:36 PM6/17/09
to wpf-di...@googlegroups.com
Just throwing out another idea.

I'm not sure what mechanism WPF uses under the hood to find an named element within a namescope (I haven't dug into Reflector).  It's possible that a tree walk is still necessary, in which case you might as well just do that.  But if there's some caching going on, it could be a fast lookup to find the named element.

[In my experience, I've always simply used a tree walk using a helper method which does the looping looking for an element by name, type, etc.  It's never had a negative effect on performance.]

Sent: Wednesday, June 17, 2009 12:00:06 PM

Corrado Cavalli

unread,
Jun 17, 2009, 3:34:26 PM6/17/09
to wpf-di...@googlegroups.com

> If you wanted to just get to the root window, there is an inherited property so you could use Window.GetWindow().

Could you please elaborate on this?

 

Corrado

 

From: wpf-di...@googlegroups.com [mailto:wpf-di...@googlegroups.com] On Behalf Of Andrew
Sent: mercoledì 17 giugno 2009 15:11
To: wpf-di...@googlegroups.com
Subject: [WPF Disciples] Re: Most efficient way to find the root element?

 

I guess it depends on what you consider to be the root element. For an element within the template of a Control, you would likely use TemplatedParent. For other elements you would walk the logical tree (and fallback to the visual tree when there is no logical parent). If you wanted to just get to the root window, there is an inherited property so you could use Window.GetWindow().

-Andrew


From: Laurent Bugnion [MVP] <lau...@galasoft.ch>


To: wpf-di...@googlegroups.com
Sent: Wednesday, June 17, 2009 4:32:58 AM

image001.png

Andrew

unread,
Jun 18, 2009, 10:44:50 AM6/18/09
to wpf-di...@googlegroups.com
Sure. The Window class defines an internal inherited dependencyproperty named IWindowService. The Window sets this property on itself and so descendant elements inherit this property. While the DP is internal, the Window class does expose a public static GetWindow method which uses this DP to get the value of the inherited windowservice - i.e. the Window that contains the specified element.

From: Corrado Cavalli <corrado...@gmail.com>
To: wpf-di...@googlegroups.com
Sent: Wednesday, June 17, 2009 3:34:26 PM
image001.png

Jaime Rodriguez

unread,
Jun 18, 2009, 11:06:14 AM6/18/09
to wpf-di...@googlegroups.com

FYI, I asked Varsha about the finding root element. Varsha is the Dev Lead for all tree services. Her answer is below (we were not missing a silver bullet).

 

Yes tree walk is the only way. However you do not need to use recursion you can simply walk the parent chain in a loop (i.e. iteratively).”

Reply all
Reply to author
Forward
0 new messages