Imposta lo stato attivo su una casella di testo in xaml wpf


91

Nonostante alcuni post su questo forum e altri non riesco a trovare qualcosa che mi dica come concentrare l'attenzione su un file TextBox.

Ho un userControl con molte etichette e caselle di testo. Quando il modulo viene caricato, voglio che un particolare textBox abbia il focus.

Ho impostato tabIndex ma non sembra funzionare.

Eventuali suggerimenti?


Possibile duplicato di WPF e focus iniziale
Ruben Bartelink

Risposte:


177

È possibile utilizzare la FocusManager.FocusedElementproprietà allegata per questo scopo. Ecco un pezzo di codice che imposta lo stato attivo su TxtB per impostazione predefinita.

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

Puoi anche usare TxtB.Focus()nel code-behind se non vuoi farlo in XAML.


13
@TarkaDaal: il commento "non ha funzionato per me" potrebbe essere un po 'più elaborato. Probabilmente è un altro controllo che ruba il focus. Quando la guerra focale inizia in WPF, le cose tendono a diventare cattive! Verifica i tuoi controlli e dove ti trovi attualmente nella struttura ad albero visuale (ad esempio, all'interno di un modello ComboBox, ciò non avrà alcun effetto e ci sono numerosi altri casi come questo). Se non riesci a trovare lo stealer, usa un comportamento o un code-behind per impostare lo stato attivo sul controllo quando viene caricato.
Julien Lebosquain

@JulienLebosquain: era un controllo piuttosto semplice, due pulsanti e una casella di testo all'interno di una griglia (che è dove ho messo le FocusManagercose). Alla fine, l'ho fatto nel code-behind.
TarkaDaal

Il membro "FocusedElement" non è riconosciuto o non è accessibile. :( plus.google.com/photos/+HendyIrawan/albums/5990385944888867505/…
Hendy Irawan

@HendyIrawan Forse è un progetto Silverlight?
MojoFilter

@MojoFilter è un progetto WPF per Windows Phone 8
Hendy Irawan,

28

È possibile applicare questa proprietà direttamente sul TextBox:

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

16
Non ha funzionato per me, l'impostazione FocusManager.FocusedElement = "{Binding ElementName = TxtB}" sul contenitore ha funzionato
Concedi il

1
Funziona come un fascino e non richiede alcuna denominazione.
Simon Mattes

1
Non ha funzionato anche per me. Ci manca qualcosa?
BrunoLM

1
Non ha funzionato neanche per me. Suggerimento del lavoro di Julien Lebosquain.
Cripta32

1
Non funziona neanche per me. Anche tutti gli altri metodi proposti non funzionano. Questo problema deve essere elementare e dovrebbe essere risolvibile facilmente. Ecco perché a molte persone non piace wpf.
IgorStack

6

Sono nuovo nell'uso di WPF e leggendo gli esempi sopra ho avuto un'esperienza simile provando a mettere a fuoco una casella di testo usando gli esempi di codice xaml forniti, cioè tutti gli esempi sopra non hanno funzionato.

Quello che ho trovato è stato che dovevo posizionare FocusManager.FocusElement nell'elemento della pagina. Presumo che questo probabilmente funzionerebbe anche se usassi una finestra come elemento genitore. Comunque, ecco il codice che ha funzionato per 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>

0

associare l'elemento in cui si desidera puntare il fuoco come

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

in griglia o groupbox ecc


4
Uhh sì, grazie per aver dato la stessa risposta che hanno fatto tutti gli altri ... 4 anni dopo ...
Adam Plocher

4
@AdamPlocher Bello, hai messo Sulfian fuori Stack Overflow in modo permanente. Un messaggio "Benvenuto in Stack overflow" sarebbe stato più appropriato.
Contango

2
@Contango: "Last seen Nov 11 '14". Se n'era andato da tempo prima che Adam pubblicasse il suo commento :)
Gone Coding

0

FocusManager non era in intellisense e questo mi ha un po 'confuso. Ho appena digitato l'intero attributo e ha funzionato.

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


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


0

Per completezza, c'è anche un modo per gestirlo dal codice sottostante (ad esempio nel caso di controlli che, per qualsiasi motivo, vengono creati dinamicamente e non esistono in XAML). Collegare un gestore all'evento Loaded della finestra e quindi utilizzare il metodo ".Focus ()" del controllo desiderato. Esempio di ossa nude di seguito.

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

0

Dalla sperimentazione in giro, la soluzione xaml

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

sembra funzionare meglio quando lo metti nell'elemento più alto nella gerarchia della finestra (di solito Finestra, o la Griglia in cui metti tutto il resto)


0

Utilizzo: 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);
    }

0

Ho un TextBox all'interno di una griglia all'interno di un DataTemplate che voglio avere il focus della tastiera quando diventa visibile. L'ho trovato anche io

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

Non ha funzionato per me.

Tuttavia, quando chiamo Focus () nel ContentControl genitore

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

inizia a funzionare e il cursore è visibile nel TextBox. Penso che il FocusScope debba essere messo a fuoco affinché la proprietà FocusManager.FocusedElement abbia un effetto.

Jerry

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.