【问题标题】:Handling selected objects on the GUI in WPF在 WPF 中处理 GUI 上的选定对象
【发布时间】:2009-11-15 19:33:01
【问题描述】:

我在 WPF 中构建了几个用户控件,它们都被添加到画布中。我想添加一个跟踪当前选定的用户控件的行为。应在以下情况下选择用户控件:

  1. 鼠标点击它;
  2. 收到焦点时;
  3. 当上述两种情况之一发生在用户控件的子控件上时。

有没有办法纯粹通过使用 WPF 的焦点机制来处理这个问题,还是我需要在焦点类的帮助下自己处理这个问题?

我已经阅读了 WPF 中处理焦点的新方法,我面临的问题是键盘焦点决定了当前选择的对象是什么,但我的控件的某些部分无法接收键盘因此即使单击了这些部分,用户控件也不会获得焦点。

我正在寻求有关如何实现此功能以及我可以/应该在多大程度上依赖焦点机制的建议。最后,如果只能选择一个对象,我不介意,但如果它很容易扩展到多选,那么我也不介意。

澄清一下,我知道我可以通过处理大量事件并跟踪状态来手动构建它,但我只是希望有一种更简单的方法可用。

【问题讨论】:

    标签: c# wpf user-interface focus


    【解决方案1】:

    将UIElement.IsKeyboardFocusWithin 与PreviewMouseDown 处理程序结合起来:

    1. 当调用PreviewMouseDown 时,设置一个标志并使用Dispatcher.BeginInvoke 在DispatcherPriority.Input 安排回调,以将焦点设置到UserControl(如果该标志仍然设置)。

    2. 为您的 UserControl 中的UIElement.IsKeyboardFocusWithin 属性更改设置处理程序。当处理程序触发时,清除标志。

    这里的想法是,如果您单击 UserControl 上的任意位置并且键盘焦点不会导致焦点移动到 UserControl 中,则将其强制移动到 UserControl 中。

    仅供参考,代码中的步骤 1 大致如下所示:

    public override OnPreviewMouseDown(MouseButtonEventArgs e)
    {
      _mouseClickedButNoFocus = true;
      Dispatcher.BeginInvoke(DispatcherPriority.Input, new Action(() =>
      {
        if(_mouseClickedButNoFocus)
          Focus();
      });
    }
    

    【讨论】:

      【解决方案2】:

      您可以使用UIElement.IsKeyboardFocusWithin 属性,当 UIElement 或其子元素之一具有键盘焦点时,该属性为真。它是一个依赖属性,因此您可以轻松地将其用于样式中的触发器

      【讨论】:

      • 问题是用户控件的某些部分无法接收键盘输入,当这些被点击时,控件仍然应该被选中。
      【解决方案3】:

      当任何孩子使用FocusManager.IsFocusScope="True" 获得键盘焦点时,您可以将逻辑焦点设置到控件。将键盘焦点设置为控件或尝试这样做会占用子控件的键。

      如果有任何孩子有焦点,您可以使用UIElement.IsKeyboardFocusWithin 设置控件的焦点。

      你可以阅读这篇文章,我认为它很好地描述了逻辑和键盘焦点之间的区别:

      http://www.pluralsight.com/community/blogs/eburke/archive/2009/03/18/why-is-focus-in-wpf-so-tricky-managing-and-understanding-focus-in-a-wpf-application.aspx

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-04-16
        • 2013-06-30
        • 2014-01-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多