Laden...

Textbox auf nächstem TabItem fokussieren

Erstellt von Jessimaus vor 6 Jahren Letzter Beitrag vor 6 Jahren 1.601 Views
J
Jessimaus Themenstarter:in
6 Beiträge seit 2017
vor 6 Jahren
Textbox auf nächstem TabItem fokussieren

Hallo Leute,

ich habe ein TabControl mit zwei TabItems. Auf jedem dieser TabItems befinden sich diverse Text- bzw. ComboBoxen.
Bei Verlassen der letzten ComboBox des ersten TabItems möchte ich den Eingabefocus auf die erste Textbox des zweiten TabItems verschieben.

private void CbxServicetechniker_OnPreviewKeyDown(object sender, KeyEventArgs e){
	if(e.Key == Key.Enter){
		Tab_Index = 1;
		TbxIsFocused = true;
		e.Handled = true;
	}
}

Für das TabControl ist u.a. folgendes definiert:

<TabControl
	SelectedIndex="{Binding Tab_Index}"
	KeyboardNavigation.DirectionalNavigation="Continue">

Und für die Ziel-TextBox:

behaviors:BhvFocusExtension.IsFocused="{Binding TbxIsFocused, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"

Das zweite TabItem wird zwar aktiviert aber der Eingabefocus ist nicht vorhanden. Ich muss erst die Tab-Taste betätigen, um den Focus in die erste TextBox zu verschieben.
Hat jemand einen Tipp, was ich ändern bzw. hinzufügen muss, damit das ohne Tab-Taste funktioniert?

PS: Auch mit dem Holzhammer

TextBoxName.Focus();

funktioniert es nicht.

Danke und Gruß
jessimaus

849 Beiträge seit 2006
vor 6 Jahren

Hallo jessimaus,

hast Du INotifyPropertyChanged in deinem Model mit dem Property TbxIsFocused implementiert?

D
985 Beiträge seit 2014
vor 6 Jahren

Das Problem kann man sehr leicht nachsstellen mit


<Window x:Class="WpfApp17.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp17"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>

        <TabControl Name="TabControl">

            <TabItem Name="First_TabItem"  Header="First">
                <StackPanel>
                    <TextBox Name="First_TextBox"/>
                </StackPanel>
            </TabItem>

            <TabItem Name="Second_TabItem" Header="Second">
                <StackPanel>
                    <TextBox Name="Second_TextBox"/>
                </StackPanel>
            </TabItem>

        </TabControl>

        <Button Grid.Row="1" Content="Next" Click="Button_Click"/>
    </Grid>
</Window>

und im CodeBehind


public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        Second_TabItem.IsSelected = true;
        Second_TextBox.Focus();
    }
}

Der erste Klick auf den Button Next bewirkt das Second_TabItem sichtbar wird, allerdings nicht, dass der Fokus auch auf der Second_TextBox ist.

Ein weiterer Klick auf den Button Next setzt dann korrekt den Fokus auf die Second_TextBox.

Damit das mit einem Klick/Aufruf funktioniert benötigt man den Dispatcher


private async void Button_Click(object sender, RoutedEventArgs e)
{
    Second_TabItem.IsSelected = true;
    // Second_TextBox.Focus();

    await Dispatcher.InvokeAsync(
        () => Second_TextBox.Focus(),
        System.Windows.Threading.DispatcherPriority.ApplicationIdle);
}

J
Jessimaus Themenstarter:in
6 Beiträge seit 2017
vor 6 Jahren

Hi

@unconnected
Ja, hab ich. 😃 Benutze ich ja an diversen anderen Stellen in der Anwendung.

@Sir Rufo
Habe deine Lösung für mich angepasst und schon funktioniert es. 😉
Kannst Du in ein zwei Sätzen darlegen, warum das im TabControl nicht auf die 'herkömmliche Weise' funktioniert. Oder wo ich das nachlesen kann.

Vielen Dank an euch beide für die schnelle Hilfe.

Gruß
jessimaus

D
985 Beiträge seit 2014
vor 6 Jahren

Visuelle Änderungen werden verzögert ausgeführt. Das Window sammelt alle Änderungen und stellt diese dann in einem Rutsch dar.

Den Fokus kann man nur auf Elemente setzen, die auch sichtbar und aktiviert sind. Vor dem Tab-Wechsel ist die TextBox aber nicht sichtbar und kann auch den Fokus nicht erhalten.

Dieses sichtbar machen der TextBox erfolgt aber wie oben erwähnt verzögert.

Wenn die View dann alles abgearbeitet und dargestellt hat, dann kann man auch den Fokus auf die TextBox legen. Aus diesem Grund muss man beim Dispatcher-Aufruf auch noch DispatcherPriority.ApplicationIdle (bzw. alle Werte ≤ DispatcherPriority.Render funktionieren) mitgeben, sonst erfolgt der Aufruf zu früh.

J
Jessimaus Themenstarter:in
6 Beiträge seit 2017
vor 6 Jahren

Hallo Sir Rufo,

dass leuchtet mir ein. Vielen Dank für deine Erläuterung.

Gruß
jessimaus