Click here to Skip to main content
6,630,586 members and growing! (16,093 online)
Email Password   helpLost your password?
Languages » C# » Windows Forms     Beginner License: The Code Project Open License (CPOL)

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

By Vincent Meijer

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.
C#
Posted:28 Nov 2008
Views:4,572
Bookmarked:16 times
Announcements
Loading...
 
Search    
Advanced Search
Add to IE Search
printPrint   add Share
      Discuss Discuss   Broken Article?Report  
5 votes for this article.
Popularity: 2.62 Rating: 3.75 out of 5

1

2
2 votes, 40.0%
3
3 votes, 60.0%
4

5

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


Member

Occupation: Software Developer
Company: Ematters
Location: Netherlands Netherlands

Other popular C# articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 4 of 4 (Total in Forum: 4) (Refresh)FirstPrevNext
GeneralWhat about ActiveControl property Pinmembergajatko8:35 29 Nov '08  
GeneralRe: What about ActiveControl property PinmemberVincent Meijer5:32 1 Dec '08  
QuestionOne Function Too Much PinmemberADLER18:00 29 Nov '08  
AnswerRe: One Function Too Much PinmemberVincent Meijer5:37 1 Dec '08  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 28 Nov 2008
Editor: Deeksha Shenoy
Copyright 2008 by Vincent Meijer
Everything else Copyright © CodeProject, 1999-2009
Web22 | Advertise on the Code Project