Ustaw fokus na polu tekstowym w XAML WPF

91

Pomimo niektórych postów na tym forum i innych nie mogę znaleźć czegoś, co mówi mi, jak ustawić fokus na TextBox.

Mam userControl z wieloma etykietami i textBoxami. Po załadowaniu formularza chcę, aby konkretny textBox miał fokus.

Ustawiłem tabIndex, ale to nie działa.

Jakieś sugestie?

user9969
źródło
Możliwy duplikat WPF i wstępny fokus
Ruben Bartelink

Odpowiedzi:

177

Możesz FocusManager.FocusedElementw tym celu wykorzystać załączoną nieruchomość. Oto fragment kodu, który domyślnie ustawia fokus na TxtB.

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

Możesz również użyć TxtB.Focus()w swoim kodzie, jeśli nie chcesz tego robić w języku XAML.

Julien Lebosquain
źródło
13
@TarkaDaal: komentarz „to nie zadziałało dla mnie” mógłby być trochę bardziej rozwinięty. To prawdopodobnie kolejna kontrola kradnąca skupienie. Kiedy w WPF zaczyna się wojna o fokus, sprawy idą niegrzecznie! Zweryfikuj kontrolki i miejsce, w którym aktualnie znajdujesz się w drzewie wizualnym (na przykład w szablonie ComboBox, nie będzie to miało żadnego efektu, a jest wiele innych podobnych przypadków). Jeśli nie możesz znaleźć złodzieja, użyj zachowania lub związanego z kodem, aby ustawić fokus na kontrolkę po jej załadowaniu.
Julien Lebosquain
@JulienLebosquain: To była całkiem prosta kontrolka, dwa przyciski i TextBox w siatce (tam właśnie umieściłem FocusManagerrzeczy). W końcu zrobiłem to w kodzie.
TarkaDaal
Element członkowski „FocusedElement” nie został rozpoznany lub nie jest dostępny. :( plus.google.com/photos/+HendyIrawan/albums/5990385944888867505/…
Hendy Irawan
@HendyIrawan Czy to może projekt Silverlight?
MojoFilter
@MojoFilter to projekt WPF na Windows Phone 8
Hendy Irawan
26

Możesz zastosować tę właściwość bezpośrednio w TextBox:

<TextBox Text="{Binding MyText}" FocusManager.FocusedElement="{Binding RelativeSource={RelativeSource Self}}"/>
Maks
źródło
17
Dla mnie nie zadziałało, ustawienie FocusManager.FocusedElement = "{Binding ElementName = TxtB}" w kontenerze zadziałało
Grant
1
Działa jak urok i nie wymaga żadnych nazw.
Simon Mattes
1
U mnie też nie działa. Czy czegoś brakuje?
BrunoLM,
1
Dla mnie też nie działało. Sugestia autorstwa Juliena Lebosquaina.
Crypt32
1
Na mnie też nie działa. Wszystkie inne proponowane metody również nie działają. Ten problem musi być elementarny i powinien być łatwy do rozwiązania. Dlatego wielu ppl nie lubi wpf.
IgorStack
6

Jestem nowy w używaniu WPF i czytając powyższe przykłady. Miałem podobne doświadczenie, próbując ustawić fokus na pole tekstowe przy użyciu podanych przykładów kodu XAML, tj. Wszystkie powyższe przykłady nie działały.

Okazało się, że muszę umieścić element FocusManager.FocusElement w elemencie strony. Zakładam, że to prawdopodobnie zadziałałoby, gdybyś użył Window jako elementu nadrzędnego. W każdym razie, oto kod, który działał dla mnie.

 <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
źródło
0

związać element, na który chcesz skierować fokus, jako

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

w siatce lub skrzynce grupowej itp

Sufian Bashir
źródło
4
O tak, dziękuję za udzielenie takiej samej odpowiedzi, jak wszyscy inni ... 4 lata później ...
Adam Plocher
4
@AdamPlocher Niezłe, na stałe wyłączasz Sulfian z przepełnienia stosu. Komunikat „Witamy w przepełnieniu stosu” byłby bardziej odpowiedni.
Contango,
2
@Contango: "Ostatnio widziano Nov 11 '14". Nie było go na długo, zanim Adam opublikował swój komentarz :)
Gone Coding
0

FocusManager nie był w trybie Intellisense i to mnie trochę zdezorientowało. Po prostu wpisałem cały atrybut i zadziałało.

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


Microsoft Visual Studio Enterprise 2015 w wersji 14.0.23107.0/C#/WPF

icernos
źródło
0

Aby zapewnić kompletność, istnieje również sposób obsługi tego z poziomu kodu (np. W przypadku kontrolek, które z dowolnego powodu są tworzone dynamicznie i nie istnieją w XAML). Dołącz procedurę obsługi do zdarzenia Loaded okna, a następnie użyj metody „.Focus ()” żądanej kontrolki. Przykład gołej kości poniżej.

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
źródło
0

Od eksperymentowania, rozwiązanie XAML

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

wydaje się działać najlepiej, gdy umieścisz go w najwyższym elemencie w hierarchii okien (zwykle Okno lub Siatka, w której umieszczasz wszystko inne)

Tan Jing Yuan
źródło
0

Stosowanie: 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
źródło
0

Mam TextBox wewnątrz siatki wewnątrz DataTemplate, na którym chcę mieć fokus klawiatury, gdy stanie się widoczny. Ja też to znalazłem

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

nie działa dla mnie.

Jednak gdy wywołuję Focus () w nadrzędnym ContentControl

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

zaczyna działać, a daszek jest widoczny w TextBox. Myślę, że FocusScope musi mieć fokus, aby właściwość FocusManager.FocusedElement miała jakikolwiek efekt.

Nocnik

Nocnik
źródło