2

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

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

那么我怎么能做到这一点..

4

4 回答 4

3

这就是我所做的,它为我工作

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

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

希望它会有所帮助

于 2013-07-23T12:58:25.467 回答
1

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

uiElement.LostFocus+=(o,e)=>
{
      var foo=FocusManager.GetFocusedElement();
}
于 2013-07-23T13:02:36.987 回答
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;
            }
        }
    }

然后在你后面的代码中,创建一个 Focus 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);
    }
}
于 2013-07-23T13:21:59.970 回答
0

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

于 2013-07-23T12:56:47.347 回答