Click here to Skip to main content
Click here to Skip to main content

GetActiveControl, Getting the MdiChild's Active Control from its Parent MdiForm

, 28 Nov 2008
Rate this:
Please Sign up or sign in to vote.
Ever have the problem that your controls, like a TextBox, ComboBox or DataGridView for example, don’t seem to be receiving any keyboard commands like Ctrl+A, Ctrl+C or Ctrl+V? Happens to me too.

Introduction

Ever have the problem that your controls, like a TextBox, ComboBox or DataGridView for example, don't seem to be receiving any keyboard commands like Ctrl+A, Ctrl+C or Ctrl+V? It happens to me too.

I was working on an MDI program containing several childforms with multiple tab or splitter panels to hold forms controls. During the initial phase, it didn't really bother me that much. First make the app work, then make it user friendly. But after some time, I had to figure out a solution.

Background

After some testing, I discovered what was happening. All the keystrokes were getting captured by the MdiForm owning all other childforms and their controls. Fine, so I take a look at the sender object. It’s the MdiForm! Getting the control I was actually using was a pain, but I figured it out.

The first thing I tried was looping through the sender.Controls collection and testing which had the ContainsFocus property set to true.

private void MdiForm_KeyDown(object sender, KeyEventArgs e)
{
 if (e.Control)
 {
  foreach (Control ctl in sender.Controls)
  {
    if (ctl.ContainsFocus)
    {
      // active control??
    }
  }
 }
}

All I got were ChildForms. They were the correct Forms but not the controls I was looking for. So I figured that I would do the same thing on the ChildForm.Controls collection.

  foreach (Control ctl in sender.Controls)
  {
    if (ctl.ContainsFocus)
    {
     foreach (Control ctl2 in sender.Controls)
     {
       if (ctl2.ContainsFocus)
       {
         //  could this be it??
       }
     }
    }
  }

This time it wasn't a form, but yet again not the control I was looking for. This was just the control that holds the control, that holds the control that holds the controls I was looking for. And this was just for one child form. Most controls were 4, 5 or even more collections away.

I decided to take a more flexible approach and use a recursive function:

public static Control GetActiveControlOnSender(object sender)
{
// check if sender is a control else just return null
 if(sender is Control)
   return GetActiveControl((Control) sender);
return null
}
 
internal static Control GetActiveControl(Control control)
{
 // check if control contains the focus. if not just return null
 if (!sender.ContainsFocus)
  return null;
// loop through collection
  foreach (Control ctl in sender.Controls)
  {
// check for child control focus
   if (ctl.ContainsFocus)
   {
// loop at child controls  control collection count 
// 0 is the top control, it has no children
// on 1 or more we do call this function again using the control
    if (ctl.Controls.Count == 0)
    {
     return ctl;
    }
    else
    {
     return GetActiveControl(ctl);
    }
   }
  }
 
// no child has focus so this has to be sender 
  return control;
}

All I had to do now was call the function from the KeyDown event and pass the sender object. Then look at the object and decide what needs to happen.

private void MdiForm_KeyUp(object sender, KeyEventArgs e)
{
// is ctrl key pressed?
 if (e.Control)
 {
  Control control = Common.GetActiveControlOnSender(sender)
 
  switch (e.KeyCode)
  {
   case Keys.A:
    if (control is TextBox)
     ((TextBox)control).SelectAll();
   break;
   case Keys.X:
    if (control is TextBox)
     ((TextBox)control).Cut();
   break;
   case Keys.V:
    if (control is TextBox)
     ((TextBox)control).Paste();
   break;
   case Keys.C:
    if (control is TextBox)
     ((TextBox)control).Copy();
   break;
  }
 }
}

This can be modified to work for any user control.

History

  • 2008-11-28: First version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Vincent Meijer
Software Developer Ematters
Netherlands Netherlands
No Biography provided

Comments and Discussions

 
QuestionWhat about ActiveControl property Pinmembergajatko29-Nov-08 7:35 
AnswerRe: What about ActiveControl property PinmemberVincent Meijer1-Dec-08 4:32 
QuestionOne Function Too Much PinmemberADLER129-Nov-08 7:00 
AnswerRe: One Function Too Much PinmemberVincent Meijer1-Dec-08 4:37 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.140721.1 | Last Updated 28 Nov 2008
Article Copyright 2008 by Vincent Meijer
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid