I've three Classes in my project Master
, Person
and Command
. Master
has two properties, a constructor and overridden the ToString
:
class Master {
public string FirstName { get; set; }
public string LastName { get; set; }
public Master(string FirstName, string LastName) {
this.FirstName = FirstName;
this.LastName = LastName;
}
public override string ToString() {
return FirstName + " " + LastName;
}
}
Command
is an implementation of ICommand
class Command : ICommand {
Func<object, bool> CanDo { get; set; }
Action<object> Do { get; set; }
public event EventHandler CanExecuteChanged;
public Command(Func<object, bool> CanDo, Action<object> Do) {
this.CanDo = CanDo;
this.Do = Do;
CommandManager.RequerySuggested += (o, e) => Evaluate();
}
public bool CanExecute(object parameter) => CanDo(parameter);
public void Execute(object parameter) => Do(parameter);
public void Evaluate() => CanExecuteChanged?.Invoke(null, EventArgs.Empty);
}
and Person
has two properties, implemented INotifyPropertyChanged
, is an ObservableCollection<Master>
and using Command
:
class Person : ObservableCollection<Master>, INotifyPropertyChanged {
string firstName, lastName;
public string FirstName {
get => firstName;
set { firstName = value; OnPropertyChanged(); }
}
public string LastName {
get => lastName;
set { lastName = value; OnPropertyChanged(); }
}
public Command AddToList { get; set; }
public new event PropertyChangedEventHandler PropertyChanged;
public Person() {
AddToList = new Command(CanDo, Do);
}
void OnPropertyChanged([CallerMemberName] string name = "") => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
bool CanDo(object para) => !string.IsNullOrEmpty(firstName) && !string.IsNullOrEmpty(lastName);
void Do(object para) {
Add(new Master(firstName, firstName));
FirstName = LastName = null;
}
}
On xaml I've these:
<Window ...>
<Window.Resources>
<local:Person x:Key="Person"/>
</Window.Resources>
<Grid DataContext="{StaticResource Person}">
<StackPanel>
<TextBox Text="{Binding FirstName}"/>
<TextBox Text="{Binding LastName}"/>
<Button Content="Click" Command="{Binding AddToList}"/>
<ListView ItemsSource="{Binding}"/>
</StackPanel>
</Grid>
</Window>
I've to click on the first TextBox
, bound to FirstName
, after launching the app to type something there, by pressing Tab I can type in the second TextBox
and if I then hit Tab again, it instead of focusing the Button
goes back to first TextBox
so I've to hit Tab twice to get to the Button
and by hitting Enter or Space I can add the item in the ListView
.
At this point I'm not sure what's focused, I've to hit Tab once more to get to the first TextBox
. After typing some more text in first as well as second TextBoxes
if I hit Tab, it instead of focusing Button
or first TextBox
selects the ListView
so I've to hit Tab thrice to get to the Button
!
I want to give first TextBox
focus when the app launches and after hitting Tab on second TextBox
I want it to go to the Button
and exclude ListView
from focus. I've tried setting Focusable="False"
, KeyboardNavigation.IsTabStop="False"
, IsTabStop="False"
in ListView
but those don't work! I also have tried settingTabIndex
on TextBoxes
and Button
like this:
<TextBox Text="{Binding FirstName}" TabIndex="1"/>
<TextBox Text="{Binding LastName}" TabIndex="2"/>
<Button Content="Click" Command="{Binding AddToList}" TabIndex="3"/>
These don't work either!