views:

385

answers:

4

Is it possible to know who got the focus in a lost focus event.

Compact Framework does not have a ActiveControl, so I don't know how to tell who got the focus.

I used this way of finding the focused control.

public System.Windows.Forms.Control FindFocusedControl()
{
    return FindFocusedControl(this);
}

public static System.Windows.Forms.Control FindFocusedControl(System.Windows.Forms.Control container)
{
    foreach (System.Windows.Forms.Control childControl in container.Controls)
    {
        if (childControl.Focused)
        {
            return childControl;
        }
    }

    foreach (System.Windows.Forms.Control childControl in container.Controls)
    {
        System.Windows.Forms.Control maybeFocusedControl = FindFocusedControl(childControl);
        if (maybeFocusedControl != null)
        {
            return maybeFocusedControl;
        }
    }

    return null; // Couldn't find any, darn!
}

That seems to work fine, even in the LostFocus call.

+2  A: 

No. first comes the LostFocus-event of one control then comes the GotFocus-event of the next control. as long as you can not figure out which control the user uses in the next moment, it is not possible.
whereas if the compact framework control does have a TabIndex-property it could be predicted only if the user uses the tab-key.

Edit: OK You posted the solution and it works fine I must admit: the simple "No" is wrong +1

Oops
thanks for editing
Oops
Edited so I can change my vote.
Vaccano
So I am confused... This doc says that GotFocus goes before LostFocus. http://msdn.microsoft.com/en-us/library/system.windows.forms.control.gotfocus.aspx But I am seeing LostFocus go first (as you said).
Vaccano
the document is of course right, but it lacks the information which control is actually meant. therefore read carefuly what I have written: LostFocus of the one control comes before the GotFocus of the _NEXT_ control. the MSDN just says GotFocus comes before LostFocus of the *same* control. You talk about "seeing" so I assume you made a small example, where you e.g. store the occurence of the Lost- and Gotfocus events of different controls in a ListBox.
Oops
Ah... I see now. Well, that makes sense, but I am still no closer to a solution to my problem.
Vaccano
maybe describe what you really want to do with it, maybe there is another better solution?
Oops
In my lost focus method, I wanted to show a message (or not) based on the control that got the focus.
Vaccano
I'd implement an IMessageFilter and just look for teh low-level messages based on the control handles you're interested in there. That's the simplest, least kludgey way to do this.
ctacke
+2  A: 

One option would be to interop the GetFocus API

[DllImport("coredll.dll, EntryPoint="GetFocus")]
public extern static IntPtr GetFocus();

This will give you the handle to the window that currently has input focus, you can then recursively iterate the control tree to find the control with that handle.

Chris Taylor
Keep in mind that calling GetFocus in the LostFocus event will yield the control losing focus, so while GetFocus will give you the current control, you have to have some event to know when to call it.
ctacke
@ctacke - wow, that sounds... complicated. So to sum up, if I call GetFocus at the wrong time (like in the LostFocus event) it will actually change the current focus rather than just tell me what control has focus?
Vaccano
+1  A: 

Using the corell.dll looks like a good idea.

Another possible way is to create GotFocus event handlers for all the controls on your form Then create a class level variable that updates with the name of the control that has the current focus.

dretzlaff17
I tried that (see here: http://stackoverflow.com/questions/2829321/find-the-focused-control-in-a-form-in-netcf) It did not work (\because of the LostFocus going before the GotFocus (as indidcated by Oops)
Vaccano
A: 

I am very grateful to all the answerers and the effort put into the responses. However, this is the solution that ended up working.

I up voted everyone that helped, but for the benefit of those that search this question later, I think this needs to be the accepted answer.

public System.Windows.Forms.Control FindFocusedControl()
{
    return FindFocusedControl(this);
}

public static System.Windows.Forms.Control FindFocusedControl(System.Windows.Forms.Control container)
{
    foreach (System.Windows.Forms.Control childControl in container.Controls)
    {
        if (childControl.Focused)
        {
            return childControl;
        }
    }

    foreach (System.Windows.Forms.Control childControl in container.Controls)
    {
        System.Windows.Forms.Control maybeFocusedControl = FindFocusedControl(childControl);
        if (maybeFocusedControl != null)
        {
            return maybeFocusedControl;
        }
    }

    return null; // Couldn't find any, darn!
}
Vaccano