Establecer el foco en un cuadro de texto en xaml wpf

91

A pesar de algunas publicaciones en este foro y otras, no puedo encontrar algo que me diga cómo establecer el enfoque en un TextBox.

Tengo un userControl con muchas etiquetas y textBoxes. Cuando se carga el formulario, quiero que un cuadro de texto en particular tenga el foco.

He configurado el tabIndex pero eso no parece funcionar.

¿Alguna sugerencia?

user9969
fuente
Posible duplicado de WPF y enfoque inicial
Ruben Bartelink

Respuestas:

177

Puede utilizar la FocusManager.FocusedElementpropiedad adjunta para este propósito. Aquí hay un fragmento de código que establece el enfoque en TxtB de forma predeterminada.

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

También puede usarlo TxtB.Focus()en su código subyacente si no desea hacer esto en XAML.

Julien Lebosquain
fuente
13
@TarkaDaal: el comentario "no funcionó para mí" podría ser un poco más elaborado. Probablemente sea otro control que roba el foco. Cuando comienza la guerra de enfoque en WPF, ¡las cosas tienden a ponerse feas! Verifique sus controles y dónde se encuentra actualmente en el árbol visual (por ejemplo, dentro de una plantilla ComboBox, esto no tendrá ningún efecto, y hay muchos otros casos como este). Si no puede encontrar al ladrón, use un comportamiento o código subyacente para establecer el foco en el control cuando esté cargado.
Julien Lebosquain
@JulienLebosquain: Era un control bastante simple, dos botones y un TextBox dentro de una Grid (que es donde puse las FocusManagercosas). Al final, lo hice en el código subyacente.
TarkaDaal
El miembro "FocusedElement" no se reconoce o no es accesible. :( plus.google.com/photos/+HendyIrawan/albums/5990385944888867505/…
Hendy Irawan
@HendyIrawan ¿Es un proyecto de Silverlight, tal vez?
MojoFilter
@MojoFilter es un proyecto WPF de Windows Phone 8
Hendy Irawan
28

Puede aplicar esta propiedad directamente en el TextBox:

<TextBox Text="{Binding MyText}" FocusManager.FocusedElement="{Binding RelativeSource={RelativeSource Self}}"/>
Max
fuente
16
No funcionó para mí, la configuración de FocusManager.FocusedElement = "{Binding ElementName = TxtB}" en el contenedor sí funcionó
Grant
1
Funciona a las mil maravillas y no requiere ningún nombre.
Simon Mattes
1
No funcionó para mí también. ¿Nos estamos perdiendo algo?
BrunoLM
1
Tampoco funcionó para mí. Sugerencia de trabajo de Julien Lebosquain.
Crypt32
1
Tampoco funciona para mí. Todos los demás métodos propuestos tampoco funcionan. Este problema debe ser elemental y debe poder resolverse fácilmente. Es por eso que a muchas personas no les gusta wpf.
IgorStack
6

Soy nuevo en el uso de WPF y leyendo los ejemplos anteriores. Tuve una experiencia similar al intentar establecer el foco en un cuadro de texto usando los ejemplos de código xaml dados, es decir, todos los ejemplos anteriores no funcionaron.

Lo que encontré fue que tuve que colocar FocusManager.FocusElement en el elemento de la página. Supongo que esto probablemente también funcionaría si usara una ventana como elemento principal. De todos modos, aquí está el código que funcionó para mí.

 <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>
Joseph Mawer
fuente
0

enlazar el elemento al que desea apuntar el enfoque como

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

en cuadrícula o cuadro de grupo, etc.

Sufian Bashir
fuente
4
Uhh, sí, gracias por dar la misma respuesta que todos los demás ... 4 años después ...
Adam Plocher
4
@AdamPlocher Bien, pusiste a Sulfian fuera de Stack Overflow permanentemente. Un mensaje de "Bienvenido al desbordamiento de pila" habría sido más apropiado.
Contango
2
@Contango: "Visto por última vez Nov 11 '14". Se había ido mucho antes de que Adam publicara su comentario :)
Gone Coding
0

FocusManager no estaba en intellisense y esto me confundió un poco. Escribí todo el atributo y funcionó.

FocusManager.FocusedElement = "{Nombre de elemento de enlace = MyTextBox}"


Microsoft Visual Studio Enterprise 2015 versión 14.0.23107.0/C#/WPF

icernos
fuente
0

Para completar, también hay una forma de manejar esto desde el código subyacente (por ejemplo, en el caso de controles que, por cualquier razón, se crean dinámicamente y no existen en XAML). Adjunte un controlador al evento Loaded de la ventana y luego use el método ".Focus ()" del control que desee. Ejemplo básico a continuación.

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();
    }
}
Robert N
fuente
0

De experimentar, la solución xaml

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

parece funcionar mejor cuando lo coloca en el elemento más alto en la jerarquía de la ventana (generalmente Ventana, o la cuadrícula en la que coloca todo lo demás)

Tan Jing Yuan
fuente
0

Uso: 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);
    }
SERKAN
fuente
0

Tengo un TextBox dentro de una Grid dentro de un DataTemplate que quiero que tenga el foco del teclado cuando se vuelva visible. Tambien encontre que

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

no funcionó para mí.

Sin embargo, cuando llamo a Focus () en el ContentControl principal

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

comienza a funcionar y el símbolo de intercalación es visible en el TextBox. Creo que el FocusScope debe recibir el enfoque para que la propiedad FocusManager.FocusedElement tenga algún efecto.

alemán

alemán
fuente