4

I'm implementing copy-paste in a Windows Forms application. I need to enable/disable the bar-buttons for this two operations when the user changes the focused element in the application.

I can find the current focused control using something like this: http://www.syncfusion.com/FAQ/windowsforms/faq_c41c.aspx#q1021q, but how can I detect that the focused control has changed?

4 Answers4

11

In your form load event handler you could also loop through all of the controls contained in the form and for each focusable control add an event handler for the Enter event:

    private void Form1_Load(object sender, EventArgs e)
    {
        foreach (Control control in Controls)
        {
            control.Enter += ControlReceivedFocus;
        }
    }

    void ControlReceivedFocus(object sender, EventArgs e)
    {
        Debug.WriteLine(sender + " received focus.");
    }
Paul Sasik
  • 79,492
  • 20
  • 149
  • 189
  • I've done exactly this (although it's essentially the same as sztomi's answer, I like that you've provided a code example) many times, and it's the best solution. Although, you'll also need a ControlLostFocus (or ControlValidating depending on what you're doing) to disable the menu items. – overslacked Jul 21 '09 at 17:04
  • 7
    You also may need to iterate the child controls ... `if (control.HasChildren)`... – CAD bloke Apr 23 '13 at 11:02
  • To recurse through and attach the event handler to all child controls, check out [Recursive control search with LINQ](https://stackoverflow.com/a/253962/1366033) – KyleMit Nov 26 '19 at 17:39
2

My proposal is to use Application.Idle event.

  • Write logic that enables/disables your buttons in Application.Idle event.
  • Subscribe to Application.Idle event on form shown event
  • Check button availability on button click (so you never pass accidental click under heavy load)
  • Do not forget to remove Idle handler on form disposing (or closing), because this is static event

Using this technique you will always have correct buttons state, and you not need to worry about subscribing to many controls events to detect focus change. This is also light-weight approach, because Idle event is raised only when application is not busy.

arbiter
  • 9,447
  • 1
  • 32
  • 43
1

I think you should add an event handler to the control (or if you have many of the same type, subclass it, and override the appropriate OnChange handler). This way you won't have to 'find' the focused control (it will be given as the sender parameter), and the event will only arise when the change actually happened.

Tamás Szelei
  • 23,169
  • 18
  • 105
  • 180
0

To detect the focus on a control you can create this event:

void MyGotFocus(object sender, EventArgs e)
{
    if (sender is TextBox)
    {
        //TODO YOUR OPERATION
        //FOR EXAMPLE
        (sender as TextBox).SelectAll();
    }
}

and the next step is to associate the control and event by code:

myText1.GotFocus += MyGotFocus;
myText2.GotFocus += MyGotFocus;
daniele3004
  • 13,072
  • 12
  • 67
  • 75