需要知道当另一个元素失去焦点时,哪个元素会得到焦点

本文关键字:元素 焦点 失去 另一个 | 更新日期: 2023-09-27 18:24:34

我在一个窗口中有许多控件。要求是知道哪个控件从控件的失焦事件中获得焦点。

比如说,一个文本框,它有焦点。现在我正在点击一个按钮。在执行此操作时,需要知道我正在将焦点从文本框失去焦点事件移动到按钮。

那么我该如何做到这一点呢。。

需要知道当另一个元素失去焦点时,哪个元素会得到焦点

这就是我所做的,它对我来说是有效的

 protected override void OnPreviewLostKeyboardFocus(KeyboardFocusChangedEventArgs e)
   {
     lostFocusControl = e.OldFocus;
   }
   private void PauseBttn_PreviewKeyDown(object sender, KeyEventArgs e)
   {
      /**invoke OnPreviewLostKeyboardFocus handller**/
   }

希望它能帮助

您可以使用FocusManager来处理此问题,在LostFocusEvent中,使用FocusManager.GetFocusedElement()

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

下面的类监视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;
            }
        }
    }

然后在你的代码中,创建一个新的FocusNotifier类实例,并挂接到它的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);
    }
}

您是否尝试将控件注册到Control.LostFocus事件,在那里您可以检查Form.ActiveControl,以确定哪个控件当前具有焦点