Custom control focus? Anyone?

  • Thread starter Thread starter Tomer
  • Start date Start date
T

Tomer

Hi,

I've wrote a custom control which acts as a radio button, it can recieve
focus, and mouse clicks.
When a message is poped up it steals the focus, and when it is closed the
focus doesn't returns to the radio control.
I've check the same procedure with the regular text box and the focus
returns to the text box after the closing of the message.


How can I change the control so that it will recieve focus automatically?

Tomer.
 
Since no one else did not proposed other solution I'll post obvious one.
You have noticed that a form does not save the focus for a child control
and on activation it recieves focus instead of its child. So, the
solution is to save the last focused control and activate it when a form
will receive the focus:

private Control _lastFocusedControl = null;
protected override void OnDeactivate(EventArgs e)
{
base.OnDeactivate (e);
_lastFocusedControl = GetRecursiveFocusedControl(this);
}

protected override void OnGotFocus(EventArgs e)
{
base.OnGotFocus (e);
if (_lastFocusedControl == null) return;
_lastFocusedControl.Focus();
}

private Control GetRecursiveFocusedControl(Control parent)
{
if (parent.Focused) return parent;

foreach (Control c in parent.Controls)
{
Control t = GetRecursiveFocusedControl(c);
if (t != null) return t;
}

return null;
}

Best regards,
Sergey Bogdanov
http://www.sergeybogdanov.com
 
Thats what I did to solve this problem, but I was hoping for a solution from
the side of the control.


Thanks for the help.

Tomer.
 
Due to the fact that the issue relates to a form behaviour you should
solve it for a form level and not for a single control. Nevertheless you
could apply this technique for a single control too.

Since we have no Control.ParentChanged event for a control we have to
use Control.GotFocus event of your control to attach to several Form
events custom handlers. The drawback of this approach is that if you
have three such controls in a form then you will have three custom
handlers for each form event. Here you are code:


EventHandler deactivateHandler;
EventHandler gotFocusHandler;
public CustomControl()
{
deactivateHandler = new EventHandler(Form_Deactivate);
gotFocusHandler = new EventHandler(Form_GotFocus);
}

protected void OnGotFocus(object sender, EventArgs e)
{
base.OnGotFocus (e);

// attach Deactivate/GotFocus handlers to a form
Form f = TopLevelControl as Form;
// since the GotFocus invokes many times for a control lifetime
// you have to make sure that only one event handler will be // attached
f.Deactivate -= deactivateHandler;
f.Deactivate += deactivateHandler;
f.GotFocus -= gotFocusHandler;
f.GotFocus += gotFocusHandler;
}

private Control _lastFocusedControl = null;
private void Form_Deactivate(object sender, EventArgs e)
{
_lastFocusedControl = GetRecursiveFocusedControl(this);
}

private void Form_GotFocus(object sender, EventArgs e)
{
if (_lastFocusedControl == null) return;
if (!_lastFocusedControl.Focused) _lastFocusedControl.Focus();
}

private Control GetRecursiveFocusedControl(Control parent)
{
if (parent.Focused) return parent;

foreach (Control c in parent.Controls)
{
Control t = GetRecursiveFocusedControl(c);
if (t != null) return t;
}

return null;
}

Best regards,
Sergey Bogdanov
http://www.sergeybogdanov.com
 
I see, Thank you!

Tomer.

Sergey Bogdanov said:
Due to the fact that the issue relates to a form behaviour you should
solve it for a form level and not for a single control. Nevertheless you
could apply this technique for a single control too.

Since we have no Control.ParentChanged event for a control we have to use
Control.GotFocus event of your control to attach to several Form events
custom handlers. The drawback of this approach is that if you have three
such controls in a form then you will have three custom handlers for each
form event. Here you are code:


EventHandler deactivateHandler;
EventHandler gotFocusHandler;
public CustomControl()
{
deactivateHandler = new EventHandler(Form_Deactivate);
gotFocusHandler = new EventHandler(Form_GotFocus);
}

protected void OnGotFocus(object sender, EventArgs e)
{
base.OnGotFocus (e);

// attach Deactivate/GotFocus handlers to a form
Form f = TopLevelControl as Form;
// since the GotFocus invokes many times for a control lifetime
// you have to make sure that only one event handler will be // attached
f.Deactivate -= deactivateHandler;
f.Deactivate += deactivateHandler;
f.GotFocus -= gotFocusHandler;
f.GotFocus += gotFocusHandler;
}

private Control _lastFocusedControl = null;
private void Form_Deactivate(object sender, EventArgs e)
{
_lastFocusedControl = GetRecursiveFocusedControl(this);
}

private void Form_GotFocus(object sender, EventArgs e)
{
if (_lastFocusedControl == null) return;
if (!_lastFocusedControl.Focused) _lastFocusedControl.Focus();
}

private Control GetRecursiveFocusedControl(Control parent)
{
if (parent.Focused) return parent;

foreach (Control c in parent.Controls)
{
Control t = GetRecursiveFocusedControl(c);
if (t != null) return t;
}

return null;
}

Best regards,
Sergey Bogdanov
http://www.sergeybogdanov.com
 
Back
Top