ILearnable .Net

April 2, 2014

Display control hierarchy in winforms application

Filed under: Uncategorized — andreakn @ 13:08

I recently changed projects and suddenly found myself in a MASSIVE winforms application… Now normally I have no problem navigating massive codebases, after all all you have to do is to right click and select “inspect element” in chrome to see which part of the code created this part of the GUI, right? not so in winforms…

after spending a bit of time searching for strings found nearby what I wanted to track down in the codebase I hit me: “there’s got to be a better way!!”

Luckily for me all GUI controls in the solution inherits from a common baseclass, so I was able to tweak that baseclass so that whenever you press the F12 key you enter “inspection mode” which makes any control clicked display a messagebox with its control hierarchy path all the way up to the form.
the result looks somewhat like this: Control hieararchy for clicked control

 public class TheBaseControl : SomeOtherControlBase
   {
      private bool currentlyInInspectMode;
      protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
      {
         ActivateOrDeactivateMouseHack(keyData);
         return base.ProcessCmdKey(ref msg, keyData);
      }

      private void ActivateOrDeactivateMouseHack(Keys keyData)
      {
         if (keyData.HasFlag(Keys.F12) )
         {
            if (!currentlyInInspectMode)
            {
               SetInspectModeRecursively(this, true, true);
               currentlyInInspectMode = true;
            }
         }
         else
         {
            if (currentlyInInspectMode)
            {
               SetInspectModeRecursively(this, false, true);
               currentlyInInspectMode = false;
            }
         }
      }

      private void SetInspectModeRecursively(Control ctrl, bool active, bool initialEventSource)
      {
         if (ctrl is TheBaseControl &&!initialEventSource) return;
         if (ctrl == null) return;
         if (active)
            ctrl.MouseDown += DisplayControlInfo;
         else
            ctrl.MouseDown -= DisplayControlInfo;

         foreach (var control in ctrl.Controls)
         {
            SetInspectModeRecursively(control as Control, active, false);
         }
      }

      private void DisplayControlInfo(object sender, MouseEventArgs e)
      {
         var clickedControl = FindControlAtCursor( this.ParentForm);
         var controlpath = "";
         var tip = clickedControl;
         while (tip != null)
         {
            controlpath = string.Format("[{0}:id={1}]{2}{3}", tip.GetType().FullName, tip.Name, Environment.NewLine,
               controlpath);
            tip = tip.Parent;
         }
         MessageBox.Show("You just clicked on " + Environment.NewLine+controlpath);
      }
      
      public static Control FindControlAtPoint(Control container, Point pos)
      {
         Control child;
         foreach (Control c in container.Controls)
         {
            if (c.Visible && c.Bounds.Contains(pos))
            {
               child = FindControlAtPoint(c, new Point(pos.X - c.Left, pos.Y - c.Top));
               if (child == null) return c;
               else return child;
            }
         }
         return null;
      }

      public static Control FindControlAtCursor(Form form)
      {
         Point pos = Cursor.Position;
         if (form.Bounds.Contains(pos))
            return FindControlAtPoint(form, form.PointToClient(Cursor.Position));
         return null;
      }
   }

Advertisements

Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Create a free website or blog at WordPress.com.

%d bloggers like this: