2013-07-23 2 views
2

У меня есть много элементов управления в окне. Требование состоит в том, чтобы знать, какой контроль получает фокус от потерянного фокусного события элемента управления.Нужно знать, какой элемент получить фокус, когда другой элемент потерял фокус

Скажите, текстовое поле и оно имеет фокус. Теперь я нажимаю кнопку. при этом нужно знать, что я перемещаю фокус на кнопку из поля «потерянное фокусное поле» в текстовом поле.

Так как же я этого добиться ..

+0

вы могли бы подписаться все элементы управления в том же событии GetFocus и проверить отправителя там – Jonesopolis

+2

Вполне вероятно, что 'потеряли focus' событие будет срабатывать до того, как кнопка даже получает фокус. Вы должны подумать об этом или, по крайней мере, подтвердить, верно ли это. Возможно, стоит сказать нам, какую конечную цель вы пытаетесь достичь, может быть альтернативный подход – musefan

+0

Согласитесь с @musefan, ** Возможно, стоит сказать нам, какую конечную цель вы пытаетесь достичь, может быть альтернативный подход **. –

ответ

0

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

Просто добавьте эти два класса в свой проект.

public class FocusNotifierEventArgs : EventArgs 
    { 
     public object OldObject { get; set; } 
     public object NewObject { get; set; } 
    } 

    public class FocusNotifier : IDisposable 
    { 
     public event EventHandler<FocusNotifierEventArgs> OnFocusChanged; 
     bool isDisposed; 
     Thread focusWatcher; 
     Dispatcher dispatcher; 
     DependencyObject inputScope; 
     int tickInterval; 

     public FocusNotifier(DependencyObject inputScope, int tickInterval = 10) 
     { 
      this.dispatcher = inputScope.Dispatcher; 
      this.inputScope = inputScope; 
      this.tickInterval = tickInterval; 
      focusWatcher = new Thread(new ThreadStart(FocusWatcherLoop)) 
      { 
       Priority = ThreadPriority.BelowNormal, 
       Name = "FocusWatcher" 
      }; 
      focusWatcher.Start(); 
     } 

     IInputElement getCurrentFocus() 
     { 
      IInputElement results = null; 
      Monitor.Enter(focusWatcher); 
      dispatcher.BeginInvoke(new Action(() => 
       { 
        Monitor.Enter(focusWatcher); 
        results = FocusManager.GetFocusedElement(inputScope); 
        Monitor.Pulse(focusWatcher); 
        Monitor.Exit(focusWatcher); 
       })); 
      Monitor.Wait(focusWatcher); 
      Monitor.Exit(focusWatcher); 
      return results; 
     } 

     void FocusWatcherLoop() 
     { 
      object oldObject = null; 
      while (!isDisposed) 
      { 
       var currentFocus = getCurrentFocus(); 
       if (currentFocus != null) 
       { 
        if (OnFocusChanged != null) 
         dispatcher.BeginInvoke(OnFocusChanged, new object[]{ this, new FocusNotifierEventArgs() 
         { 
          OldObject = oldObject, 
          NewObject = currentFocus 
         }}); 
        oldObject = currentFocus; 
        } 
       } 
       Thread.Sleep(tickInterval); 
      } 
     } 

     public void Dispose() 
     { 
      if (!isDisposed) 
      { 
       isDisposed = true; 
      } 
     } 
    } 

Затем в коде позади, создать новый экземпляр класса Фокус Notifier и крючок на это OnFocusChanged событие, не забудьте утилизировать его в конце или нить будет держать ваше приложение открытым.

public partial class MainWindow : Window 
{ 
    FocusNotifier focusNotifier; 

    public MainWindow() 
    { 
     InitializeComponent(); 
     focusNotifier = new FocusNotifier(this); 
     focusNotifier.OnFocusChanged += focusNotifier_OnFocusChanged; 
    } 

    void focusNotifier_OnFocusChanged(object sender, FocusNotifierEventArgs e) 
    { 
     System.Diagnostics.Debug.WriteLine(e.OldObject); 
     System.Diagnostics.Debug.WriteLine(e.NewObject); 

    } 

    protected override void OnClosing(System.ComponentModel.CancelEventArgs e) 
    { 
     focusNotifier.Dispose(); 
     base.OnClosing(e); 
    } 
} 
0

вы пытались зарегистрировать элементы управления Control.LostFocus событие, и там вы можете проверить Form.ActiveControl, чтобы определить, какой контроль в настоящее время имеет фокус

2

Это то, что я сделал, и его работу для меня

protected override void OnPreviewLostKeyboardFocus(KeyboardFocusChangedEventArgs e) 
    { 
    lostFocusControl = e.OldFocus; 
    } 

    private void PauseBttn_PreviewKeyDown(object sender, KeyEventArgs e) 
    { 
     /**invoke OnPreviewLostKeyboardFocus handller**/ 
    } 

Надеется, что это поможет

1

Вы можете использовать FocusManager справиться с этим, В вашем LostFocusEvent, используйте FocusManager.GetFocusedElement()

uiElement.LostFocus+=(o,e)=> 
{ 
     var foo=FocusManager.GetFocusedElement(); 
} 
+0

Это даст текущий элемент. Мне нужно знать элемент, который будет фокусироваться. – Sankarann

+0

nop, GetFocusedElement возвращает новый элемент, на который вы нажали :-) Проверено с помощью простого образца ;-) –

+0

Это самый простой и правильный ответ на мой взгляд. Благодаря! –