MaskedTextBox detecting a tab - c#

I have a MaskedTextBox that formats text to look like (###) ###-####
After entering the first 3 digits, they like to press "TAB" to the next set. Unfortunately by pressing TAB, they are in the next field.
So my boss asked me to modify the application so that the users remain in the same field but the cursor is in the next group.
private void maskedTextBoxHomePhone_KeyPress(object sender, KeyPressEventArgs e)
{
MaskedTextBox mtb = (MaskedTextBox)sender;
if (e.KeyChar == (char)Keys.Tab)
{
if (mtb.TextLength == 3)
{
mtb.SelectionStart = 4;
}
}
}
I've also tried
private void maskedTextBoxHomePhone_KeyDown(object sender, KeyEventArgs e)
{
MaskedTextBox mtb = (MaskedTextBox)sender;
if (e.KeyCode == Keys.Tab)
{
if (mtb.TextLength == 3)
{
mtb.SelectionStart = 4;
}
}
}

Tabs have a special meaning, that will cause the focus to change, so the event handler won't get called.
You could work around this by using the Leave event of a text box and counting the textlength that you have stored in some local variable:
private void maskedTextBoxHomePhone_Leave(object sender, EventArgs e)
{
if (_mtbTextLength == 3) { //change selection start and goes back to masked text box }
}
Anyway, actually I would try to convince my boss otherwise. Do you
really need this? Tabs are always used to change fields, you can get
your users confused.
Another option would be to change the Tab behaviour by overriding the ProcessCmdKey:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == Keys.Tab)
{
//Do something
}
}

Related

C# custom ENTER key behaviour

I have a small projet in which I want several buttons to behave differently when Clicked or Ctrl+Clicked. To achieve that, each of those buttons has this kind of function attached to their Click() event :
private void Button1_Click(object sender, EventArgs e)
{
int value = 10 //default value
bool boool = false;
if (ModifierKeys == Keys.Control)
{
using (var form = new NUP_Popup(0, value, value, "maximum ?"))
{ //creates a simple window that allows user to change the value of 'value'
form.ShowDialog();
if (form.DialogResult == DialogResult.OK)
{
value = form.retVal;
boool = true;
}
else return;
}
}
//do stuff here, either with default or user value
}
Now, Clicking or Ctrl+Clicking behaves as intended with this function. My problem is that this behaviour doesn't apply when my buttons are activated using the Enter key : Enter key alone triggers the "normal" behaviour but Ctrl+Enter does nothing (button is not activated).
I already have overriden the ProcessDialogKey() function to close the window when Escape is pressed, so I thought I could use it to make Enter key presses trigger the Click() event function :
protected override bool ProcessDialogKey(Keys keyData) //Allows quit when Esc is pressed
{
if (Form.ModifierKeys == Keys.None && keyData == Keys.Escape)
{
this.Close();
return true;
}
if (keyData == Keys.Return)
{
this.OnClick(new EventArgs());
}
return base.ProcessDialogKey(keyData);
}
And that's where I'm stuck. Of course this doesn't do anything but I don't really have an idea of what to type inside my second condition to make it work.
Maybe I'm using the wrong approach ? Can someone point me in the right direction to do it ?
Assuming you placed a Label with ID Label1 and a button with ID Button1, following will do:
private void button1_Click(object sender, EventArgs e)
{
label1.Text = "Button Clicked";
if (Control.ModifierKeys == Keys.Control) label1.Text += " with Ctrl";
}
private void button1_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == '\n') button1_Click(sender, new EventArgs());
}
to your solution, simply add a KeyPress event to your Button1 and apply following code inside the keypress event Button1_KeyPress:
if (e.KeyChar == '\n') Button1_Click(sender, new EventArgs());
Okay, so I finally found a working solution by adding this to my overriden ProcessDialogKey() method :
if (keyData == (Keys.Enter | Keys.Control))
{
(this.ActiveControl as Button).PerformClick();
}
I don't know if it qualifies as "clean" code, but it has the merit of fulfilling my 2 requirements : making Ctrl+Enter function as Ctrl+Click without having to declare 2 methods per Button.
I found a solution that enables you to either click Enter or Ctrl+Enter:
private void txtIP_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == '\n' || e.KeyChar == '\r') btnStart_Click(sender, new EventArgs());
}

C# Cannot handle Ctrl+K event of textbox

