C# Disable the TAB key - c#

I have this code:
this.searchInput.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.inputKeypress);
private void Keypress(object sender, KeyPressEventArgs e)
{
// If Tab has been pressed
if(122 == (int)e.KeyChar)
{
switchTab(sTab);
MessageBox.Show(sTab);
}
}
What it does is that it sets focus to another element.
But, when the focus is set to a TextBox, and I press TAB, it just makes a tab in the TextBox, and does not set focus on the next element.
Anyone got an idea how can I make this work?
I've tried to set e.Handled = true; but that didn't work...

Have you tried setting AcceptsTab on the TextBox to false?
Edit:
yep. It does not work. Strange... It still tabulates in the textbox
That makes little sense. I ran a small test app, and the tab key only brings focus away from the TextBox when its AcceptsTab and Multiline properties are both true, regardless of an event handler being defined for KeyPress.
Are you sure some other code isn't setting AcceptsTab to true? If you are, does setting Multiline to false change the tab behaviour at all? Could you post more of your relevant code?

Set the AcceptsTab property of the text box to false?

You'll need to create an instance of the control like so, and override the following methods:
using System.Windows.Forms
//optional namespace
public class NoTabTextBox : TextBox
{
protected override bool IsInputKey(Keys keyData)
{
switch (keyData)
{
case Keys.Tab:
return true;
}
return base.IsInputKey(keyData);
}
protected override void OnKeyDown(KeyEventArgs e)
{
if (e.KeyCode == Keys.Tab) { e.Handled = true; e.SuppressKeyPress = true; }
base.OnKeyDown(e);
}
}
Build the solution, then subsitute you're regular TextBox with the new one 'NoTabTextBox', by finding it under the user controls in toolbox.
This will capture the Tab key and force it to do nothing.

Related

How to make Enter Key as Default key for Tab Changing for all the textbox in a Window Form C#?

I am using c# window form application. I have already tried many example on the internet for this query but nothing works for me. I just want to replace the action of Enter key with Tab key on a Window Forms. I don't want to apply keydown or up event on one by one on my textbox. I just want a single event which I can apply on my window form.
Thanks.
It works fine now I used these code of lines on form keyup event, and set the KeyPreview property True.
if (e.KeyData == System.Windows.Forms.Keys.Enter)
{
SendKeys.Send("{TAB}");
}
Create your own custom TextBox:
public class MyTextBox : TextBox
{
protected override void OnKeyDown(KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
Parent.SelectNextControl(this, true, true, true, true);
e.Handled = true;
e.SuppressKeyPress = true; // suppress Ding sound
}
base.OnKeyDown(e);
}
}
Compile the code. This component will appear in the toolbar. Use it instead of the regular textboxes.

How to enable a WinForm button in time to receive focus by tabbing

