I've set my form's KeyPreview property to true.
I've added this code:
private void PlatypusScheduleForm_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.F9)
{
tabControlPlatypi.SelectedTab = tabPageDuckBill;
}
else if (e.KeyCode == Keys.F10)
{
tabControlPlatypi.SelectedTab = tabPagePlatypus;
}
}
When I mash F10, it works as expected; mashing F9, however, does nothing.
tabPageDuckBill is the design-time/default tabPage that displays. Why would F10 work in taking me to the "other" tab page, but F9 then not go back to the original?
I found that if I just did this:
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.F9)
{
tabControl1.SelectedTab = tabPage1;
e.SuppressKeyPress = true;
}
else if (e.KeyCode == Keys.F10)
{
tabControl1.SelectedTab = tabPage2;
e.SuppressKeyPress = true;
}
}
it'll toggle back and forth just fine. Without that e.SuppressKeyPress = true;, however, it exhibited the behavior you mentioned.
I ran into this same problem in the past, and the problem persisted even after removing suspect code from the SelectedIndexChanged() event. I then used a different techniques that worked much better. Instead of using the form KeyDown event, I overrode the form ProcessCmdKey event as follow:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == Keys.F9)
{
this.tabControl1.SelectedTab = tabPage1;
return true;
}
else if (keyData == Keys.F10)
{
this.tabControl1.SelectedTab = tabPage2;
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
Related
I have this class inherited by RichTextBox. I overrided void OnKeyDown to check for incoming Tabs, because I don't want them.
Using breakpoints, I see that the overrided void is called, but it doesn't do its job.
Here is the code:
class ProgrammingTextBox : RichTextBox
{
protected override void OnKeyDown(KeyEventArgs e)
{
if (e.KeyCode == Keys.Tab)
{
// Tab was pressed, replace it with space
e.SuppressKeyPress = true; // Don't press Tab
for (int i = 0; i < 4; i++)
{
base.OnKeyDown(new KeyEventArgs(Keys.Space); // Repeat space 4 times
}
}
else base.OnKeyDown(e);
}
}
The wanted output should be text with 4 spaces but results as a Tab, like the OnKeyDown call from the for loop wasn't called.
Any idea what should I do?
base.OnKeyDown(new KeyEventArgs(Keys.Space);
OnKeyDown() on OnKeyPress() only generates notifications, their job is not to modify the Text property. That's up to you, assign the SelectedText property. Like this:
class ProgrammingTextBox : RichTextBox {
protected override bool IsInputKey(Keys keyData) {
if (keyData == Keys.Tab) return true;
return base.IsInputKey(keyData);
}
protected override void OnKeyDown(KeyEventArgs e) {
if (e.KeyCode == Keys.Tab) {
const string tabtospaces = " ";
var hassel = this.SelectionLength > 0;
this.SelectedText = tabtospaces;
if (!hassel) this.SelectionStart += tabtospaces.Length;
e.SuppressKeyPress = true;
}
else base.OnKeyDown(e);
}
}
When working with Tab (which is not an ordinary key - it can, say, be preprocessed and move focus control) you have to override a different method, ProcessCmdKey:
https://msdn.microsoft.com/en-us/library/system.windows.forms.control.processcmdkey(v=vs.110).aspx
Something like this
protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
if (keyData == Keys.Tab) {
//TODO: Your code here
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
see also
https://msdn.microsoft.com/en-us/library/system.windows.forms.textboxbase.acceptstab.aspx
I'm starting with C#, and I'm doing a calculator as my first project. I want a keyboard handler for my GUI that makes the same operations as the button handlers that I did before. The problem is when I get to the "enter" key. That's my void:
private void keyboardHandler(object sender, KeyPressEventArgs e){
char keyPressed = e.KeyChar;
if (keyPressed >= (char)Keys.D0 && keyPressed <= (char)Keys.D9)
{
//Some stuff
}
else if (keyPressed == (char)Keys.Back)
{
//More stuff
}
else if (keyPressed == (char)Keys.Enter || keyPressed == (char)Keys.Return)
{
this.operate();
operator = operation.START;
}
}
The problem is that if I press the enter key, it throws the handler event BUT it also press the button as if I click on it. Here's an image:
Any idea? Thanks :)
Override ProcessCmdKey handler for your form.
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == Keys.Enter)
{
this.operate();
operator = operation.START;
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
You need to set the KeyPressEventArgs.Handled property to true.
So this tells the operating system, or normal window messaging func (WndProc) to ignore the key press as it's already been dealth with. See: https://msdn.microsoft.com/en-us/library/system.windows.forms.keypresseventargs.handled%28v=vs.110%29.aspx
So like:
private void keyboardHandler(object sender, KeyPressEventArgs e){
char keyPressed = e.KeyChar;
if (keyPressed >= (char)Keys.D0 && keyPressed <= (char)Keys.D9)
{
//Some stuff
}
else if (keyPressed == (char)Keys.Back)
{
//More stuff
}
else if (keyPressed == (char)Keys.Enter || keyPressed == (char)Keys.Return)
{
this.operate();
operator = operation.START;
e.Handled = true;
}
}
my question is how to detect two hot keys in win form application
CTRL +C,CTRL,K like visual studio commenting command
I need to simulate VS hot key For commenting a line of code
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.Modifiers == Keys.Control && e.KeyCode == Keys.C)
{
}
}
Simple way is... There is a Windows API Function called ProcessCmdKey, by overriding this function we can achieve what we want
protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
if (keyData == (Keys.Control | Keys.C)) {
MessageBox.Show("You have pressed the shortcut Ctrl+C");
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
Microsoft Documentation can be found here
source
private bool _isFirstKeyPressedW = false;
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control & e.KeyCode == Keys.W)
{
_isFirstKeyPressedW = true;
}
if (_isFirstKeyPressedW)
{
if (e.Control & e.KeyCode == Keys.S)
{
//write your code
}
else
{
_isFirstKeyPressedW = e.KeyCode == Keys.W;
}
}
}
if you want to handle Ctrl + C followed by Ctrl+ K you need to maintain a state variable.
Set the Form KeyPreview property to true and handle the Form KeyDown event.
Try This:
this.KeyPreview=true;
private bool isFirstKeyPressed= false;
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control && e.KeyCode == Keys.C)
{
isFirstKeyPressed = true;
}
if (isFirstKeyPressed)
{
if (e.Control && e.KeyCode == Keys.K)
{
MessageBox.Show("Ctrl+C and Ctrl+K pressed Sequentially");
/*write your code here*/
isFirstKeyPressed= false;
}
}
}
How can I determine in KeyDown that ⇧ + Tab was pressed.
private void DateTimePicker_BirthDate_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Tab && e.Modifiers == Keys.Shift)
{
//do stuff
}
}
can't work, because never both keys are pressed exactly in the same second. You always to at first the Shift and then the other one..
It can't work, because never both keys are pressed exactly in the same second.
You're right that your code doesn't work, but your reason is wrong. The problem is that the Tab key has a special meaning - it causes the focus to change. Your event handler is not called.
If you use a different key instead of Tab, then your code will work fine.
If you really want to change the behaviour of Shift + Tab for one specific control, it can be done by overriding ProcessCmdKey but remember that many users use the Tab key to navigate around the form and changing the behaviour of this key may annoy those users.
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (DateTimePicker_BirthDate.Focused && keyData == (Keys.Tab | Keys.Shift))
{
MessageBox.Show("shift + tab pressed");
return true;
}
else
{
return base.ProcessCmdKey(ref msg, keyData);
}
}
If you are looking for a key press combination (Tab, then Shift) like Ctrl K + D you will have to use this modified example which was taken from MSDN social.
private StringBuilder _pressedKeys = new StringBuilder();
private void DateTimePicker_BirthDate_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Tab)
{
_pressedKeys.Append("Tab");
return;
}
if (e.Modifiers == Keys.Shift)
{
_pressedKeys.Append("Shift");
return;
}
if (_pressedKeys.ToString()."TabShift")
{
MessageBox.Show("It works!");
_pressedKeys.Clear();
}
else
{
_pressedKeys.Clear();
}
base.OnKeyDown(e);
}
First hook the Tab keypress event, then during the event, check the state of the Shift key. Keep in mind that there are two shift keys; make sure you check both of them.
This very related post shows how to check the state of modifier keys:
How to detect the currently pressed key?
Edit: an insight provided by another answerer who justly deserves an upvote is that the default behavior of the tab key (to change control focus) must be suppressed.
You can find your answer in
this post
It's Simple.
You can do that using KeyUp Event in the TextBox
private void txtBox1_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Tab && e.Shift == false) // TAB Key Pressed
{
}
if (e.KeyCode == Keys.Tab && e.Shift == true) // TAB + SHIFT Key Pressed
{
}
}
Or
Using this you can identify Any Key is press inside the form
//Add This code inside the Form_Load Event
private void Form1_Load(object sender, EventArgs e)
{
this.KeyUp += new System.Windows.Forms.KeyEventHandler(KeyPressEvent);
this.KeyPreview = true;
}
//Create this Custom Event
private void KeyPressEvent(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Tab && e.Shift == false) // TAB Key Pressed
{
}
if (e.KeyCode == Keys.Tab && e.Shift == true) // TAB + SHIFT Key Pressed
{
}
}
It's Simple.
Using this you can identify Any Key is press inside the form
//Add This code inside the Form_Load Event
private void Form1_Load(object sender, EventArgs e)
{
this.KeyUp += new System.Windows.Forms.KeyEventHandler(KeyPressEvent);
this.KeyPreview = true;
}
//Create this Custom Event
private void KeyPressEvent(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Tab && e.Shift == false) // TAB Key Pressed
{
}
if (e.KeyCode == Keys.Tab && e.Shift == true) // TAB + SHIFT Key Pressed
{
}
}
I have this requirement that the users need to use the keyboard numpad keys to control specific button assigned to it and perform each function.
Example:
if Numpad key 0 is press then Button0 will be triggered.
Or
if(Numpad0 is pressed)
{
//do stuff
if (inputStatus)
{
txtInput.Text += btn0.Text;
}
else
{
txtInput.Text = btn0.Text;
inputStatus = true;
}
}
else if(Numpad1 is pressed)
{
//do stuff
}
In my form i have a split container then all Buttons are located on a group box.
Set KeyPreview to true and handle KeyDown:
private void Form_KeyDown(object sender, KeyDownEventArgs e) {
if(e.KeyCode >= Keys.NumPad0 && e.KeyCode <= Keys.NumPad9)
((Button) this["Button" + (e.KeyCode - Keys.NumPad0).ToString()]).PerformClick();
}
I haven't tested it, but that's about how I would do it.
Add a window handler for the keydown event:
private void Window_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys./*numpad keys*/)
{
// do something such as call the click handler for your button!
e.Handled = true;
}
}
Or you can do it for the Form instead! You didn't specify, but the logic is the same.
And don't forget to turn KeyPreview on. Use Keys.NumPad0, Keys.NumPad1, etc for the number pad keys. See MSDN for the Keys Enumeration.
If you want to prevent the keys default action being performed set e.Handled = true as shown above.
Set the Form's KeyPreview to true and handle the Form.KeyDown event.
private void Form_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.NumPad0)
{
Button0.PerformClick()
e.Handled = true;
}
else if (e.KeyCode == Keys.NumPad1)
{...}
...
}
By using ProcessCmdkey Solves the Problem:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == Keys.Numpad0)
{
Numpad0.PerformClick();
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
Thanks