Simulating Enter Key Press sending from a Button on it's Click Event?

710 views Asked by At

Hello I have a problem and don't quite know how to fix it, I'm fairly new to C# programming and object oriented programming in general and only really have limited knowledge of procedural programming because I'm mainly a Dynamics NAV Developer which this solution should also be an AddIn for. So I have an Panel as a UserControl, this user Control is populated with some textboxes and buttons, the buttons are arranged to represent a Numpad and are also named like the corresponding Numpad Keys.
So now some words to my actual problem in the following Scenario: I'm entering a textbox typing something in with the Numpad Buttons or with Keyboard and then I want to either press Tab/Enter keys on my keyboard or use the Button Enter to get to the next field, if I'm pressing the actual Keyboard Keys e.g. "Enter" or "Tabulator" I'm getting focus of the next textbox with following code:

        private void PerformEnter(object sender, KeyEventArgs e)
    {
        try
        {
            if (e.KeyCode == Keys.Enter || e.KeyCode == Keys.Return)
            {
                this.SelectNextControl((Control)sender, true, true, true, true);
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message, "An error has occurred", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }

Which is executed in all of the KeyUp Event Handlers of my existing textboxes. But if I now press Enter this solution won't do it because the next Control in the Form/Panel that i'm using is not the next textbox where it should head to, because I jumped from my textbox that then lost Focus to the Numpad Button Enter which then gets the focus, but how do I manage to jump to the next textbox that has the next greater TabIndex than my recent textbox? My textboxes have the following TabIndex:

txtInputField1.TabIndex = 1;
txtInputField2.TabIndex = 2;
txtInputField3.TabIndex = 3;
txtInputField4.TabIndex = 4;

I also have an field named _recentTextBox to keep track of the recentTextBox which works.

private TextBox _recentTextBox;

Which is then set in each textboxes Leave Event Handler.

    private void txtInputField1_Leave(object sender, EventArgs e)
    {
        _recentTextBox = (TextBox)sender;
    }

So how I can I achieve this when I enter for example txtInputField1 clicking Enter on the NumPad Button that then the next Control that is selected needs to be txtInputField2 instead of in my situation the next Control that has an greater TabIndex than my Enter Button? Thanks in advance and any help would be appreciated.
Also there's the Layout of my UserControl if it is any help.

UserControl_Layout

1

There are 1 answers

1
msmolcic On BEST ANSWER

You could collect your input boxes in the Dictionary<int, TextBox> mapped by their TabIndex and have a separate field for the currently selected input field.

private Dictionary<int, TextBox> inputFieldsTabOrder = new Dictionary<int, TextBox>();

private TextBox selectedInputField;

public YourForm()
{
    InitializeComponent();

    // Set the first TextBox as the initially selected input field and focus it.
    this.selectedInputField = this.txtInputField1;
    this.selectedInputField.Focus();

    // Collect the other TextBox input fields mapped by TabIndex to your Dictionary.
    this.inputFieldsTabOrder.Add(this.txtInputField1.TabIndex, this.txtInputField1);    
    this.inputFieldsTabOrder.Add(this.txtInputField2.TabIndex, this.txtInputField2);
    this.inputFieldsTabOrder.Add(this.txtInputField3.TabIndex, this.txtInputField3);
    this.inputFieldsTabOrder.Add(this.txtInputField4.TabIndex, this.txtInputField4);   
}

In the Enter event of your input fields, simply set the selectedInputField value to the sender value which should be the TextBox that just got focus.

private void InputField_OnEnter(object sender, EventArgs e)
{
    this.selectedInputField = (TextBox)sender;
}

In the KeyUp event of your input fields and the Click event of your Enter button, call the same FocusNextInputField method which should call the next TextBox in the line.

private void InputField_OnKeyUp(object sender, KeyEventArgs e)
{
    if (e.KeyCode == Keys.Enter || e.KeyCode == Keys.Return)
    {
        this.FocusNextInputField();
    }
}

private void ButtonEnter_OnClick(object sender, EventArgs e)
{
    this.FocusNextInputField();
}

The definition of FocusNextInputField method should be the following.

private void FocusNextInputField()
{
    int nextInputFieldIndex = this.selectedInputField.TabIndex % inputFieldsTabOrder.Count + 1;
    this.selectedInputField = this.inputFieldsTabOrder[nextInputFieldIndex];
    this.selectedInputField.Focus();
}

What happens here is that the currently selected input field index gets incremented by one, allowing us to select the next input field in the row. Modulo is used in the calculation in order to switch from the last input field to the first one again.