Visual Studio 2010, C#
I have a ComboBox with a DropDown, AutoComplete set to SuggestAppend and the AutoCompleteSource is from the ListItems. The user keys data into it until the have the correct entry. Utill the data matches one of the list items, a button next to the combobox is disabled.
If the user hits the tab key the autocomplete feature accepts current suggestion. It also moves on to the next control in tab sequence that is enabled. Of course since I want it to go to the disbabled button I need to enable it as soon as I validate the entry.
The problem is that none of the events I've tried, PreviewKeyDown, LostFocus, SelectedIndexChanged allow me to enable the button in time for it to be proccessed and receive the focus. It always goes to the next button in tab order which is always enabled.
I am about ready to leave the button enabled and have it give an error if pressed too soon but I don't want to do it that way. I also don't want to get into have special mode flags to keep track of when these controls receive focus. Validation seems to be a normal thing, but I'm stuck.
If the SelectedIndexChanged worked when the user made a match this would be easy. It doesn't fire when the box clears nor when a typed match is found.
You could create your own ComboBox class to encapsulate this behavior. Something like this:
using System;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.myComboBox1.TheButton = this.button1;
this.myComboBox1.Items.AddRange( new string[] {
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
"Sunday"
} );
button1.Enabled = false;
}
}
public class MyComboBox : ComboBox
{
public Control TheButton { get; set; }
public MyComboBox()
{
}
bool IsValidItemSelected
{
get { return null != this.SelectedItem; }
}
protected override void OnValidated( EventArgs e )
{
if ( null != TheButton )
{
TheButton.Enabled = this.IsValidItemSelected;
TheButton.Focus();
}
base.OnValidated( e );
}
protected override void OnTextChanged( EventArgs e )
{
if ( null != TheButton )
{
TheButton.Enabled = this.IsValidItemSelected;
}
base.OnTextChanged( e );
}
}
}
try this :
key_press event :
if (e.KeyData == Keys.Enter)
{
button2.Enabled = true;
button2.Focus();
}
Instead of the event hanlders you mentioned, (LostFocus, SelectedIndexChanged and PreviewKeyDown) use the "Validated" event of your combobox to set the enabled state of the button.
You may need to also manually focus on the button to force the focus to move to it though.
e.g.
private void comboBox1_Validated(object sender, EventArgs e)
{
button1.Enabled = true;
button1.Focus();
}
With some thought to the other answers here I came up with a partial senario that works without using AutoComplete. A side effect is that the PreviewKeyDown event is called a second time and therefore validation is called twice. I wonder why... maybe I should ask another question.
private void comboBox1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) {
if (e.KeyData == Keys.Tab) {
if (ValidationRoutine()) {
e.IsInputKey = true; //If Validated, signals KeyDown to examine this key
} //Side effect - This event is called twice when IsInputKey is set to true
}
}
private void comboBox1_KeyDown(object sender, KeyEventArgs e) {
if (e.KeyData == Keys.Tab) {
e.SuppressKeyPress = true; //Stops further processing of the TAB key
btnEdit.Enabled = true;
btnEdit.Focus();
}
}
Once you turn on AutoCompleteMode with any setting other than None, the KeyDown event doesn't fire for Tab anymore the key is silently eaten.

KeyDown event doesn't raise

I have a form with a button in. I want to capture the Form.KeyDown event.
private void buttonStart_Click(object sender, EventArgs e)
{
if (!this.gameRunning)
{
this.buttonStrat.Text = "Pause";
this.timer1.Enabled = true;
}
else
{
this.buttonStart.Text = "Continue";
this.timer1.Enabled = false;
}
this.gameRunning = !this.gameRunning;
}
However, I was disabling buttonStart without supporting PAUSE and it was working nice. Since I have added the PAUSE advantage, the Form.KeyDown event doesn't raise and buttonStart is Focused. Whenever I disable buttonStart, it fires.
NOTES:
I have set Form.KeyPreview to true, stills doesn't raise
I have set Form.AcceptButton to null, stills doesn't raise
I have made buttonStart subscriped to Form.KeyDown, stills doesn't.
I hope this will helps you ..
Override IsInputKey behaviour
You must override the IsInputKey behavior to inform that you want the Right Arrow key to be treated as an InputKey and not as a special behavior key.
For that you must override the method for each of your controls.
I would advise you to create your won Buttons, let's say MyButton
The class below creates a custom Button that overrides the IsInputKey method so that the right arrow key is not treated as a special key. From there you can easily make it for the other arrow keys or anything else.
public partial class MyButton : Button
{
protected override bool IsInputKey(Keys keyData)
{
if (keyData == Keys.Right)
{
return true;
}
else
{
return base.IsInputKey(keyData);
}
}
}
Afterwards, you can treat your keyDown event event in each different Button or in the form itself:
In the Buttons' KeyDown Method try to set these properties:
private void myButton1_KeyDown(object sender, KeyEventArgs e)
{
e.Handled = true;
//DoSomething();
}
-- OR --
handle the common behaviour in the form: (do not set e.Handled = true; in the buttons)
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
//DoSomething();
}

C#: TextBox not receiving keys when using TextPreview on form

