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
Hallo jessimaus,
hast Du INotifyPropertyChanged in deinem Model mit dem Property TbxIsFocused implementiert?
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);
}
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
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.
Hallo Sir Rufo,
dass leuchtet mir ein. Vielen Dank für deine Erläuterung.
Gruß
jessimaus