简体   繁体   English

"将焦点设置在 xaml wpf 中的文本框上"

[英]Set the focus on a textbox in xaml wpf

Despite some posts on this forum and others i cannot find something that tells me how to set the focus on a TextBox<\/code> .尽管这个论坛和其他一些帖子我找不到告诉我如何将焦点设置在TextBox<\/code>上的东西。

I have a userControl with many labels and textBoxes.我有一个带有许多标签和文本框的用户控件。 When the form is loaded I want the a particular textBox to have the focus.加载表单时,我希望特定的文本框具有焦点。

I have set the tabIndex but that didn't seem to work.我已经设置了 tabIndex 但这似乎不起作用。

Any suggestions?有什么建议?

"

You can use the FocusManager.FocusedElement attached property for this purpose.为此,您可以使用FocusManager.FocusedElement附加属性。 Here's a piece of code that set the focus to TxtB by default.这是一段默认将焦点设置为 TxtB 的代码。

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

You can also use TxtB.Focus() in your code-behind if you don't want to do this in XAML.如果您不想在 XAML 中执行此操作,也可以在代码隐藏中使用TxtB.Focus()

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

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

I am new to using WPF and reading through the above examples I had a similar experience trying set the focus to a textbox using the xaml code examples given, ie all the examples above didn't work.我是使用 WPF 的新手并通读上述示例我有类似的经验尝试使用给定的 xaml 代码示例将焦点设置到文本框,即上面的所有示例都不起作用。

What I found was I had to place the FocusManager.FocusElement in the page element.我发现我必须将 FocusManager.FocusElement 放在页面元素中。 I assume this would probably work as well if you used a Window as the parent element.我认为如果您使用 Window 作为父元素,这可能也会起作用。 Anyway, here is the code that worked for me.无论如何,这是对我有用的代码。

 <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>

I have a TextBox inside a Grid inside a DataTemplate which I want to have keyboard focus when it becomes visible.我在 DataTemplate 的 Grid 中有一个 TextBox,当它变得可见时,我希望它具有键盘焦点。 I also found that我也发现

<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>

did not work for me.对我不起作用。

However when I call Focus() in the parent ContentControl但是,当我在父 ContentControl 中调用 Focus()

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

it starts to work and the caret is visible in the TextBox.它开始工作并且插入符号在 TextBox 中可见。 I think the FocusScope has to be given focus for the FocusManager.FocusedElement property to have any effect.我认为 FocusScope 必须获得焦点才能使 FocusManager.FocusedElement 属性产生任何效果。

Jerry杰瑞

bind the element you want to point the focus in as将要指向焦点的元素绑定为

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

in grid or groupbox etc在网格或分组框等

FocusManager was not in intellisense and this confused me a bit. FocusManager 不是智能感知,这让我有点困惑。 I just typed the entire attribute and it worked.我只是输入了整个属性并且它起作用了。

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


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

For completeness, there is also a way to handle this from code behind (eg in the case of controls that, for whatever reason, are created dynamically and don't exist in XAML).为了完整起见,还有一种方法可以从背后的代码中处理这个问题(例如,在控件的情况下,无论出于何种原因,都是动态创建的并且不存在于 XAML 中)。 Attach a handler to the window's Loaded event and then use the ".Focus()" method of the control you want.将处理程序附加到窗口的 Loaded 事件,然后使用所需控件的“.Focus()”方法。 Bare-bones example below.下面的简单示例。

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();
    }
}

From experimenting around, the xaml solution通过试验,xaml 解决方案

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

seems to work best when you place it in the highest element in the window hierarchy (usually Window, or the Grid you place everything else in)当您将其放置在窗口层次结构中的最高元素(通常是窗口或放置其他所有内容的网格)时,似乎效果最佳

Usage: local:FocusManager.FocusOnLoad="True"用法: 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);
    }

Further to my comment on Feb 04 '22, I solved it this way:继我在 22 年 2 月 4 日发表的评论之后,我以这种方式解决了它:

In the UserControl definitionin the XAML add a Loaded event handler.在 XAML 中的 UserControl 定义中,添加一个 Loaded 事件处理程序。 (pressing tab after Loaded= will automatically add an event handler to the code behind) (在 Loaded= 之后按 Tab 会自动将事件处理程序添加到后面的代码中)

Then edit the event handler in the code behind:然后在后面的代码中编辑事件处理程序:

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

I'm hoping that WPF is clever enough to handle th unhooking of the evnt at some point, allowing the class to be garbage collected and not give rise to memory leaks, but I don't know.我希望 WPF 足够聪明,可以在某些时候处理 unhook 事件,允许对类进行垃圾收集并且不会引起内存泄漏,但我不知道。 I'd be interested in any comments on that.我会对对此的任何评论感兴趣。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM