代码之家  ›  专栏  ›  技术社区  ›  Kasper Holdum

在WPF中的GUI上处理选定的对象

  •  2
  • Kasper Holdum  · 技术社区  · 15 年前

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

    1. 鼠标点击它;
    2. 当它获得焦点时;
    3. 当上述两种情况中的任何一种发生在用户控件的子控件上时。

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

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

    我正在寻找关于如何实现这个特性以及我可以/应该多依赖焦点机制的建议。最后,我不介意是否只能选择一个对象,但如果它很容易扩展到多选,那么我也不介意。

    为了澄清这一点,我知道我可以通过处理大量事件和跟踪状态手动构建这一模型,但我只是希望能找到一种更简单的方法。

    3 回复  |  直到 14 年前
        1
  •  1
  •   Ray Burns    15 年前

    联合 UIElement.IsKeyboardFocusWithin 用一个 PreviewMouseDown 汉德勒:

    1. 什么时候? 预览鼠标向下 调用时,设置标志并使用 Dispatcher.BeginInvoke DispatcherPriority.Input 如果仍设置了标志,则将焦点设置为用户控件。

    2. 为设置处理程序 uielement.iskeyboardfocuswithin 用户控件中的属性更改。当处理程序触发时,清除标志。

    这里的想法是,如果单击用户控件和键盘焦点上的任何位置都不会导致焦点移动到用户控件中,则强制将焦点移动到用户控件中。

    仅供参考,下面是第1步在代码中的大致情况:

    public override OnPreviewMouseDown(MouseButtonEventArgs e)
    {
      _mouseClickedButNoFocus = true;
      Dispatcher.BeginInvoke(DispatcherPriority.Input, new Action(() =>
      {
        if(_mouseClickedButNoFocus)
          Focus();
      });
    }
    
        2
  •  1
  •   Thomas Levesque    15 年前

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

        3
  •  1
  •   Yogesh    15 年前

    当任何子项使用键盘焦点时,可以将逻辑焦点设置为控件。 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