C# WPF 如果当前已删除,则聚焦上一个文本框

标签 c# wpf focus

我有一个项目,如果当前字段为空但用户继续删除,我需要关注前一个字段。就像你在某处键入 CD-Key 一样。你有几个 block ,每个 block 有 4-5 个符号。例如,如果您删除第三个文本框,您将在第三个文本框变空后立即被迫返回第二个文本框。

if (textBox2.Text.Length == 0)
{
     Keyboard.Focus(textBox1);
}

这段代码工作正常,但考虑到我有另一个 onfocus 事件,所以 textBox2 在获得焦点后立即变为空,并且由于上面的代码焦点强制返回 textBox1。所以它是循环的。

如果我做对了,我需要捕获按下 Delete 按钮的时间,对吗?但这是我的问题。我不知道如何插入这段代码

private void Window_KeyDown(object sender, KeyEventArgs e)
{
    if (e.Key == Key.Delete)
    {
        if (textBox2.Text.Length == 0)
        {
             Keyboard.Focus(textBox1);
        }
    }
}

在这个函数中:

private void textBox2_TextChanged(object sender, TextChangedEventArgs e)
{
     if (textBox2.Text.Length == 2)
     {
          Keyboard.Focus(textBox3);
     }
     // HERE I NEED SOMETHING LIKE ELSE IF (e.Key == Key.Delete) {...
}

请帮帮我。 更新。我已经尝试了另一种解决方案,但它不起作用:

private void textBox2_KeyDown(object sender, KeyEventArgs e)
{
     if (e.Key == Key.Delete)
     {
          if (textBox2.Text.Length == 0)
          {
               Keyboard.Focus(textBox1);
          }
     }
}

最佳答案

这是任意数量的 TextBox 的通用解决方案。

TextBox的列表初始化:

private readonly List<TextBox> _textBoxes;

public MainWindow()
{
    InitializeComponent();

    _textBoxes = new List<TextBox> { _textBox1, _textBox2, _textBox3 };
}

有KeyUp事件的版本:

private void TextBox_KeyUp(object sender, KeyEventArgs e)
{
    if (e.Key == Key.Tab)
        return;

    var current = (TextBox)sender;
    if (current.Text.Any())
        return;

    var index = _textBoxes.IndexOf(current);
    if (index == 0)
        return;

    var previous = _textBoxes[index - 1];
    previous.Focus();
    previous.CaretIndex = previous.Text.Length;
}

以上版本不允许在按住场景下跳转文本框。要解决此问题,请使用 TextChanged 事件:

private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
    var current = (TextBox)sender;
    if (current.Text.Any())
        return;

    var index = _textBoxes.IndexOf(current);
    if (index == 0)
        return;

    var previous = _textBoxes[index - 1];
    previous.Focus();
    previous.CaretIndex = previous.Text.Length;
}

PreviewKeyDown 仅支持 Key.Delete 的第三种解决方案:

private void TextBox_PreviewKeyDown(object sender, KeyEventArgs e)
{
    if (e.Key != Key.Delete)
        return;

    var current = (TextBox)sender;
    if (current.Text.Length != 0)
        return;

    var index = _textBoxes.IndexOf(current);
    if (index == 0)
        return;

    var previous = _textBoxes[index - 1];
    previous.Focus();
    previous.CaretIndex = 0;
}

第四种解决方案也带有支持 Key.Delete 和 Key.Back 的 PreviewKeyDown:

private void TextBox_PreviewKeyDown(object sender, KeyEventArgs e)
{
    if (e.Key != Key.Delete && e.Key != Key.Back)
        return;

    var current = (TextBox)sender;
    if (current.Text.Length != 0)
        return;

    var index = _textBoxes.IndexOf(current);
    if (index == 0)
        return;

    var previous = _textBoxes[index - 1];
    previous.Focus();

    if (e.Key == Key.Delete)
        previous.CaretIndex = 0;
}

关于C# WPF 如果当前已删除,则聚焦上一个文本框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18035928/

相关文章:

java - Key Listener 继续关注 Java 游戏

java - 为什么focusLost之后会触发其他focusLost?

c# - 根据其他列表的结果计算的 TimeSpan 列表

c# - WPF (Avalonia) 可重用上下文菜单样式

java - 在 JOptionPane.showOptionDialog() 中设置组件焦点

WPF:为什么所有人都喜欢Grid控件?

c# - 动态绑定(bind)——根据列解析属性名

c# - 将数学公式应用到新列表时如何保持精度?

带有附件的 C# MailMessage 破坏了主题编码

c# - 是否可以像在 C++ 中一样在 C# 中创建 "private"或 "public" block ?