我需要能够确定ContainsFocus
(特别是Windows窗体)上Control
的更改时间。覆盖OnGotFocus
不是答案。当我将表单带到前台时,ContainsFocus
为真,Focused
为假。那么OnGotFocus
是否有ContainsFocus
等价物?或者其他任何方式?
答案 0 :(得分:2)
注意:如果您有子控件,则会触发子控件的GotFocus事件。否则调用表单的OnGotFocus。
如果我正确理解了这个问题,那么这应该有效:
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...");
}
答案 1 :(得分:0)
解决此问题的一种方法是使用Timer。这绝对是蛮力,但它完成了工作:
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;
}
但有更简单的方法吗?
答案 2 :(得分:0)
处理GotFocus和LostFocus事件应该这样做。
需要注意的另一件事...... SDK说明了ContainsFocus属性:
您可以使用此属性来确定 无论是控制还是任何控制 其中包含的控件有 输入焦点。判断是否 无论如何,控制都有焦点 是否有任何子控件 焦点,使用聚焦属性。
编辑:
处理GotFocus事件时,您可能仍需要检查Focused / ContainsFocus属性,具体取决于控件层次结构的设置方式。
如果控件或其任何子项具有焦点,则ContainsFocus将为true。 只有当具体控制本身具有焦点时,焦点才会成立,无论其子女如何。