如何相对于所选按钮向上、向下、向左和向右更改按钮的焦点?
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 理解哪个按钮是 up 或 down 或 left 和 right 相对于 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.Up
或 Keys.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;
}
}
我是编程新手。
不知道怎么解释好!!
如何让我的 WinForms 应用程序理解按钮位置, 例如,假设放置了一些按钮,其中一个是 select
按钮1-按钮2-按钮3
按钮4-(按钮5)-按钮6
按钮 7 -按钮 8- 按钮 9
我怎样才能按下键盘并跳转到 (button8) 而不是 (button6),或者按下向上键并从 (button2) 跳转。 我如何让 visual studio 理解哪个按钮是 up 或 down 或 left 和 right 相对于 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.Up
或Keys.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
更新后,无论处于活动状态还是非活动状态,都可以使用数字键盘。
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;
}
}