Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
283 views
in Technique[技术] by (71.8m points)

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

I'm new in programming.

I don't know how to explain well!!.

How can i make my WinForms application understand the button location, for example imagine a number of buttons positioned and that one of them is select

button1- button2 -button3

button4-(button5)-button6

button7 -button8- button9

how can i press down on the keyboard and jump to (button8) and not to (button6), or press upkey and go from (button2). how can i make visual studio understand which button is up or down or left and right relative to the button that is selected?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can add your Buttons to a TableLayoutPanel, so each Button's position is determined by the TableLayoutPanel's (Column:Row) coordinates.

  • Create a TableLayoutPanel (in the below, named tlpButtons) with enough Rows and Columns to contain your Buttons. You can add/remove Rows and Column at run-time, if needed.
  • Select all your Buttons and subscribe to the PreviewKeyDown, using the PropertyGrid in the Form Designer, so that you have just one event handler for all your Buttons (in this code, the event handler is named buttons_PreviewKeyDown).
  • When the Key.Up or Keys.Down are pressed, the PreviewKeyDown handler of the Buttons is invoked. The sender argument references the control that triggered the event, so we cast sender to Control (since only a Control type reference is needed, we don't use any property specific to a derived type, like Button)
  • If we handle the Key pressed, we have to set IsInputKey, otherwise the event is passed on to the control and processed (causing the normal selection to trigger)
  • The TableLayoutPanel's GetPositionFromControl() returns the Row/Column position of this Control.
  • We just set the Row value ± 1, depending on what cursor Key has been pressed (while checking whether the new value is in the [0 : RowsCount] range).
    The GetControlFromPosition() method returns the reference of the control in the new position: we use this reference to set the current ActiveControl.

This is the result:

Button PreviewKeyDown


Note:
the buttons_PreviewKeyDown event handler is the same for all Buttons/Controls.
tlpButtons is the name of the TableLayoutPanel used as container for the Buttons/Controls

Updated to also work with a Numeric Pad when either active or inactive.

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...