Many objects in .NET are stored in a hierarchy.  For example: controls, files and folders, and anything you would normally display in a tree view.  There are many different algorithms for finding the root of a hierarchy.  Here is one of them:

public MyObject GetRoot()
{
    // start with this as root
    MyObject root = this;
    // get the parent
    MyObject parent = this.Parent;

    // keep going until no more parents
    while (parent != null)
    {
        // save the parent
        root = parent;
        // get the parent of the parent
        parent = parent.Parent;
    }

    return root;
}

Sample Program

Here is a simple console program that demonstrates this.  Note that the function to get the root is a method GetRoot() instead of a Root property.  Making it a method instead of a property implies that it must be calculated each time, similar to how the .NET Control class has a FindForm() method.

using System;
using System.Collections.Generic;

namespace CSharp411
{
    class Program
    {
        static void Main( string[] args )
        {
            MyObject a = new MyObject( "a" );
            MyObject b = new MyObject( "b" );
            MyObject c = new MyObject( "c" );
            MyObject d = new MyObject( "d" );

            a.AddChild( b );
            b.AddChild( c );
            c.AddChild( d );

            Write( a );
            Write( b );
            Write( c );
            Write( d );
            Console.ReadLine();
        }
        static void Write( MyObject obj )
        {
            string objName = obj.Name;
            MyObject parent = obj.Parent;
            string parentName = parent == null ? "none" : parent.Name;
            MyObject root = obj.GetRoot();
            string rootName = root == null ? "none" : root.Name;
            Console.WriteLine( "Object={0}, Parent={1}, Root={2}", objName, parentName, rootName );
        }
    }
    class MyObject
    {
        public MyObject()
        {
        }
        public MyObject( string name )
        {
            this.m_Name = name;
        }
        private string m_Name;
        public string Name
        {
            get
            {
                return this.m_Name;
            }
            set
            {
                this.m_Name = value;
            }
        }
        public override string ToString()
        {
            return this.m_Name;
        }
        private MyObject m_Parent;
        public MyObject Parent
        {
            get
            {
                return this.m_Parent;
            }
        }
        private List<myobject> m_Children = new List</myobject><myobject>();
        public void AddChild( MyObject obj )
        {
            this.m_Children.Add( obj );
            obj.m_Parent = this;
        }
        public IEnumerator</myobject><myobject> Children
        {
            get
            {
                return this.m_Children.GetEnumerator();
            }
        }
        public MyObject GetRoot()
        {
            // start with this as root
            MyObject root = this;
            // get the parent
            MyObject parent = this.Parent;

            // keep going until no more parents
            while (parent != null)
            {
                // save the parent
                root = parent;
                // get the parent of the parent
                parent = parent.Parent;
            }

            return root;
        }
    }
}

Program Output

As you would expect, the output when you run this program is:

Object=a, Parent=none, Root=a
Object=b, Parent=a, Root=a
Object=c, Parent=b, Root=a
Object=d, Parent=c, Root=a