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}")
Related
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());
}
In my UWP application, I want my TextBox to be able to go to new line by pressing down the Enter key but I also need to trigger an action when Ctrl+Enter are pressed.
The issue is, I can't seem to find a way to prevent the text to go to the next line when I press down Ctrl+Enter. Here is the code I have tried.
XAML
<TextBox x:Name="TextBox1" AcceptsReturn="True" />
In the constructor
TextBox1.AddHandler(KeyDownEvent, new KeyEventHandler(TextBox1_KeyDown), true);
Handler
private void TextBox1_KeyDown(object sender, KeyRoutedEventArgs e)
{
var ctrl = Window.Current.CoreWindow.GetKeyState(VirtualKey.Control);
if (ctrl.HasFlag(CoreVirtualKeyStates.Down) && e.Key == VirtualKey.Enter)
{
e.Handled = true;
}
}
You could create a custom class that inherits from TextBox and override its OnKeyDown method where you have full control of firing the base.OnKeyDown method to prevent from adding a new line.
class CTRLEnterTextBox : TextBox
{
protected override void OnKeyDown(KeyRoutedEventArgs e)
{
if (Window.Current.CoreWindow.GetKeyState(VirtualKey.Control).HasFlag(CoreVirtualKeyStates.Down) && e.Key == VirtualKey.Enter)
{
e.Handled = true;
}
else
{
base.OnKeyDown(e);
}
}
}
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
}
}
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)
Hi i have a C# winform application with a particular form populated with a number of textboxes. I would like to make it so that by pressing the right arrow key this mimicks the same behaivour as pressing the tab key. Im not really sure how to do this.
I dont want to change the behaivour of the tab key at all, just get the right arrow key to do the same thing whilst on that form.
Can anyone offer any suggestions?
You should override the OnKeyUp method in your form to do this...
protected override void OnKeyUp(KeyEventArgs e)
{
if (e.KeyCode == Keys.Right)
{
Control activeControl = this.ActiveControl;
if(activeControl == null)
{
activeControl = this;
}
this.SelectNextControl(activeControl, true, true, true, true);
e.Handled = true;
}
base.OnKeyUp(e);
}
You can use the KeyDown event on the form to trap the key stroke then perform whatever action you want. For example:
private void MyForm_KeyDown(object sender, KeyEventArgs e)
{
if(e.KeyCode == Keys.Right)
{
this.SelectNextControl(....);
e.Handled = true;
}
}
Don't forget to set the KeyPreview property on the form to True.
I think this will accomplish what you're asking:
private void form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Right)
{
Control activeControl = form1.ActiveControl;
// may need to check for null activeControl
form1.SelectNextControl(activeControl, true, true, true, true);
}
}