I would like to perform some actions when the user presses Ctrl + K on a textbox.
private void subject_TextBox_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control && e.KeyCode == Keys.K)
MessageBox.Show("!");
}
Nothing happens when I run it.
When I debug I can see that e.Control is true (this means I pressed Ctrl) but the e.KeyCode is not equivalent to K.
Any ideas?
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == (Keys.Control | Keys.K) && focusedTextbox == subject_TextBox)
{
//Some Code
}
}
private TextBox focusedTextbox = null;
private void subject_TextBox_KeyDown(object sender, KeyEventArgs e)
{
MethodName(e.KeyCode)
}
private void MethodName(Keys keys)
{
focusedTextbox = (TextBox)sender;
}
Use this code, this should work i have tested it myself and it will work, you will want to run the 'MethodName' method in each textbox, or if you can find a better way to change the 'focusedTextBox' field then do that hope this helped.
In the KeyDown event, you just ask for the 'state' of the keyboard.
You might want to check out this topic:
Capture multiple key downs in C#
Really don't know what is the problem reason.
May the event is fired as soon as the Ctrl is pressed, without waiting to the K to be pressed as well.
However, when I use the same code in the TextBox_KeyUp event, it works fine.

How can I get my cursor out of the textbox?

I have a pretty complex visual studio form where I have like 2 textboxes, and some other stuff I need for my project, but my problem is - I want to use arrow keys to do tasks (bind them like short-cuts) and I can do that only when I don't edit my textboxes or else I get stuck in them and even if I try to reset my cursor (click on the form) it stays in the textbox and I can only jump in between characters, not use my arrows like I binded them. So my two questions are -
How can I reset my cursor if I have previously selected a textbox?
How can I unbind my default arrow keys so they don't jump between characters and buttons?
Try adding a key event on the textboxes that catches the arrow key strokes and moves focus accordingly.
void inputField_KeyDown(object sender, KeyEventArgs e)
{
if ((e.KeyCode == Keys.Left) || (e.KeyCode == Keys.Right) || (e.KeyCode == Keys.Up) || (e.KeyCode == Keys.Down))
{
//nextControl.Focus();
}
}
Just be aware that this will then remove the ability to navigate between the characters in a textbox. I think that the numpad arrows might still work inside the textbox since they have a different keycodes, but I can't be sure right now.
Hi and Welcome to stackoverflow, I'm not sure i have a complete answere but I have a few thougth on the subject.
Hard to answeer without some code, to se how you turns off the curser i think?
why does it have to in the first place? seems to overcomlicate it abit ?
the way i whould go about this, it's to egnore the the muse curser all together at first, and make a on KeyDown event on the textbox that needs the to be able to shift to the next like this
private void yourControl_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyData == Keys.Down || e.KeyData == Keys.Up)
{
// shift to next textbox maybe, to keep thing simple ?
}
}
though this will act wierd if you use a mulitlines textbox or other control that allready have these keys bind.
you can allso add a field boolean as a switch to enable the keys, that gets set on the textsboxes activation (thats what happens then you click it to write text) and it can be reused, then it look like this
class yourProgram
{
private bool fieldIskeysMode = false;
private void yourControl_KeyDown(object sender, KeyEventArgs e)
{
if (fieldIskeysMode) // if True
{
if (e.KeyData == Keys.Down || e.KeyData == Keys.Up)
{
// shift to next textbox maybe, to keep thing simple ?
}
if (e.KeyData == Keys.Escape) fieldIskeysMode = false; // one line set to falls on esc key
}
}
private void yourControl_Activate(object sender, KeyEventArgs e)
{
if (!fieldIskeysMode) // if not true
{
fieldIskeysMode = true;
}
}
}
hope this helps.

Tab will not fire keydown or keypress event

I am working in a webform and have a form with a tab bar on it. Each tab has multiple text boxes in it. I have the tab indexes incremented, starting with 1 for each tab. I want to tab from tab to tab if the user hits the end of the form and hits tab.
I used the leave method and changed the tabs for my tab control the only problem is if I didn't hit tab and say I click to another control on that tab it will still shoot over to the new tab.
I figure a way to solve this would be to listen for the tab key press and if the key press is tab on leave then change the form to the other tab, I just can't seem to get it to work though. I have tried with keypress and keydown but neither will pick up that tab as a key. If I was to say click or hit start typing it will trigger the events but tab will not.
Any suggestions?
I have tried these and none of these event would even trigger.
private void afsiTxtDaysForTempOEpriceOverrides_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == 11)
{
afsiTxtDaysForTempOEpriceOverrides_Leave(sender, e);
}
}
private void afsiTxtDaysForTempOEpriceOverrides_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == "11")
{
afsiTxtDaysForTempOEpriceOverrides_Leave(sender, e);
}
}
private void afsiChkSalesBaseCostUpdate_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == 11)
{
afsiChkSalesBaseCostUpdate_Leave(sender, e);
}
}
private void afsiChkSalesBaseCostUpdate_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == 11)
{
afsiChkSalesBaseCostUpdate_Leave(sender, e);
}
}
EDIT: Found out that the page is using UltraWinTabControl from Infragistics so maybe this is causing some issues with the tabbing.
I ended up needing to override ProcessCmdKey now I face a new problem that is kind of related but not particular to this so I will add it as a comment if I get my answer.
private bool isTab = false;
private bool isShiftTab = false;
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == Keys.Tab)
{
isTab = true;
ShiftTab.Append("Tab");
}
else
{
isTab = false;
}
return base.ProcessCmdKey(ref msg, keyData);
}
You will need to have the MultiLine property set to true, and AcceptsTab also set to true.
Or use e.KeyCode instead or e.KeyData, it worked for me
if (e.KeyCode == Keys.Tab | e.KeyData == Keys.Enter)

