如何设置标签顺序? [英] How to set tab order?

查看:22
本文介绍了如何设置标签顺序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的项目中有三个类MasterPersonCommand.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;
    }
}

CommandICommand

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 并按 EnterSpace 我可以在 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" 但那些不起作用!我也试过在 TextBoxesButton 上设置 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