WPF:在用户控件中设置键盘焦点?(键绑定问题)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12866392/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 23:32:55  来源:igfitidea点击:

WPF: Setting Keyboard Focus in a User Control? (Problems with KeyBinding)

wpfxamlfocus

提问by Jeff Dege

I have an app that has a main window that contains a bunch of stuff. From time to time the user will do something in response to which I want to display something else entirely in the main window, temporarily hiding what is there.

我有一个应用程序,它的主窗口包含一堆东西。有时用户会做一些我想在主窗口中完全显示其他内容的响应,暂时隐藏那里的内容。

I'm doing this by making the outermost element in the main window a Grid with no rows or columns defined. Every element in the grid, then will completely fill the one single cell in the grid, drawing on top of the others.

我通过将主窗口中的最外层元素设为一个没有定义行或列的网格来实现这一点。网格中的每个元素都将完全填充网格中的一个单元格,并在其他单元格之上绘制。

My regular bunch stuff, then, is in the first element of the grid, and my temporary something else is a UserControl as the second element of the grid, that is normally set Visibility=Collapsed.

然后,我的常规一堆东西位于网格的第一个元素中,而我的其他临时元素是 UserControl 作为网格的第二个元素,通常设置为 Visibility=Collapsed。

Except for the KeyBinding everything works fine. When the appropriate command is triggered in the regular bunch of stuff, the visibility on the UserControl is set to Visible, and it covers the regular bunch of stuff completely. When the user clicks on the close button on the UserControl, it's visibility is set to Collapsed, again, and it disappears and the regular bunch of stuff is revealed.

除了 KeyBinding 一切正常。当在常规的一堆东西中触发适当的命令时,UserControl 上的可见性设置为 Visible,它完全覆盖了常规的一堆东西。当用户单击 UserControl 上的关闭按钮时,它的可见性再次设置为 Collapsed,然后它消失并显示常规的一堆东西。

My problem is with KeyBindings. I have a few defined on the UserControl - that should not be defined on the main window - and they don't work. Or rather, they work fine once I click inside the UserControl, but they don't work until I do.

我的问题是 KeyBindings。我在 UserControl 上定义了一些 - 不应在主窗口上定义 - 它们不起作用。或者更确切地说,一旦我在 UserControl 内部单击,它们就可以正常工作,但是直到我这样做时它们才起作用。

I need them to work as soon as the UserControl is made visible, without requiring the user to click or tab into the UserControl proper.

我需要它们在 UserControl 可见后立即工作,而无需用户单击或选项卡进入 UserControl 正确的位置。

My guess is that this has something to do with keyboard focus - but I've been unable to find a way to set the focus on the UserControl. Here's the thing - the only element within the UserControl is a tab control, all of the tabs of which are dynamically constructed via templates. There are no elements known at compile time that I can reference explicitly and pass to KeyBoard.Focus().

我的猜测是这与键盘焦点有关 - 但我一直无法找到将焦点设置在 UserControl 上的方法。事情就是这样 - UserControl 中唯一的元素是选项卡控件,所有选项卡都是通过模板动态构建的。在编译时没有已知的元素可以显式引用并传递给 KeyBoard.Focus()。

So, am I right in thinking that it's lack of focus that is causing the problem? And if so, how can I set focus to an element in a TabControl, when I don't even know how many tabs there are, let alone which is the selected one?

那么,我认为导致问题的原因是注意力不集中是正确的吗?如果是这样,当我什至不知道有多少选项卡时,如何将焦点设置到 TabControl 中的元素,更不用说哪个是选定的选项卡?

回答by Jeff Dege

I wanted this control to have the focus, when it became visible. So in the constructor, I set up a handler on IsVisibleChanged.

当它变得可见时,我希望这个控件具有焦点。所以在构造函数中,我在 IsVisibleChanged 上设置了一个处理程序。

public MyControl
{
    ...
    this.IsVisibleChanged += new DependencyPropertyChangedEventHandler(MyControl_IsVisibileChanged);
}

void MyControl_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
    if (!(bool(e.NewValue)
        return;
    this.Focusable = true;
    Keyboard.Focus(this);
}

I could have set Focusable in the xaml, but I prefer it in the code-behind, so that all of the relevant code is in one place.

我可以在 xaml 中设置 Focusable,但我更喜欢在代码隐藏中设置,以便所有相关代码都在一个地方。

回答by Daniel Jonsson

For me this worked in the code-behind:

对我来说,这在代码隐藏中起作用:

using System.Windows.Input;

namespace MyApplication.Views.Dialogs
{
    public partial class MyControl
    {
        public MyControl()
        {
            InitializeComponent();
            Loaded += (sender, args) =>
            {
                MyButton.Focus();
                Keyboard.Focus(MyButton);
            };
        }
    }
}