Je dois être en mesure de déterminer quand ContainsFocus
changements sur un Control
(spécifiquement un formulaire Windows). Overriding OnGotFocus
n'est pas la réponse. Lorsque j'apporte le formulaire au premier plan, ContainsFocus
est vrai et Focused
est faux. Donc, y a-t-il un OnGotFocus
équivalent pour ContainsFocus
? Ou de toute autre manière?Y at-il un moyen d'attraper quand ContainsFocus change?
Répondre
Remarque: Les événements GotFocus des contrôles enfants sont déclenchés si vous avez un contrôle enfant. Sinon, OnGotFocus du formulaire est appelé.
Si je comprends bien la question, cela devrait fonctionner:
bool lastNotificationWasGotFocus = false;
protected override void OnControlAdded(ControlEventArgs e)
{
SubscribeEvents(e.Control);
base.OnControlAdded(e);
}
protected override void OnControlRemoved(ControlEventArgs e)
{
UnsubscribeEvents(e.Control);
base.OnControlRemoved(e);
}
private void SubscribeEvents(Control control)
{
control.GotFocus += new EventHandler(control_GotFocus);
control.LostFocus += new EventHandler(control_LostFocus);
control.ControlAdded += new ControlEventHandler(control_ControlAdded);
control.ControlRemoved += new ControlEventHandler(control_ControlRemoved);
foreach (Control innerControl in control.Controls)
{
SubscribeEvents(innerControl);
}
}
private void UnsubscribeEvents(Control control)
{
control.GotFocus -= new EventHandler(control_GotFocus);
control.LostFocus -= new EventHandler(control_LostFocus);
control.ControlAdded -= new ControlEventHandler(control_ControlAdded);
control.ControlRemoved -= new ControlEventHandler(control_ControlRemoved);
foreach (Control innerControl in control.Controls)
{
UnsubscribeEvents(innerControl);
}
}
private void control_ControlAdded(object sender, ControlEventArgs e)
{
SubscribeEvents(e.Control);
}
private void control_ControlRemoved(object sender, ControlEventArgs e)
{
UnsubscribeEvents(e.Control);
}
protected override void OnGotFocus(EventArgs e)
{
CheckContainsFocus();
base.OnGotFocus(e);
}
protected override void OnLostFocus(EventArgs e)
{
CheckLostFocus();
base.OnLostFocus(e);
}
private void control_GotFocus(object sender, EventArgs e)
{
CheckContainsFocus();
}
private void control_LostFocus(object sender, EventArgs e)
{
CheckLostFocus();
}
private void CheckContainsFocus()
{
if (lastNotificationWasGotFocus == false)
{
lastNotificationWasGotFocus = true;
OnContainsFocus();
}
}
private void CheckLostFocus()
{
if (ContainsFocus == false)
{
lastNotificationWasGotFocus = false;
OnLostFocus();
}
}
private void OnContainsFocus()
{
Console.WriteLine("I have the power of focus!");
}
private void OnLostFocus()
{
Console.WriteLine("I lost my power...");
}
Une façon de résoudre ce problème consiste à utiliser une minuterie. C'est vraiment de la force brute, mais ça fait le travail:
private Timer m_checkContainsFocusTimer = new Timer();
private bool m_containsFocus = true;
m_checkContainsFocusTimer.Interval = 1000; // every second is good enough
m_checkContainsFocusTimer.Tick += new EventHandler(CheckContainsFocusTimer_Tick);
m_checkContainsFocusTimer.Start();
private void CheckContainsFocusTimer_Tick(object sender, EventArgs e)
{
if (!m_containsFocus && ContainsFocus)
OnAppGotFocus();
m_containsFocus = ContainsFocus;
}
Mais y a-t-il un moyen plus facile?
La gestion des événements GotFocus et LostFocus devrait le faire.
Une autre chose à noter ... le SDK dit ceci au sujet de la propriété ContainsFocus:
Vous pouvez utiliser cette propriété pour déterminer si un contrôle ou l'un des contrôles qu'il contient a l'entrée concentrer. Pour déterminer si le contrôle a le focus, indépendamment de si l'un de ses contrôles enfants a le focus , utilisez la propriété Focused.
EDIT:
Lors de la manipulation de l'événement GotFocus, vous pouvez toujours avoir à vérifier la propriété Focused/ContainsFocus selon la façon dont la hiérarchie de vos contrôles est mis en place.
ContainsFocus sera vrai si le contrôle ou l'un de ses enfants ont un focus. Le focus ne sera vrai que si le contrôle spécifique a le focus, indépendamment de ses enfants.
Désolé, mais comme je l'ai dit dans la question, GotFocus ne fonctionne pas pour cela. –
@MikeHall a raison. GotFocus ne tire pas sur le parent un de ses contrôles enfants obtient le focus. Ainsi, la question est toujours comment obtenir un événement lorsque le parent ContainsFocus change. Malheureusement, la réponse à cette question ne fonctionne que pour les contrôles ajoutés via Controls.Add, pas si les enfants eux-mêmes ont des contrôles ajoutés ... – stuzor
Je sais que cela devrait fonctionner, mais OnGotFocus n'est même pas appelé lorsque le formulaire est porté à la premier plan. Par conséquent, CheckContainsFocus() ne sera pas appelé. Donc, vous êtes à gauche avec le même problème. :( –
Les événements GotFocus des contrôles enfants sont déclenchés si vous avez un contrôle enfant.Sinon OnGotFocus du formulaire est appelé.Vérifiez simplement si "private void OnContainsFocus()" est appelé ou non.Il l'a fait et il fonctionne –
Je l'ai essayé et ça a marché.Avec des contrôles sur le formulaire, l'override OnGotFocus n'a jamais été appelé, mais le control_GotFocus était en effet appelé, alors c'était tout. –