Axarydax
Axarydax

Reputation: 16603

How to let parent control know that its child got focus?

imagine that I have a Form with 9 controls (TabbedStuffControl) in a 3x3 tile, and these controls contain TabControls containing another control (StuffControl) with ListBoxes and TextBoxes.

I'd like to know a proper way to let TabbedStuffControl that its child has received a focus? e.g. user clicks into a textbox of StuffControl or drags something to listbox of StuffControl. Eventually the Form should know which TabbedStuffControl is active

Do I need to hook up GotFocus event of TextBoxes and ListBoxes and TabControls, then dispatch another event to finally let Form know who got focus? I think that there should be a simpler way - that somehow TabbedStuffControl knows that its child got focus, so there would be only one place in code that I'll hook up.

Thanks.

Upvotes: 1

Views: 1370

Answers (2)

Hans Passant
Hans Passant

Reputation: 941277

Using the Enter event (better then GotFocus) is certainly a good approach. Subscribe a handler for all controls, then go find the parent of the control in the Enter event handler. This sample code demonstrates the approach:

  public partial class Form1 : Form {
    public Form1() {
      InitializeComponent();
      wireEnter(this.Controls);
    }
    private void wireEnter(Control.ControlCollection ctls) {
      // Hook Enter event for all controls
      foreach (Control ctl in ctls) {
        ctl.Enter += ctl_Enter;
        wireEnter(ctl.Controls);
      }
    }

    TabbedStuffControl mParent;

    private void ctl_Enter(object sender, EventArgs e) {
      // Find parent
      Control parent = (sender as Control).Parent;
      while (parent != null && !(parent is TabbedStuffControl)) parent = parent.Parent;
      if (parent != mParent) {
        // Parent changed, do something.  Watch out for null
        //....
        mParent = parent as TabbedStuffControl;
      }
    }
  }

Upvotes: 2

Icono123
Icono123

Reputation: 3950

You'll have to use COM:

// Import GetFocus() from user32.dll
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Winapi)]
internal static extern IntPtr GetFocus();

protected Control FocusControl
{
    get
    {
        Control focusControl = null;
        IntPtr focusHandle = GetFocus();

        if (focusHandle != IntPtr.Zero)
            // returns null if handle is not to a .NET control
            focusControl = Control.FromHandle(focusHandle);

        return focusControl;
    }
}

Upvotes: 0

Related Questions