I am implementing a search function in a windows form in c#. I have set KeyPreviewto true on the form and have added an event handler for KeyDown so I can catch things like ctrl+f, esc and enter.
I am catching these keys just fine and I'm able to make my text box appear, but I am unable to type into the box. All of the keys are going to PortsTraceForm_KeyDown(...) but they never make it to the text box. According to the msdn page about KeyPreview, setting e.Handled to false should cause the event to pass to the view in focus (the text box), but this isn't happening. I have not registered a KeyDown event for the text box, so it should be using the default behavior. Have I missed something?
KeyDown event:
private void PortsTraceForm_KeyDown(object sender, KeyEventArgs e)
{
e.SuppressKeyPress = true;
e.Handled = false;
if (e.KeyData == (Keys.F | Keys.Control)) // ctrl+f
{
e.Handled = true;
ShowSearchBar();
}
else if (e.KeyCode == Keys.Escape) // esc
{
e.Handled = true;
HideSearchBar();
}
else if (e.KeyCode == Keys.Enter) // enter
{
if (searchPanel.Visible)
{
e.Handled = true;
if (searchShouldClear)
SearchStart();
else
SearchNext();
}
}
}
show search bar:
private void ShowSearchBar()
{
FindBox.Visible = true;
FindBox.Focus(); // focus on text box
}
hide search bar:
private void HideSearchBar()
{
this.Focus(); // focus on form
FindBox.Visible = false;
}
Your TextBox likely does not have focus even though you are calling Focus(). From the documentation:
Focus is a low-level method intended primarily for custom control authors. Instead, application programmers should use the Select method or the ActiveControl property for child controls, or the Activate method for forms.
You can check the return value of Focus() for success, but I have had little luck in the past using that method to set focus to an arbitrary control. Instead, try using the method that the documentation suggests, i.e., call Select().
EDIT:
Nevermind (though it's still valid advice), I think I see your problem:
e.SuppressKeyPress = true
Why are you doing this? Again, from the docs:
[SuppressKeyPress] Gets or sets a value indicating whether the key event should be passed on to the underlying control
So you are intentionally preventing the TextBox from getting key events. If you want to pass the event through you shouldn't be setting that property to false.
try this example , of overrides method.
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
// your code here
// this is message example
MessageBox.Show(keyData.ToString());
return base.ProcessCmdKey(ref msg, keyData);
}
Regards.

How to skip Validating after clicking on a Form's Cancel button

