如何设置制表符顺序? [英] How to set tab order?

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

问题描述

我的项目 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< Master> 并使用 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>

在启动应用程序以在其中键入某些内容后,通过按 Tab ,我必须单击绑定到 FirstName 的第一个 TextBox 我可以键入第二个 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 焦点,然后在第二个 TextBox 上点击 Tab 后,我希望它转到按钮,并从焦点中排除 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/zh-cn/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天全站免登陆