在 WPF XAML 中将焦点设置在 TextBox 上

问题描述 投票:0回答:10

尽管这个论坛和其他论坛上有一些帖子,但我找不到告诉我如何将焦点设置在

TextBox
上的内容。

我有一个带有许多标签和文本框的

UserControl
。加载表单后,我希望特定的
TextBox
获得焦点。

我已经设置了

TabIndex
,但这似乎不起作用。

有什么建议吗?

wpf textbox focus
10个回答
189
投票

您可以使用

FocusManager.FocusedElement
附加属性来实现此目的。这是一段默认将焦点设置到 TxtB 的代码。

<StackPanel Orientation="Vertical" FocusManager.FocusedElement="{Binding ElementName=TxtB}">
    <TextBox x:Name="TxtA" Text="A" />
    <TextBox x:Name="TxtB" Text="B" />
</StackPanel>

如果您不想在 XAML 中执行此操作,也可以在代码隐藏中使用

TxtB.Focus()


27
投票

您可以直接在 TextBox 上应用此属性:

<TextBox Text="{Binding MyText}" FocusManager.FocusedElement="{Binding RelativeSource={RelativeSource Self}}"/>

8
投票

我是使用 WPF 的新手,在阅读上面的示例时,我有过类似的经历,尝试使用给出的 xaml 代码示例将焦点设置到文本框,即上面的所有示例都不起作用。

我发现我必须将 FocusManager.FocusElement 放置在页面元素中。我认为如果您使用 Window 作为父元素,这可能也会起作用。无论如何,这是对我有用的代码。

 <Page x:Class="NameOfYourClass"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
  xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
  mc:Ignorable="d"
  Title="Title" 
  Height="720"
  Width="915"
  Background="white"
  Loaded="pgLoaded"
  FocusManager.FocusedElement="{Binding ElementName=NameOfYourTextBox}">

  <!-- Create child elements here. -->

  </Page>

3
投票

我在 DataTemplate 内的网格内有一个文本框,我希望在它变得可见时具有键盘焦点。我还发现了

<DataTemplate x:Key="DistanceView" DataType="{x:Type vm:ROI}">
    <Grid FocusManager.FocusedElement="{Binding ElementName=tbDistance}">
        <TextBox x:Name="tbDistance" Grid.Column="1" Grid.Row="1" VerticalAlignment="Bottom"/>
    </Grid>
</DataTemplate>

对我不起作用。

但是当我在父 ContentControl 中调用 Focus() 时

private void ContentControl_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
    if ((sender as ContentControl).IsVisible)
    {
        (sender as ContentControl).Focus();
    }
}

它开始工作并且插入符号在文本框中可见。我认为必须为 FocusScope 提供焦点才能使 FocusManager.FocusedElement 属性产生任何效果。

杰瑞


1
投票

通过周围的实验,xaml 解决方案

FocusManager.FocusedElement="{Binding ElementName=yourElement}"

当您将其放置在窗口层次结构中的最高元素(通常是窗口,或放置其他所有内容的网格)中时,效果似乎最好


1
投票

用途:

local:FocusManager.FocusOnLoad="True"

    public class FocusManager
    {
        public static readonly DependencyProperty FocusOnLoad = DependencyProperty.RegisterAttached(
            "FocusOnLoad",
            typeof(bool),
            typeof(FocusManager),
            new UIPropertyMetadata(false, new PropertyChangedCallback(OnValueChanged))
            );

        private static void OnValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            if (!(sender is Control control))
                return;

            if ((bool) e.NewValue == false)
                return;

            control.Loaded += (s, e) => control.Focus();
        }

        public static bool GetFocusOnLoad(DependencyObject d) => (bool) d.GetValue(FocusOnLoad);

        public static void SetFocusOnLoad(DependencyObject d, bool value) => d.SetValue(FocusOnLoad, value);
    }

0
投票

FocusManager 不在智能感知中,这让我有点困惑。我刚刚输入了整个属性并且它起作用了。

FocusManager.FocusedElement="{Binding ElementName=MyTextBox}"


Microsoft Visual Studio Enterprise 2015 版本 14.0.23107.0/C#/WPF


0
投票

为了完整起见,还有一种方法可以从代码隐藏中处理此问题(例如,无论出于何种原因,动态创建的控件并且在 XAML 中不存在)。将处理程序附加到窗口的 Loaded 事件,然后使用所需控件的“.Focus()”方法。下面是简单的示例。

public class MyWindow
{
    private VisualCollection controls;
    private TextBox textBox;

    // constructor
    public MyWindow()
    {
        controls = new VisualCollection(this);
        textBox = new TextBox();
        controls.Add(textBox);

        Loaded += window_Loaded;
    }

    private void window_Loaded(object sender, RoutedEventArgs e)
    {
        textBox.Focus();
    }
}

-1
投票

将您想要将焦点指向的元素绑定为

FocusManager.FocusedElement= "{Binding ElementName= Comobox1}"

在网格或组框中等


-1
投票

继我在 2022 年 2 月 4 日的评论之后,我用这种方式解决了这个问题:

在 XAML 的 UserControl 定义中添加 Loaded 事件处理程序。 (在 Loaded= 之后按 Tab 键会自动将事件处理程序添加到后面的代码中)

然后在后面的代码中编辑事件处理程序:

private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
    expressionTextBox.Focus();
}

我希望 WPF 足够聪明,能够在某个时刻处理事件的脱钩,从而允许类被垃圾收集并且不会引起内存泄漏,但我不知道。我对任何对此的评论感兴趣。

© www.soinside.com 2019 - 2024. All rights reserved.