I use C#.
I have a Windows Form with an edit box and a Cancel button. The edit box has code in validating event. The code is executed every time the edit box loses focus. When I click on the Cancel button I just want to close the form. I don't want any validation for the edit box to be executed. How can this be accomplished?
Here is an important detail: if the validation fails, then
e.Cancel = true;
prevents from leaving the control.
But when a user clicks Cancel button, then the form should be closed no matter what. how can this be implemented?
If the validation occurs when the edit box loses focus, nothing about the the cancel button is going to stop that from happening.
However, if the failing validation is preventing the cancel button from doing its thing, set the CausesValidation property of the button to false.
Reference: Button.CausesValidation property
Obviously CausesValidation property of the button has to be set to false and then the validating event will never happen on its click. But this can fail if the parent control of the button has its CausesValidation Property set to true. Most of the time developers misses/forgets to change the CausesValidation property of the container control (like the panel control). Set that also to False. And that should do the trick.
I was having problems getting my form to close, since the validation of certain controls was stopping it. I had set the control.CausesValidation = false for the cancel button and all the parents of the cancel button. But still was having problems.
It seemed that if the user was in the middle of editing a field that was using validation and just decided to give up (leaving the field with an invalid input), the cancel button event was being fired but the window would not close down.
This was fixed by the following in the cancel button click event:
private void btnCancel_Click(object sender, EventArgs e)
{
// Stop the validation of any controls so the form can close.
AutoValidate = AutoValidate.Disable;
Close();
}
Set the CausesValidation property of the Cancel button to false.
Set the CausesValidation property to false.
None of these answers quite did the job, but the last answer from this thread does. Basically, you need to:
Insure that the Cancel button (if any) has .CausesValidation set to false
Override this virtual method.
protected override bool ProcessDialogKey(Keys keyData) {
if (keyData == Keys.Escape) {
this.AutoValidate = AutoValidate.Disable;
CancelButton.PerformClick();
this.AutoValidate = AutoValidate.Inherit;
return true;
}
return base.ProcessDialogKey(keyData);
}
I didn't really answer this, just pointing to the two guys who actually did.
Setting CausesValidation to false is the key, however this alone is not enough. If the buttons parent has CausesValidation set to true, the validating event will still get called. In one of my cases I had a cancel button on a panel on a form, so I had to set CausesValidation = false on the panel as well as the form. In the end I did this programatically as it was simpler than going through all the forms...
Control control = cancelButton;
while(control != null)
{
control.CausesValidation = false;
control = control.Parent;
}
In my case, in the form I set the property AutoValidate to EnableAllowFocusChange
By using Visual Studio wizard you can do it like that:
Judicious use of the Control.CausesValidation property will help you achieve what you want.
Just above the validation code on the edit box add:
if (btnCancel.focused)
{
return;
}
That should do it.
In complement of the answer of Daniel Schaffer: if the validation occurs when the edit box loses focus, you can forbid the button to activate to bypass local validation and exit anyway.
public class UnselectableButton : Button
{
public UnselectableButton()
{
this.SetStyle(ControlStyles.Selectable, false);
}
}
or if you use DevExpress:
this.simpleButtonCancel.AllowFocus = false;
Note that doing so will change the keyboard experience: the tab will focus anymore on the cancel button.
Maybe you want to use BackgroundWorker to give little bit delay, so you can decide whether validation should run or not. Here's the example of avoiding validation on form closing.
// The flag
private bool _isClosing = false;
// Action that avoids validation
protected override void OnClosing(CancelEventArgs e) {
_isClosing = true;
base.OnClosing(e);
}
// Validated event handler
private void txtControlToValidate_Validated(object sender, EventArgs e) {
_isClosing = false;
var worker = new BackgroundWorker();
worker.DoWork += worker_DoWork;
worker.RunWorkerAsync();
worker.RunWorkerCompleted += worker_RunWorkerCompleted;
}
// Do validation on complete so you'll remain on same thread
void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
if (!_isClosing)
DoValidationHere();
}
// Give a delay, I'm not sure this is necessary cause I tried to remove the Thread.Sleep and it was still working fine.
void worker_DoWork(object sender, DoWorkEventArgs e) {
Thread.Sleep(100);
}
This is an old question however I recently ran into this issue and solved it this way:
1st, we are loading a UserControl into a 'shell' Form that has a save and cancel button. The UserControl inherit an interface (like IEditView) that has functions for Save, Cancel, Validate and ToggleValidate.
In the shell form we used the mouse enter and mouse leave like so:
private void utbCancel_MouseEnter(object sender, EventArgs e)
{
((Interface.IEdit)tlpMain.Controls[1]).ToggleValidate();
}
private void utbCancel_MouseLeave(object sender, EventArgs e)
{
((Interface.IEdit)tlpMain.Controls[1]).ToggleValidate();
}
Then in ToggleValidate (Say a simple form with two controls...you can always just loop through a list if you want) we set the CausesValidation
public bool ToggleValidate()
{
uneCalcValue.CausesValidation = !uneCalcValue.CausesValidation;
txtDescription.CausesValidation = !txtDescription.CausesValidation;
return txtDescription.CausesValidation;
}
Hope this helps.
I found this thread today while investigating why my form would not close when a validation error occurred.
I tried the CausesValidation = false on the close button and on the form itself (X to close).
Nothing was working with this complex form.
While reading through the comments I spotted one that appears to work perfectly
on the form close event , not the close button (so it will fire when X is clicked also)
This did the trick.
AutoValidate = AutoValidate.Disable;
Create a bool:
bool doOnce;
Set it to false in your function and then:
if (doOnce == false)
{
e.cancel = true;
doOnce = true;
}
This means it will only run once and you should be able to cancel it. This worked for me anyways.
This work for me.
private void btnCancelar_MouseMove(object sender, MouseEventArgs e)
{
foreach (Control item in Form.ActiveForm.Controls)
{
item.CausesValidation = false;
}
}

Categories

Resources