24

我正在努力解决在 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 但没有获得键盘焦点。我错过了什么吗?除非另一个控件猛烈地保持在我很确定我没有编码的键盘焦点上,否则为什么这段相当简单的代码将无法正常工作。

4

4 回答 4

72

作为一种解决方法,您可以尝试使用 将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最后完成。

于 2012-12-19T15:31:34.543 回答
2

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

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

在后面的代码中

    private void Got_Loaded(object sender, RoutedEventArgs e)
    {
        Keyboard.Focus(((TextBox)sender));
    }
于 2019-09-29T05:34:03.247 回答
0

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

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

于 2017-09-04T14:36:26.037 回答
0

我遇到了类似的问题。

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

我尝试了 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;
}
于 2021-05-09T14:53:48.807 回答