Reputation: 16603
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
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
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