2008-12-05 4 views
0

Мне нужно определить, когда ContainsFocus изменяется на Control (в частности, на форму окна). Переопределение OnGotFocus - не ответ. Когда я выношу форму на передний план, ContainsFocus является истинным, а Focused является ложным. Итак, есть ли OnGotFocus эквивалент для ContainsFocus? Или любым другим способом?Есть ли способ поймать, когда ContainsFocus меняется?

ответ

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..."); 
    } 
+0

Я знаю, что это должно сработать, но OnGotFocus даже не вызывается, когда форма доводится до на переднем плане. Следовательно, CheckContainsFocus() не будет вызван. Таким образом, у вас осталась та же проблема. :( –

+0

События GotFocus дочерних элементов управления запускаются, если у вас есть дочерний элемент управления. В противном случае вызывается OnGotFocus формы. Просто проверьте, вызван ли «private void OnContainsFocus()». Я сделал, он работает. –

+0

Я попробовал, и это сработало. С элементами управления в форме переопределение OnGotFocus никогда не вызывалось, но control_GotFocus действительно вызывался. Вот и все. Спасибо. –

0

Один из способов решения этой проблемы - использовать таймер. Это определенно грубая сила, но она выполняет свою работу:

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; 
} 

Но есть ли более простой способ?

0

Обработка событий GotFocus и LostFocus должна это сделать.

Другое дело отметить ... В SDK говорит это о недвижимости ContainsFocus:

Вы можете использовать это свойство для определения , имеет ли элемент управления или любой из элементов управления, содержащихся в нем вход фокус. Чтобы определить, имеет ли управление фокус, независимо от , имеет ли какой-либо из его дочерних элементов фокус фокус, используется свойство Focused.

EDIT:

При обработке события GotFocus, вы все равно должны проверить Focused/свойство ContainsFocus в зависимости от того, как иерархия элементов управления устанавливается.

Содержит фокусировку, если контроль или любой из его детей имеют фокус. Фокус будет прав, только если конкретный элемент управления имеет фокус, независимо от его детей.

+0

Извините, но, как я уже говорил в этом вопросе, GotFocus не работает для этого. –

+0

@MikeHall прав. GotFocus не запускает родительский элемент управления детьми, который получает фокус. Итак, остается вопрос, как получить событие, когда изменяется родительский ContainsFocus. К сожалению, ответ на этот вопрос работает только для элементов управления, добавленных через Controls.Add, а не если у самих детей есть элементы управления ... – stuzor

Смежные вопросы