如何相对于所选按钮向上、向下、向左和向右更改按钮的焦点?

How to change focus on buttons up, down, left and right relative to the button that is selected?

我是编程新手。

不知道怎么解释好!!

如何让我的 WinForms 应用程序理解按钮位置, 例如,假设放置了一些按钮,其中一个是 select

按钮1-按钮2-按钮3

按钮4-(按钮5)-按钮6

按钮 7 -按钮 8- 按钮 9

我怎样才能按下键盘并跳转到 (button8) 而不是 (button6),或者按下向上键并从 (button2) 跳转。 我如何让 visual studio 理解哪个按钮是 updownleftright 相对于 selected?

的按钮

我假设您是在谈论表单中的按钮。

把它们放在这样的列表中

List<Button> buttons = new List<Button>() {Button1, Button2...}

现在你知道你在哪个按钮上了,向上意味着你需要获取当前索引并从中减去 3* (Button6 -> Button3) 然后使用它作为列表的新索引。 对于向下添加 3* 和 left/right 是 minus/plus 1.

现在您只需定义边缘情况: 如果您在 Button9 上按下或向右按下会怎样?

*This value changes based on the amount of columns. 3 columns => +/-3; 4 col => +/-4

您可以将按钮添加到 TableLayoutPanel,因此每个按钮的位置都由 TableLayoutPanel 的 (Column:Row) 坐标决定。

  • 创建一个 TableLayoutPanel(在下面,命名为 tlpButtons),具有足够的行和列来包含您的按钮。如果需要,您可以在 运行 时 add/remove 行和列。
  • Select 所有按钮并订阅 PreviewKeyDown,使用表单设计器中的 PropertyGrid,这样您所有的按钮只有一个事件处理程序(在此代码中,事件处理程序名为 buttons_PreviewKeyDown).
  • 当按下 Key.UpKeys.Down 时,将调用按钮的 PreviewKeyDown 处理程序。 sender 参数引用触发事件的控件,因此我们将 sender 转换为 Control(因为只需要一个 Control 类型引用,我们不使用任何特定于派生的 属性输入,例如 Button)
  • 如果我们处理Key pressed,我们必须设置IsInputKey,否则事件传递给控件并处理(导致正常选择触发)
  • TableLayoutPanel 的 GetPositionFromControl() returns 此控件的 Row/Column 位置。
  • 我们只是设置行值± 1,这取决于按下了哪个光标键(同时检查新值是否在[0 : RowsCount]范围内)。
    GetControlFromPosition() method returns the reference of the control in the new position: we use this reference to set the current ActiveControl.

这是结果:


注:
buttons_PreviewKeyDown 事件处理程序对于所有 Buttons/Controls.
都是相同的 tlpButtons 是用作 Buttons/Controls

容器的 TableLayoutPanel 的名称

更新后,无论处于活动状态还是非活动状态,都可以使用数字键盘。

private void buttons_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
    var btn = sender as Control;
    var pos = tlpButtons.GetPositionFromControl(btn);
    bool moveFocus = false;

    switch (e.KeyCode) {
        case Keys.NumPad8:
        case Keys.Up:
            pos.Row = (pos.Row > 0) ? pos.Row - 1 : tlpButtons.RowCount - 1;
            moveFocus = true;
            break;
        case Keys.NumPad2:
        case Keys.Down:
            pos.Row = (pos.Row < (tlpButtons.RowCount - 1)) ? pos.Row + 1 : 0;
            moveFocus = true;
            break;
        case Keys.NumPad4:
            if (pos.Column > 0) {
                pos.Column -= 1;
            }
            else {
                pos.Column = tlpButtons.ColumnCount - 1;
                pos.Row = pos.Row > 0 ? pos.Row - 1 : tlpButtons.RowCount - 1;
            }
            moveFocus = true;
            break;
        case Keys.NumPad6:
            if (pos.Column < (tlpButtons.ColumnCount - 1)) {
                pos.Column += 1;
            }
            else {
                pos.Column = 0;
                pos.Row = (pos.Row < tlpButtons.RowCount - 1) ? pos.Row + 1 : 0;
            }
            moveFocus = true;
            break;
    }
    if (moveFocus) {
        e.IsInputKey = true;
        var ctrl = tlpButtons.GetControlFromPosition(pos.Column, pos.Row);
        if (ctrl != null) this.ActiveControl = ctrl;
    }
}