Transferring focus from a textbox to a button
-
Hi. I'm having a problem with focusing from textbox to a button. Is there a way in doing this? I tried coding it but it doesn't work. Here's my code so far: The textbox:
private void txtBoxLogIn_TextChanged(object sender, EventArgs e)
{
txtBoxLogIn.KeyPress += new KeyPressEventHandler(txtBoxLogIn_KeyPress);
}and the eventhandler:
private void txtBoxLogIn_KeyPress(object sender, KeyPressEventArgs e)
{if (e.KeyChar == (char)Keys.Enter) { txtBoxPassword.Focus(); } else if (e.KeyChar == (char)Keys.Enter && txtBoxPassword.Focused == true) { btnProceedLogIn.Focus(); }
}
I'll be using only one eventhandler in transferring focus to other controls.
-
Hi. I'm having a problem with focusing from textbox to a button. Is there a way in doing this? I tried coding it but it doesn't work. Here's my code so far: The textbox:
private void txtBoxLogIn_TextChanged(object sender, EventArgs e)
{
txtBoxLogIn.KeyPress += new KeyPressEventHandler(txtBoxLogIn_KeyPress);
}and the eventhandler:
private void txtBoxLogIn_KeyPress(object sender, KeyPressEventArgs e)
{if (e.KeyChar == (char)Keys.Enter) { txtBoxPassword.Focus(); } else if (e.KeyChar == (char)Keys.Enter && txtBoxPassword.Focused == true) { btnProceedLogIn.Focus(); }
}
I'll be using only one eventhandler in transferring focus to other controls.
Is it a login dialog? and you want btnProceedLogIn to behave as default button? set the DialogResult property of btnProceedLogIn to OK and then whenever you press Enter, btnProceedLogIn will be activated. Now, in the code, if the login is successful, and you want to close the form, no need to do anything else. In case the login is unsuccessful, add a line:
this.DialogResult = DialogResult.None;
This will ensure that form will not be closed.
-
Hi. I'm having a problem with focusing from textbox to a button. Is there a way in doing this? I tried coding it but it doesn't work. Here's my code so far: The textbox:
private void txtBoxLogIn_TextChanged(object sender, EventArgs e)
{
txtBoxLogIn.KeyPress += new KeyPressEventHandler(txtBoxLogIn_KeyPress);
}and the eventhandler:
private void txtBoxLogIn_KeyPress(object sender, KeyPressEventArgs e)
{if (e.KeyChar == (char)Keys.Enter) { txtBoxPassword.Focus(); } else if (e.KeyChar == (char)Keys.Enter && txtBoxPassword.Focused == true) { btnProceedLogIn.Focus(); }
}
I'll be using only one eventhandler in transferring focus to other controls.
gamer1127 wrote:
private void txtBoxLogIn_TextChanged(object sender, EventArgs e) { txtBoxLogIn.KeyPress += new KeyPressEventHandler(txtBoxLogIn_KeyPress); }
Why re-subscribe to the event every time the text changes? Shouldn't you only need to subscribe to that once?
gamer1127 wrote:
I'll be using only one eventhandler in transferring focus to other controls.
Why? Have you tried separate handlers for each control? That might be the source of the problem. [EDIT] Actually, that is the source of the problem. The first
if
statement in theKeyPress
handler doesn't check what control the Enter Key was pressed in. It just sets the focus to the password box regradless of where Enter was pressed.:badger:
-
Is it a login dialog? and you want btnProceedLogIn to behave as default button? set the DialogResult property of btnProceedLogIn to OK and then whenever you press Enter, btnProceedLogIn will be activated. Now, in the code, if the login is successful, and you want to close the form, no need to do anything else. In case the login is unsuccessful, add a line:
this.DialogResult = DialogResult.None;
This will ensure that form will not be closed.
-
Actually to have a button respond to the enter key you need to set the AcceptButton property of the form that the button is on.
There is a catch. If you only set AcceptButton Property, the Button doesn't change its DialogResult property. This however is not true for Cancel button in which case, Cancel button dialogresult is changed.
-
There is a catch. If you only set AcceptButton Property, the Button doesn't change its DialogResult property. This however is not true for Cancel button in which case, Cancel button dialogresult is changed.
To have a button respond to a key press, you set the AcceptButton property of the form for enter and the CancelButton property for the esc key the DialogResult property of the buttons has no effect on this what so ever. The DialogResult property of the buttons is only used to control what is returned as a DialogResult when you use ShowDialog() to display a form. -- EDIT -- As the OP is trying to move focus from control to control when the enter key is pressed, DialogResult really has no bearing on the OP question.
-
gamer1127 wrote:
private void txtBoxLogIn_TextChanged(object sender, EventArgs e) { txtBoxLogIn.KeyPress += new KeyPressEventHandler(txtBoxLogIn_KeyPress); }
Why re-subscribe to the event every time the text changes? Shouldn't you only need to subscribe to that once?
gamer1127 wrote:
I'll be using only one eventhandler in transferring focus to other controls.
Why? Have you tried separate handlers for each control? That might be the source of the problem. [EDIT] Actually, that is the source of the problem. The first
if
statement in theKeyPress
handler doesn't check what control the Enter Key was pressed in. It just sets the focus to the password box regradless of where Enter was pressed.:badger:
Jimmanuel wrote:
Why? Have you tried separate handlers for each control?
I just thought of applying the concept of having controls tagged to only one event-handler if they will have the same behavior. If that is the case, then i'll try using one event-handler for each control.
-
gamer1127 wrote:
private void txtBoxLogIn_TextChanged(object sender, EventArgs e) { txtBoxLogIn.KeyPress += new KeyPressEventHandler(txtBoxLogIn_KeyPress); }
Why re-subscribe to the event every time the text changes? Shouldn't you only need to subscribe to that once?
gamer1127 wrote:
I'll be using only one eventhandler in transferring focus to other controls.
Why? Have you tried separate handlers for each control? That might be the source of the problem. [EDIT] Actually, that is the source of the problem. The first
if
statement in theKeyPress
handler doesn't check what control the Enter Key was pressed in. It just sets the focus to the password box regradless of where Enter was pressed.:badger:
-
Hi. I'm having a problem with focusing from textbox to a button. Is there a way in doing this? I tried coding it but it doesn't work. Here's my code so far: The textbox:
private void txtBoxLogIn_TextChanged(object sender, EventArgs e)
{
txtBoxLogIn.KeyPress += new KeyPressEventHandler(txtBoxLogIn_KeyPress);
}and the eventhandler:
private void txtBoxLogIn_KeyPress(object sender, KeyPressEventArgs e)
{if (e.KeyChar == (char)Keys.Enter) { txtBoxPassword.Focus(); } else if (e.KeyChar == (char)Keys.Enter && txtBoxPassword.Focused == true) { btnProceedLogIn.Focus(); }
}
I'll be using only one eventhandler in transferring focus to other controls.
Now I have a new problem. Whenever I click the Log-In button it doesn't show an error message even if there's no entered data or the entered username and passwords are both wrong. It just do the event of logging in if both the username and passwords are correct. The username and password are saved in an MS Access database and i used SELECT query to check if both exists. Here is the code to clearly understand:
string sConnection = "Provider = Microsoft.Jet.OLEDB.4.0;" + "Data Source = Schedule.mdb";
try { OleDbConnection dbConnect = new OleDbConnection(sConnection); dbConnect.Open(); string sqlString = "SELECT \* FROM LogIn WHERE ID = '" + txtBoxLogIn.Text + "' AND Password = '" + txtBoxPassword.Text + "';"; OleDbCommand dbCmd = new OleDbCommand(); dbCmd.CommandText = sqlString; dbCmd.Connection = dbConnect; OleDbDataReader dbReader; dbReader = dbCmd.ExecuteReader(); while (dbReader.Read()) { if (dbReader\[0\].ToString() == txtBoxLogIn.Text && dbReader\[1\].ToString() == txtBoxPassword.Text ) { frmMainForm frmMainForm = new frmMainForm(); frmMainForm.ShowDialog(); this.Close(); } else { MessageBox.Show("Either the Username or Password does not exist", "Log-In Error", MessageBoxButtons.OKCancel, MessageBoxIcon.Error); } } dbReader.Close(); dbConnect.Close(); } catch (Exception ex) { MessageBox.Show(ex.ToString()); return; }
Did I do something wrong?
-
Jimmanuel wrote:
Why? Have you tried separate handlers for each control?
I just thought of applying the concept of having controls tagged to only one event-handler if they will have the same behavior. If that is the case, then i'll try using one event-handler for each control.
But they don't all have the same behaviour, they have similar behaviour. It's not a bad idea, but you have to abstract away all of the things from the handler that are specific for each control. You can actually do this pretty elegantly with one handler by using the
Control
sTag
property and thesender
param of the handler. The idea is that the Enter key press transfers focus to the nextControl
, right? That's the similar behaviour the handler should implement but it needs to know whichControl
to transfer focus to. That's easy with theTag
. In the constructor of your form go through the similar behavingControl
s and save a reference to the nextControl
that gets focus in theTag
:txtBoxLogIn.Tag = txtBoxPassword; // give focus to the password box
txtBoxPassword.Tag = btnProceedLogIn; // give focus to the button
btnProceedLogIn.Tag = null; // set this to null to signify the end of the chainThen your handler simplifies to this:
private void focusForwardingControl_KeyDown(object sender, KeyEventArgs e)
{
Control control = sender as Control;
if (control == null)
{
// if this event isn't from a Control object then return
return;
}if (e.KeyCode == Keys.Enter) { // get the next Control to have focus Control nextControl = control.Tag as Control; if (nextControl != null) { // if there's a valid Control stored then give it focus nextControl.Focus(); } }
}
Then both text boxes can use to the same event handler to forward focus to the next
Control
in the chain. Note that I'm using theKeyDown
handler instead ofKeyPress
, I like the Event Args better. Also, all code here was written in the CP post editor so it hasn't been tested or compiled :):badger:
-
But they don't all have the same behaviour, they have similar behaviour. It's not a bad idea, but you have to abstract away all of the things from the handler that are specific for each control. You can actually do this pretty elegantly with one handler by using the
Control
sTag
property and thesender
param of the handler. The idea is that the Enter key press transfers focus to the nextControl
, right? That's the similar behaviour the handler should implement but it needs to know whichControl
to transfer focus to. That's easy with theTag
. In the constructor of your form go through the similar behavingControl
s and save a reference to the nextControl
that gets focus in theTag
:txtBoxLogIn.Tag = txtBoxPassword; // give focus to the password box
txtBoxPassword.Tag = btnProceedLogIn; // give focus to the button
btnProceedLogIn.Tag = null; // set this to null to signify the end of the chainThen your handler simplifies to this:
private void focusForwardingControl_KeyDown(object sender, KeyEventArgs e)
{
Control control = sender as Control;
if (control == null)
{
// if this event isn't from a Control object then return
return;
}if (e.KeyCode == Keys.Enter) { // get the next Control to have focus Control nextControl = control.Tag as Control; if (nextControl != null) { // if there's a valid Control stored then give it focus nextControl.Focus(); } }
}
Then both text boxes can use to the same event handler to forward focus to the next
Control
in the chain. Note that I'm using theKeyDown
handler instead ofKeyPress
, I like the Event Args better. Also, all code here was written in the CP post editor so it hasn't been tested or compiled :):badger:
-
Now I have a new problem. Whenever I click the Log-In button it doesn't show an error message even if there's no entered data or the entered username and passwords are both wrong. It just do the event of logging in if both the username and passwords are correct. The username and password are saved in an MS Access database and i used SELECT query to check if both exists. Here is the code to clearly understand:
string sConnection = "Provider = Microsoft.Jet.OLEDB.4.0;" + "Data Source = Schedule.mdb";
try { OleDbConnection dbConnect = new OleDbConnection(sConnection); dbConnect.Open(); string sqlString = "SELECT \* FROM LogIn WHERE ID = '" + txtBoxLogIn.Text + "' AND Password = '" + txtBoxPassword.Text + "';"; OleDbCommand dbCmd = new OleDbCommand(); dbCmd.CommandText = sqlString; dbCmd.Connection = dbConnect; OleDbDataReader dbReader; dbReader = dbCmd.ExecuteReader(); while (dbReader.Read()) { if (dbReader\[0\].ToString() == txtBoxLogIn.Text && dbReader\[1\].ToString() == txtBoxPassword.Text ) { frmMainForm frmMainForm = new frmMainForm(); frmMainForm.ShowDialog(); this.Close(); } else { MessageBox.Show("Either the Username or Password does not exist", "Log-In Error", MessageBoxButtons.OKCancel, MessageBoxIcon.Error); } } dbReader.Close(); dbConnect.Close(); } catch (Exception ex) { MessageBox.Show(ex.ToString()); return; }
Did I do something wrong?
There are a couple things wrong: * This deserves a new post instead of a reply to your original question. * The reader and connection are not properly disposed of, they should be used in
using
statements to ensure that even if theException
handler orthis.Close()
is called they get cleaned up properly. * Catching the generalException
is considered bad practice. * The case wheredbReader.Read()
returns false isn't handled - if there aren't any matching rows then the innerif - else
will be skipped completely *** This is probably the cause of what you're seeing *SELECT *
is also not the best practice, it'd be better if you specify the column names in theSELECT
. * You should use a parameterized query to prevent SQL injection attacks. Here's and example forSqlConnection
s: clickety[^],OleDbConnection
s are similar * shouldn't thatwhile
be anif
? * If those column values might be null then they should be checked forDBNull.Value
before they'reToString()
ed:badger:
-
There are a couple things wrong: * This deserves a new post instead of a reply to your original question. * The reader and connection are not properly disposed of, they should be used in
using
statements to ensure that even if theException
handler orthis.Close()
is called they get cleaned up properly. * Catching the generalException
is considered bad practice. * The case wheredbReader.Read()
returns false isn't handled - if there aren't any matching rows then the innerif - else
will be skipped completely *** This is probably the cause of what you're seeing *SELECT *
is also not the best practice, it'd be better if you specify the column names in theSELECT
. * You should use a parameterized query to prevent SQL injection attacks. Here's and example forSqlConnection
s: clickety[^],OleDbConnection
s are similar * shouldn't thatwhile
be anif
? * If those column values might be null then they should be checked forDBNull.Value
before they'reToString()
ed:badger:
With all the things you pointed out, it means that I have to learn a lot of things when it comes to programming with relational database. :( Have to start reading all the ebooks that i got. We just started discussing programming with database and we already have a project that has it.
-
With all the things you pointed out, it means that I have to learn a lot of things when it comes to programming with relational database. :( Have to start reading all the ebooks that i got. We just started discussing programming with database and we already have a project that has it.
It's all forgivable if you're new :). The really important one in that list is to make sure that the connection to the database is cleaned up properly: see the docs for the OleDbConnection[^] class for a small example of how to protect your connection. For the details about what it's doing read up on the using[^] statement.
:badger:
-
It's all forgivable if you're new :). The really important one in that list is to make sure that the connection to the database is cleaned up properly: see the docs for the OleDbConnection[^] class for a small example of how to protect your connection. For the details about what it's doing read up on the using[^] statement.
:badger:
-
With all the things you pointed out, it means that I have to learn a lot of things when it comes to programming with relational database. :( Have to start reading all the ebooks that i got. We just started discussing programming with database and we already have a project that has it.
While a lot of folks will get mad at people "having others do their homework for them" you handled this very well. You attempted the code, had some problems and asked an intelligent question. You listened to advice, tried the solution and again did everything correct. You did your best and this stuff is not easy at all. Don't give up and keep going, with your attitude you can do it. :) Threads like these are part of why this place exists.