Définir le focus sur une zone de texte dans xaml wpf

91

Malgré certains messages sur ce forum et d'autres, je ne trouve pas quelque chose qui me dise comment mettre l'accent sur un TextBox.

J'ai un userControl avec de nombreuses étiquettes et textBoxes. Lorsque le formulaire est chargé, je veux qu'une zone de texte particulière ait le focus.

J'ai défini le tabIndex mais cela ne semble pas fonctionner.

Aucune suggestion?

user9969
la source
Copie possible de WPF et mise au point initiale
Ruben Bartelink

Réponses:

177

Vous pouvez utiliser la FocusManager.FocusedElementpropriété ci-jointe à cette fin. Voici un morceau de code qui définit le focus sur TxtB par défaut.

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

Vous pouvez également utiliser TxtB.Focus()dans votre code-behind si vous ne souhaitez pas le faire en XAML.

Julien Lebosquain
la source
13
@TarkaDaal: le commentaire "ça n'a pas marché pour moi" pourrait être un peu plus élaboré. C'est probablement un autre contrôle qui vole l'attention. Lorsque la guerre de concentration commence dans WPF, les choses ont tendance à devenir vilaines! Veuillez vérifier vos contrôles et où vous vous trouvez actuellement dans l'arborescence visuelle (par exemple, dans un modèle ComboBox, cela n'aura aucun effet, et il existe de nombreux autres cas comme celui-ci). Si vous ne trouvez pas le voleur, utilisez un comportement ou un code-behind pour définir le focus sur le contrôle lorsqu'il est chargé.
Julien Lebosquain
@JulienLebosquain: C'était un contrôle assez simple, deux boutons et une zone de texte dans une grille (c'est là que j'ai mis le FocusManagertruc). En fin de compte, je l'ai fait dans le code-behind.
TarkaDaal
Le membre "FocusedElement" n'est pas reconnu ou n'est pas accessible. :( plus.google.com/photos/+HendyIrawan/albums/5990385944888867505/…
Hendy Irawan
@HendyIrawan C'est peut-être un projet Silverlight?
MojoFilter
@MojoFilter c'est un projet WPF Windows Phone 8
Hendy Irawan
28

Vous pouvez appliquer cette propriété directement sur la zone de texte:

<TextBox Text="{Binding MyText}" FocusManager.FocusedElement="{Binding RelativeSource={RelativeSource Self}}"/>
Max
la source
16
Cela n'a pas fonctionné pour moi, la configuration de FocusManager.FocusedElement = "{Binding ElementName = TxtB}" sur le conteneur a fonctionné
Accorder
1
Fonctionne comme un charme et ne nécessite aucun nom.
Simon Mattes
1
Cela n'a pas fonctionné pour moi aussi. Sommes-nous en train de manquer quelque chose?
BrunoLM
1
Cela n'a pas fonctionné pour moi non plus. Suggestion de l'oeuvre de Julien Lebosquain.
Crypt32
1
Cela ne fonctionne pas non plus pour moi. Toutes les autres méthodes proposées ne fonctionnent pas non plus. Ce problème doit être élémentaire et doit être résolu facilement. C'est pourquoi beaucoup de personnes n'aiment pas wpf.
IgorStack
6

Je suis nouveau dans l'utilisation de WPF et en lisant les exemples ci-dessus, j'ai eu une expérience similaire en essayant de définir le focus sur une zone de texte en utilisant les exemples de code xaml donnés, c'est-à-dire que tous les exemples ci-dessus n'ont pas fonctionné.

Ce que j'ai trouvé, c'est que je devais placer le FocusManager.FocusElement dans l'élément de page. Je suppose que cela fonctionnerait probablement aussi bien si vous utilisiez une fenêtre comme élément parent. Bref, voici le code qui a fonctionné pour moi.

 <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
la source
0

liez l'élément sur lequel vous souhaitez mettre le focus en tant que

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

dans la grille ou la groupbox etc.

Soufian Bashir
la source
4
Euh ouais, merci d'avoir donné la même réponse que tout le monde a fait ... 4 ans plus tard ...
Adam Plocher
4
@AdamPlocher Bien joué, vous mettez définitivement Sulfian hors de Stack Overflow. Un message "Welcome to Stack overflow" aurait été plus approprié.
Contango
2
@Contango: "Dernière vue Nov 11 '14". Il a été depuis longtemps avant Adam a posté son commentaire :)
Autant en emporte Coding
0

FocusManager n'était pas dans l'intellisense et cela m'a un peu dérouté. J'ai juste tapé l'attribut entier et cela a fonctionné.

FocusManager.FocusedElement = "{Nom de l'élément de liaison = MyTextBox}"


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

Icernos
la source
0

Pour être complet, il existe également un moyen de gérer cela à partir du code derrière (par exemple dans le cas de contrôles qui, pour une raison quelconque, sont créés dynamiquement et n'existent pas en XAML). Attachez un gestionnaire à l'événement Loaded de la fenêtre, puis utilisez la méthode ".Focus ()" du contrôle souhaité. Exemple de bare-bones ci-dessous.

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
la source
0

De l'expérimentation autour, la solution xaml

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

semble fonctionner mieux lorsque vous le placez dans l'élément le plus élevé de la hiérarchie de la fenêtre (généralement Window, ou la grille dans laquelle vous placez tout le reste)

Tan Jing Yuan
la source
0

Usage: 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
la source
0

J'ai une zone de texte dans une grille à l'intérieur d'un DataTemplate que je veux avoir le focus clavier quand il devient visible. J'ai aussi trouvé 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>

N'a pas travaillé pour moi.

Cependant, lorsque j'appelle Focus () dans le ContentControl parent

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

il commence à fonctionner et le curseur est visible dans la zone de texte. Je pense que le FocusScope doit avoir le focus pour que la propriété FocusManager.FocusedElement ait un effet.

Jerry

Jerry
la source