如何设置标签顺序? [英] How to set tab order?
问题描述
我的项目中有三个类Master
、Person
和Command
.Master
有两个属性,一个是构造函数,另一个是覆盖 ToString
:
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
是 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);
}
和Person
有两个属性,实现了INotifyPropertyChanged
,是一个ObservableCollection
并使用Command
:
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;
}
}
在 xaml 上我有这些:
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>
在启动应用程序后,我必须点击绑定到 FirstName
的第一个 TextBox
,然后按 Tab我可以输入第二个 TextBox
,然后如果我再次点击 Tab,它不是聚焦 Button
而是回到第一个 TextBox
所以我必须按 Tab 两次才能到达 Button
并按 Enter 或 Space 我可以在 ListView
中添加项目.
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
.
此时我不确定重点是什么,我必须再次点击 Tab 才能到达第一个 TextBox
.在第一个和第二个 TextBoxes
中输入更多文本后,如果我点击 Tab,它而不是聚焦 Button
或第一个 TextBox
选择 ListView
所以我必须按 Tab 三次才能到达 Button
!
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
!
我想在应用程序启动时和在第二个 TextBox
上点击 Tab 后给予第一个 TextBox
焦点我希望它转到 Button
并从焦点中排除 ListView
.我试过在 ListView 中设置
Focusable="False"
, KeyboardNavigation.IsTabStop="False"
, IsTabStop="False"
但那些不起作用!我也试过在 TextBoxes
和 Button
上设置 TabIndex
像这样:
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"/>
这些也不行!
推荐答案
您遇到的问题是,当您从第二个文本框移开时,它需要决定将焦点放在何处.但是,在那个时间点,该命令仍然处于禁用状态,因为它无法执行,因为文本框中的值尚未到达视图模型中.该值在焦点移动后到达.
The problem you're having is that at the point you tab away from the second text box it needs to decide where to place the focus. However, at that point in time, the command is still disabled because it cannot be executed because the value from the text box has not arrived in the view model yet. This value arrives after the focus has been moved.
解决此问题的一种方法是更改第二个文本框的绑定,以便每次更改值时都会更新 ViewModel.将以下子句添加到该绑定中:
One way to fix this would be to change the binding of the second textbox so that the ViewModel is updated on every change to the value. Add the following clause to that binding:
UpdateSourceTrigger=PropertyChanged
此处有更多详细信息... https://docs.microsoft.com/en-us/dotnet/framework/wpf/data/how-to-control-when-the-textbox-text-updates-来源
More details here... https://docs.microsoft.com/en-us/dotnet/framework/wpf/data/how-to-control-when-the-textbox-text-updates-the-source
现在每当你输入一个字符时,命令都会重新考虑它是否可以执行.
Now whenever you type a character the command will reconsider whether it can be executed.
这篇关于如何设置标签顺序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!