【问题标题】:Keyboard.Focus does not work on text box in WPFKeyboard.Focus 不适用于 WPF 中的文本框
【发布时间】:2012-12-06 23:30:42
【问题描述】:

我正在努力解决在 wpf 中看起来如此简单的问题,但我还没有发现为什么我不能让我的应用程序按照我的计划运行。

当用户按下 ctrl+f 时,我的 wpf 应用程序中会弹出一个小的搜索框。我想要的只是插入符号在搜索框文本框中闪烁,准备好接受任何用户输入,而无需用户单击它。这是文本框的 xaml 代码,它是可见的、启用的、可点击测试的、可制表符的和可聚焦的。

   <TextBox x:Name="SearchCriteriaTextBox" Text="{Binding SearchCriteria}" Focusable="True" IsEnabled="True" IsTabStop="True" IsHitTestVisible="True" Style="{DynamicResource SearchTextBoxStyle}" Grid.Column="1" Margin="5,10,0,5" />

在后面的代码中,当搜索框的可见性受到影响时,我会调用此方法。搜索框在应用启动时加载。

    /// <summary>
    /// Handles events triggered from focusing on this view.
    /// </summary>
    /// <param name="sender">The sender.</param>
    /// <param name="dependencyPropertyChangedEventArgs">The key event args.</param>
    private void OnIsVisibleChanged(object sender, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
    {
        if (!((bool) dependencyPropertyChangedEventArgs.NewValue))
        {
            return;
        }

        SearchCriteriaTextBox.Focus();
        Keyboard.Focus(SearchCriteriaTextBox);
        SearchCriteriaTextBox.Select(0, 0);

        if (SearchCriteriaTextBox.Text.Length > 0)
        {
            SearchCriteriaTextBox.SelectAll();
        }
    }

问题是,代码被调用,组件变为 IsFocused=true 但没有获得键盘焦点。 我错过了什么吗?除非另一个控件一直保持在我很确定我没有编码的键盘焦点上,否则为什么这段相当简单的代码不能正常工作。

【问题讨论】:

  • 在 Loaded 事件之后尝试这样做。
  • 我猜想在调用此方法后另一个控件会获得焦点。也许你应该把焦点放在另一个事件上。
  • @HighCore 我有一个问题:每次可见性变化时都会触发 Loaded 事件吗?
  • 不。它在控件加载时触发,但由于您没有发布足够的代码来了解您如何创建或显示您的控件,我只是在猜测。
  • 您的 OnIsVisibleChanged 代码实际上解决了我自己的问题!

标签: c# wpf xaml textbox focus


【解决方案1】:

我遇到了类似的问题。

在我的情况下,我需要一个特定的文本框在弹出模式窗口后获得键盘焦点。这将节省用户在开始提供输入信息之前将焦点移至此文本框的额外工作。

我尝试了 Window.Loaded += (o, e) => Keyboard.Focus(textBox),但这不起作用。

所以我使用了一种解决方法,并且完成了工作,即使认为它可能不是那么优雅。

这里是:

Window.PreviewKeyDown += Window_PreviewKeyDown;

private void Window_PreviewKeyDown(object sender, KeyEventArgs e) {
    Keyboard.Focus(TextBox);
    Window.PreviewKeyDown -= Window_PreviewKeyDown;
}

【讨论】:

    【解决方案2】:

    在 Rachel 的解决方案的基础上,有一个更简单的方法。

    在 XAML 中添加到 TextBox Loaded="Got_Loaded"

    在后面的代码中

        private void Got_Loaded(object sender, RoutedEventArgs e)
        {
            Keyboard.Focus(((TextBox)sender));
        }
    

    【讨论】:

      【解决方案3】:

      如果它对我有这个问题的任何人有帮助,并且我的应用程序有一个主窗口,其中多个用户控件放置在具有可见性数据绑定的单独网格中。因为在构建应用程序时网格就在那里,所以在 Loaded 或 Constructor 上调用的 .Focus() 将在构建时调用,而不是在可见性时调用。

      无论如何,我通过在网格的 MouseEnter 事件上调用 .Focus() 来修复它。适合我。

      【讨论】:

        【解决方案4】:

        作为一种解决方法,您可以尝试使用Dispatcher 将焦点设置在稍后的DispatcherPriority,例如Input

        Dispatcher.BeginInvoke(DispatcherPriority.Input,
            new Action(delegate() { 
                SearchCriteriaTextBox.Focus();         // Set Logical Focus
                Keyboard.Focus(SearchCriteriaTextBox); // Set Keyboard Focus
             }));
        

        从您的问题描述来看,您似乎没有设置键盘焦点。 WPF 可以有多个焦点范围,因此多个元素可以有逻辑焦点 (IsFocused = true),但是只有一个元素可以有键盘焦点并接收键盘输入。

        您发布的代码应该正确设置焦点,因此之后必须发生某些事情才能将键盘焦点移出您的TextBox。通过将焦点设置为稍后的调度程序优先级,您将确保将键盘焦点设置为您的SearchCriteriaTextBox 最后完成。

        【讨论】:

        • 刚刚发现,即将发布我自己的回复,感谢 Rachel,它确实在多线程环境中完美运行。编辑:您可以调用 Dispatcher.BeginInvoke(DispatcherPriority.Input, new ThreadStart(() => SearchCriteriaTextBox.Focus()));获得相同的结果,而无需调用文本框焦点
        • 这对我有用:MessageBox.Show("foo"); myTextBox.Select(0, myTextBox.Text.Length); myTextBox.Focus();
        • 有人解释过这个问题吗?
        • 我尝试了所有方法,从键盘焦点到将 Focusable 设置为 true 并将可见性设置为 true,然后调用 Focus,还尝试了 FocusManager,但这是唯一有效的方法。
        猜你喜欢
        • 2014-01-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-04-25
        相关资源
        最近更新 更多