Press Enter to move to next control

I have a few TextBox on the WinForm. I would like the focus to move to the next control when Enter key is pressed? Whenever a textbox gains control, it will also select the text, so that any editing will replace the current one.
What is the best way to do this?
Tab as Enter: create a user control which inherits textbox, override the KeyPress method. If the user presses enter you can either call SendKeys.Send("{TAB}") or System.Windows.Forms.Control.SelectNextControl(). Note you can achieve the same using the KeyPress event.
Focus Entire text: Again, via override or events, target the GotFocus event and then call TextBox.Select method.
A couple of code examples in C# using SelectNextControl.
The first moves to the next control when ENTER is pressed.
private void Control_KeyUp( object sender, KeyEventArgs e )
{
if( (e.KeyCode == Keys.Enter) || (e.KeyCode == Keys.Return) )
{
this.SelectNextControl( (Control)sender, true, true, true, true );
}
}
The second uses the UP and DOWN arrows to move through the controls.
private void Control_KeyUp( object sender, KeyEventArgs e )
{
if( e.KeyCode == Keys.Up )
{
this.SelectNextControl( (Control)sender, false, true, true, true );
}
else if( e.KeyCode == Keys.Down )
{
this.SelectNextControl( (Control)sender, true, true, true, true );
}
}
See MSDN SelectNextControl Method
In a KeyPress event, if the user pressed Enter, call
SendKeys.Send("{TAB}")
Nicest way to implement automatically selecting the text on receiving focus is to create a subclass of TextBox in your project with the following override:
Protected Overrides Sub OnGotFocus(ByVal e As System.EventArgs)
SelectionStart = 0
SelectionLength = Text.Length
MyBase.OnGotFocus(e)
End Sub
Then use this custom TextBox in place of the WinForms standard TextBox on all your Forms.
This may help:
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
//
// Detect the KeyEventArg's key enumerated constant.
//
if (e.KeyCode == Keys.Enter)
{
MessageBox.Show("You pressed enter! Good job!");
}
}
You can put a KeyPress handler on your TextBoxes, and see which key was used.
To handle the text selection, put a handler on the GotFocus event.
You may also want to consider how to (or if you need to) handle multi-line TextBoxes.
private void txt_invoice_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
txt_date.Focus();
}
private void txt_date_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
txt_patientname.Focus();
}
}
You could also write your own Control for this, in case you want to use this more often.
Assuming you have multiple TextBoxes in a Grid, it would look something like this:
public class AdvanceOnEnterTextBox : UserControl
{
TextBox _TextBox;
public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(String), typeof(AdvanceOnEnterTextBox), null);
public static readonly DependencyProperty InputScopeProperty = DependencyProperty.Register("InputScope", typeof(InputScope), typeof(AdvanceOnEnterTextBox), null);
public AdvanceOnEnterTextBox()
{
_TextBox = new TextBox();
_TextBox.KeyDown += customKeyDown;
Content = _TextBox;
}
/// <summary>
/// Text for the TextBox
/// </summary>
public String Text
{
get { return _TextBox.Text; }
set { _TextBox.Text = value; }
}
/// <summary>
/// Inputscope for the Custom Textbox
/// </summary>
public InputScope InputScope
{
get { return _TextBox.InputScope; }
set { _TextBox.InputScope = value; }
}
void customKeyDown(object sender, KeyEventArgs e)
{
if (!e.Key.Equals(Key.Enter)) return;
var element = ((TextBox)sender).Parent as AdvanceOnEnterTextBox;
if (element != null)
{
int currentElementPosition = ((Grid)element.Parent).Children.IndexOf(element);
try
{
// Jump to the next AdvanceOnEnterTextBox (assuming, that Labels are inbetween).
((AdvanceOnEnterTextBox)((Grid)element.Parent).Children.ElementAt(currentElementPosition + 2)).Focus();
}
catch (Exception)
{
// Close Keypad if this was the last AdvanceOnEnterTextBox
((AdvanceOnEnterTextBox)((Grid)element.Parent).Children.ElementAt(currentElementPosition)).IsEnabled = false;
((AdvanceOnEnterTextBox)((Grid)element.Parent).Children.ElementAt(currentElementPosition)).IsEnabled = true;
}
}
}
}
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == (Keys.Enter))
{
SendKeys.Send("{TAB}");
}
return base.ProcessCmdKey(ref msg, keyData);
}
goto the design form and View-> tab(as like picture shows) Order then you ordered all the control[That's it]
Try to use:
SendKeys.Send("{TAB}")

Categories