在WPF中设置文本框焦点

135

如何在WPF中设置TextBox元素的焦点。

我有这段代码:

txtCompanyID.Focusable = true;
txtCompanyID.Focus();

... 但是它没有起作用。

有什么想法吗?


txtCompanyID.Focusable = true; Keyboard.Focus(txtCompanyID); 这是它的工作方式。 - MindRoasterMir
@MindRoasterMir 对我也有效。 - Willy
10个回答

182

在 XAML 中:

<StackPanel FocusManager.FocusedElement="{Binding ElementName=Box}">
   <TextBox Name="Box" />
</StackPanel>

11
我更喜欢这种方法,因为它符合MVVM的架构。 - Todd Sprang
2
聚焦元素是只读的,如何在XAML中设置? 我尝试了以下代码,但没有起作用:<Style.Triggers> <Trigger Property="Validation.HasError" Value="True"> <Setter Property="FocusManager.FocusedElement" Value="{Binding Source={RelativeSource Self}}"/> </Trigger> </Style.Triggers> - WPFKK
@user841612,请查看以下链接并验证程序集和命名空间 https://msdn.microsoft.com/zh-cn/library/system.windows.input.focusmanager.focusedelement(v=vs.110).aspx - usefulBee
这只能起作用一次。如果您想在构建页面后更改焦点,则需要以编程方式执行此操作。 - Joe Steele
这也可以工作。txtCompanyID.Focusable = true; Keyboard.Focus(txtCompanyID); - MindRoasterMir
这个方法可行,但是我必须在最外层容器上编写FocusManager.FocusedElement属性(在我的情况下是DockPanel),而不是直接包含TextBox的DockPanel上。 - Sandra

72

到目前为止,还没有人解释为什么问题中的代码不起作用。我猜测代码放在了Window的构造函数中。但此时设置焦点为时机过早。必须在窗口准备好交互后才能执行。最好的地方是Loaded事件中的代码:

public KonsoleWindow() {
  public TestWindow() {
    InitializeComponent();
    Loaded += TestWindow_Loaded;
  }

  private void TestWindow_Loaded(object sender, RoutedEventArgs e) {
    txtCompanyID.Focus();
  }
}

1
逻辑上是正确的,经过艰苦卓绝的努力,这个答案非常好,完美地解决了问题。 - shivani
这个对我有用。被接受的答案没有。谢谢。 - BoundForGlory
不确定是否是版本特定,但 Focus() 需要一个焦点状态参数,例如 txtCompanyId.Focus(FocusState.Keyboard) - Dan
是的,在Loaded事件中可以工作。 - Willy

52

5
如果你想要聚焦的元素父元素,那该怎么办呢? - Brock Hensley
10
FocusManager.SetFocusedElement(FocusManager.GetFocusScope(parentElement), parentElement);将父元素设置为焦点作用域的焦点元素。 - Philter

31
txtCompanyID.Focusable = true;
Keyboard.Focus(txtCompanyID);

MSDN:

在整个桌面上,只能有一个具有键盘焦点的元素。在 WPF 中,具有键盘焦点的元素将设置 IsKeyboardFocused 为 true。

您可以在设置行之后进行分隔,并检查 IsKeyboardFocused 属性的值。还要检查是否确实到达该行或者您设置了其他元素来获取焦点。


23
尝试这样做:MyTextBox.Focus ( );

2
这是最优雅的答案,而且不需要您指定父级。谢谢,它对我非常有效! - dbeachy1
Peter Huber的回答做到了这一点,但解释说窗口需要先加载,这就是为什么我的不起作用。 - Adriaan Davel

21

因为我使用的是网格而不是StackPanel,所以这些都对我没用。

最后我找到了这个例子: http://spin.atomicobject.com/2013/03/06/xaml-wpf-textbox-focus/

并将其修改为:

在“资源”部分:

    <Style x:Key="FocusTextBox" TargetType="Grid">
        <Style.Triggers>
            <DataTrigger Binding="{Binding ElementName=textBoxName, Path=IsVisible}" Value="True">
                <Setter Property="FocusManager.FocusedElement" Value="{Binding ElementName=textBoxName}"/>
            </DataTrigger>
        </Style.Triggers>
    </Style>

在我的网格定义中:

<Grid Style="{StaticResource FocusTextBox}" />

6
这对我也起作用了,其他的则没有。感谢链接,非常有趣。同样有趣的是,这么简单的事情竟然可以如此复杂。 - TravisWhidden
2
以上答案无论容器是Grid还是StackPanel都可以正常工作。由于您的网格结构不清楚,很难判断出可能出了什么问题。不过看到有替代方案也是不错的。 - usefulBee
1
对我来说,这也是唯一能够正确工作的方式。不错。 - OregonGhost

12

如果您在其他答案中没有找到解决方案,那么这就是我解决问题的方法。

Application.Current.Dispatcher.BeginInvoke(new Action(() =>
{
    TEXTBOX_OBJECT.Focus();
}), System.Windows.Threading.DispatcherPriority.Render);

据我所知,其他解决方案可能无法使用,因为在应用程序渲染其他组件之前调用了 Focus()


3
这个回答应该有更好的排名。 - Simon Mourier

1
在代码后台,您只能通过执行以下操作来实现它。
 private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            txtIndex.Focusable = true;
            txtIndex.Focus();
        }

注意:在窗口加载之前它是无法运行的。

0
另一个可能的解决方案是使用DevExpress免费MVVM框架提供的FocusBehavior
<TextBox Text="This control is focused on startup">
    <dxmvvm:Interaction.Behaviors>
        <dxmvvm:FocusBehavior/>
    </dxmvvm:Interaction.Behaviors>
</TextBox>

它允许您在控件加载时、引发某个事件或更改属性时集中控制。


0
如果你正在寻找一个WPF/Xaml的解决方案,只需将焦点添加到对象并在上面添加FocusManager的代码。我不知道为什么原始代码不起作用的答案。
例如: FocusManager.FocusedElement="{Binding ElementName=StudentNameText}" Width="800" Orientation="Horizontal" /> Focusable="True" Text="{Binding StudentName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Height="33" VerticalAlignment="Top" Width="200">

你的回答并没有提供比之前的回答更多的信息,我认为你应该阅读帮助中心以获取答案,特别是如何回答问题?为什么你的回答可能会被删除?然后,要么编辑你的回答以添加之前回答中没有提供的信息,要么干脆删除你的回答。 - undefined
这完全不是真的。focusbehavior只在下面进行了处理,而且复制和粘贴是无效的。我的解决方案表明,在声明stackpanel时可以内联设置focusbehavior,然后在文本框本身中设置focusable。这比那个引发错误的Interaction.behaviors更加简洁。此外,这是唯一一个示例,展示了如何在XAML中设置focusable,而不是在代码后台中设置。此外,这段代码可以直接复制和粘贴,无需任何编辑。其他代码都无法做到这一点。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接