Defina o foco em uma caixa de texto em xaml wpf

91

Apesar de alguns posts neste fórum e outros, não consigo encontrar algo que me diga como definir o foco em a TextBox.

Eu tenho um userControl com muitos rótulos e textBoxes. Quando o formulário é carregado, quero que um determinado textBox tenha o foco.

Eu configurei o tabIndex, mas não parece funcionar.

Alguma sugestão?

usuário9969
fonte
Possível duplicata do WPF e foco inicial
Ruben Bartelink 01 de

Respostas:

177

Você pode usar a FocusManager.FocusedElementpropriedade anexada para essa finalidade. Aqui está um trecho de código que define o foco para TxtB por padrão.

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

Você também pode usar TxtB.Focus()em seu code-behind se não quiser fazer isso em XAML.

Julien Lebosquain
fonte
13
@TarkaDaal: o comentário "não funcionou para mim" poderia ser um pouco mais elaborado. Provavelmente é outro controle roubando o foco. Quando a guerra de foco começa no WPF, as coisas tendem a dar errado! Verifique seus controles e onde você está atualmente na árvore visual (por exemplo, dentro de um modelo ComboBox, isso não terá efeito, e há vários outros casos como este). Se você não conseguir encontrar o ladrão, use um comportamento ou code-behind para definir o foco para o controle quando ele for carregado.
Julien Lebosquain
@JulienLebosquain: Era um controle bem simples, dois botões e um TextBox dentro de uma Grid (que é onde coloquei as FocusManagercoisas). No final, eu fiz isso no code-behind.
TarkaDaal
O membro "FocusedElement" não é reconhecido ou não está acessível. :( plus.google.com/photos/+HendyIrawan/albums/5990385944888867505/…
Hendy Irawan
@HendyIrawan Esse é um projeto do Silverlight, talvez?
MojoFilter
@MojoFilter é um projeto WPF do Windows Phone 8
Hendy Irawan
28

Você pode aplicar esta propriedade diretamente no TextBox:

<TextBox Text="{Binding MyText}" FocusManager.FocusedElement="{Binding RelativeSource={RelativeSource Self}}"/>
Max
fonte
16
Não funcionou para mim, definir FocusManager.FocusedElement = "{Binding ElementName = TxtB}" no contêiner funcionou
Concessão de
1
Funciona perfeitamente e não requer nenhuma nomenclatura.
Simon Mattes,
1
Não funcionou para mim também. Estamos perdendo alguma coisa?
BrunoLM
1
Não funcionou para mim também. Sugestão de trabalho de Julien Lebosquain.
Crypt32 de
1
Não funciona para mim também. Todos os outros métodos propostos também não funcionam. Este problema deve ser elementar e deve ser resolvido facilmente .. É por isso que muitas pessoas não gostam de wpf.
IgorStack
6

Eu sou novo no uso do WPF e lendo os exemplos acima, tive uma experiência semelhante ao tentar definir o foco para uma caixa de texto usando os exemplos de código xaml fornecidos, ou seja, todos os exemplos acima não funcionaram.

O que descobri foi que precisava colocar o FocusManager.FocusElement no elemento da página. Suponho que isso provavelmente funcionaria bem se você usasse uma janela como o elemento pai. Enfim, aqui está o código que funcionou para mim.

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

vincule o elemento para o qual você deseja apontar o foco como

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

na grade ou caixa de grupo etc

Sufian Bashir
fonte
4
Uhh sim, obrigado por dar a mesma resposta que todo mundo deu ... 4 anos depois ...
Adam Plocher
4
@AdamPlocher Legal, você tirou o Sulfian do Stack Overflow permanentemente. Uma mensagem "Welcome to Stack overflow" teria sido mais apropriada.
Contango
2
@Contango: "Visto pela última vez Nov 11 '14". Ele já havia partido há muito tempo antes de Adam postar seu comentário :)
Gone Coding
0

FocusManager não estava em intellisense e isso me confundiu um pouco. Eu apenas digitei o atributo inteiro e funcionou.

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


Microsoft Visual Studio Enterprise 2015 versão 14.0.23107.0/C#/WPF

icernos
fonte
0

Para completar, também há uma maneira de lidar com isso por trás do código (por exemplo, no caso de controles que, por qualquer motivo, são criados dinamicamente e não existem no XAML). Anexe um manipulador ao evento Loaded da janela e, em seguida, use o método ".Focus ()" do controle desejado. Exemplo básico abaixo.

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

Por experimentar, a solução xaml

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

parece funcionar melhor quando você o coloca no elemento mais alto na hierarquia da janela (geralmente a janela ou a grade em que você coloca todo o resto)

Tan Jing Yuan
fonte
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
fonte
0

Eu tenho um TextBox dentro de uma grade dentro de um DataTemplate que quero ter o foco do teclado quando se tornar visível. Eu também descobri 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ão funcionou para mim.

No entanto, quando eu chamo Focus () no ContentControl pai

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

ele começa a funcionar e o acento circunflexo fica visível no TextBox. Acho que o FocusScope deve receber o foco para que a propriedade FocusManager.FocusedElement tenha algum efeito.

Jerry

Jerry
fonte