如何设置制表符顺序?

时间:2019-10-13 20:42:07

标签: wpf .net-core

我在项目MasterPersonCommand中有三个班级。 Master有两个属性,一个构造函数,并覆盖了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<Master>和使用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上,我有这些:

<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>

启动应用程序以在其中键入内容后,我必须单击绑定到TextBox的第一个FirstName,通过按 Tab 可以输入第二个TextBox,如果我再按一次 Tab ,它不是聚焦Button而是回到第一个TextBox,所以我必须按 Tab < / kbd>两次进入Button,然后按 Enter Space ,可以将项目添加到ListView中。

在这一点上,我不确定重点是什么,我必须再按一次 Tab 才能到达第一个TextBox。如果我按了 Tab ,则在第一个和第二个TextBoxes中键入了更多文本后,它不再聚焦Button或第一个TextBox选择了{{1} },所以我必须三次按 Tab 才能进入ListView

我想在应用启动时首先关注Button,然后在第二TextBox上点击 Tab 后,我希望它转到TextBox并排除Button来自焦点。我尝试在ListView中设置Focusable="False"KeyboardNavigation.IsTabStop="False"IsTabStop="False",但是这些无效!我还尝试过在ListViewTabIndex上设置TextBoxes,如下所示:

Button

这些也不起作用!

2 个答案:

答案 0 :(得分:1)

您遇到的问题是,在远离第二个文本框的位置,它需要确定将焦点放置在何处。但是,在该时间点,该命令仍被禁用,因为由于文本框中的值尚未到达视图模型中而无法执行,因此该命令无法执行。该值在焦点移动后到达。

解决此问题的一种方法是更改​​第二个文本框的绑定,以便在每次更改值时更新ViewModel。将以下子句添加到该绑定:

tiempo =...

此处有更多详细信息... https://docs.microsoft.com/en-us/dotnet/framework/wpf/data/how-to-control-when-the-textbox-text-updates-the-source

现在,每当您键入一个字符时,该命令就会重新考虑是否可以执行该命令。

答案 1 :(得分:1)

简短答案:

在绑定上设置UpdateSourceTrigger=PropertyChanged

<TextBox Text="{Binding FirstName, UpdateSourceTrigger=PropertyChanged}"/>
<TextBox Text="{Binding LastName, UpdateSourceTrigger=PropertyChanged}"/>

我怀疑正在发生的事情是WPF在评估CanExecute命令之前正在评估下一个选项卡的位置,因此,在确定要跳转至下一个选项卡的位置时,该按钮仍处于禁用状态,因此唯一要做的就是回到第一个文本框。

UpdateSourceTrigger告诉WPF评估每次按键时的绑定,而不是焦点改变时的绑定,这意味着在按钮需要工作时,按钮已正确启用。