So I'm making a form, and I want the left and right keys to ONLY correspond to a numericUpDown box that I have on the form. So the code I wrote is the following :
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == Keys.Right)
{
numericUpDown1.Value = Convert.ToDecimal(numericUpDown1.Value + 1);
}
if (keyData == Keys.Left)
{
try
{
numericUpDown1.Value = Convert.ToDecimal(numericUpDown1.Value - 1);
}
catch { }
}
return base.ProcessCmdKey(ref msg, keyData);
}
However it seems to still do the default action of moving between different objects on the form if that's what the selected view is currently. How do I stop the default action?
You need to return true when you don't want the default action to be carried out.
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == Keys.Right)
{
numericUpDown1.Value = Convert.ToDecimal(numericUpDown1.Value + 1);
return true;
}
if (keyData == Keys.Left)
{
try
{
numericUpDown1.Value = Convert.ToDecimal(numericUpDown1.Value - 1);
return true;
}
catch { }
}
}
Maybe you should return true to indicate you have processed the key stroke message so that no other controls get it.
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == Keys.Right){
numericUpDown1.Value = Convert.ToDecimal(numericUpDown1.Value + 1);
return true;
}
else if (keyData == Keys.Left){
try {
numericUpDown1.Value = Convert.ToDecimal(numericUpDown1.Value - 1);
}
catch { }
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
NOTE: It looks like that you didn't post the code you run? I highly recommend you to post the actual code of yours, your code doesn't even compile because lacking of return. And your code lacks the return base.ProcessCmdKey(ref msg, keyData); which is required to process other keys.
you can add an event hanlder and do this:
private void keypressed(Object o, KeyPressEventArgs e)
{
if (e.KeyCode == Keys.Right || e.KeyCode == Keys.Left)
{
e.Handled = true; //this line will do the trick
//add the rest of your code here.
}
}
Related
The arrow keys should scroll only pictureBox (placed in panel). It works fine.
But it also scroll through comboBox items though it is closed (droppedUp).
How to disable it?
private void Form1_Load(object sender, EventArgs e)
{
comboBox1.DropDownStyle = ComboBoxStyle.DropDown;
comboBox1.DroppedDown = false;
comboBox1.Items.Add("111");
comboBox1.Items.Add("222");
}
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == Keys.Down)
{
Point current = panel1.AutoScrollPosition;
Point scrolled = new Point(current.X, -current.Y + 50);
panel1.AutoScrollPosition = scrolled;
}
return base.ProcessCmdKey(ref msg, keyData);
}
I had read about Control.PreviewKeyDown event:
preview key event
and also found another example:
preview key event
but I cannot understand how it used in my case.
As Hans Passant commented, you must return true. Also, add some other keys that maybe change the selected item in the combobox:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == Keys.Down ||
keyData == Keys.Up ||
keyData == Keys.PageDown ||
keyData == Keys.PageUp)
{
Point current = panel1.AutoScrollPosition;
Point scrolled = new Point(current.X, -current.Y + 50);
panel1.AutoScrollPosition = scrolled;
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
I have the following code in my project which disables arrow keys completely:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (!msg.HWnd.Equals(Handle) &&
(keyData == Keys.Left || keyData == Keys.Right ||
keyData == Keys.Up || keyData == Keys.Down))
return true;
if (keyData == Keys.Escape)
{
this.Close();
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
I also have this code after it which I need in order to make it such that the up arrow key counts up.
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Up)
{
int count;
if (count_lbl.Text.Equals(""))
count = 0;
else
count = Convert.ToInt32(count_lbl.Text);
count++;
count_lbl.Text = count.ToString();
}
}
I don't want the arrow keys to change focus to any control, other than the one I initialized my form to, but I still want to be able to use them later on in order to be able to do other things. Is there a way to do this?
Thanks.
Just put the "counting" code in ProcessCmdKey()?
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (!msg.HWnd.Equals(Handle) &&
(keyData == Keys.Left || keyData == Keys.Right ||
keyData == Keys.Up || keyData == Keys.Down)) {
if (keyData == Keys.Up) {
int count;
if (count_lbl.Text.Equals(""))
count = 0;
else
count = Convert.ToInt32(count_lbl.Text);
count++;
count_lbl.Text = count.ToString();
}
return true;
}
if (keyData == Keys.Escape)
{
this.Close();
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
I've set KeyPreview = true; for my Form. I basically want to use the arrow keys to go to the next and previous images instead of changing focus to different controls. I've set the Handled property to true but still the focus changes on arrow key press.
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Delete)
{
// Do stuff
}
else if (e.KeyCode == Keys.Left)
{
// Do stuff
e.Handled = true;
}
else if (e.KeyCode == Keys.Right)
{
// Do stuff
e.Handled = true;
}
}
EDIT
The behavior I want to achieve is as follows.
Left Arrow Key -> Previous Image
Right Arrow Key -> Next Image
Now, I also have a few TextBoxes on my Form and I therefore do not want to go to next and previous images if those Textboxes are in focus because then it should navigate through the text instead.
This worked for me.
Do not set KeyPreview = true; for the Form.
Override ProcessCmdKey and process as needed if any of the TextBoxes do not have focus.
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (textBox1.ContainsFocus || textBox2.ContainsFocus || textBox3.ContainsFocus)
{
return base.ProcessCmdKey(ref msg, keyData);
}
if (keyData == Keys.Delete)
{
removeRect();
return true;
}
else if (keyData == Keys.Left)
{
previousImg();
return true;
}
else if (keyData == Keys.Right)
{
nextImg();
return true;
}
else
{
return base.ProcessCmdKey(ref msg, keyData);
}
}
I am making key board shortcuts to a Winform application in C# using Visual Studio 2012. My shortcuts work perfect. But it gives a annoying beep sound.
I added e.Handled = true; and e.SuppressKeyPress = true; according to many threads. But it does not work and my winform stuck.
How can I avoid this?
private void textBoxSearch_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Down)
{
do stuff
}
else if (e.KeyCode == Keys.Enter)
{
//do stuff
}
e.Handled = true;
e.SuppressKeyPress = true;
}
and I need a solution for this too.
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == (Keys.Control | Keys.F))
{
//do stuff
}
else if (keyData == (Keys.Control | Keys.G)) {
//do stuff
}
return base.ProcessCmdKey(ref msg, keyData);
}
What you have in the KeyDown event should work. The SupressKeyPress = true stopped the ding for me when I copied your code.
In the ProcessCmdKey event you would need this:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == (Keys.Control | Keys.F))
{
//do stuff
return;
}
else if (keyData == (Keys.Control | Keys.G)) {
//do stuff
return;
}
return base.ProcessCmdKey(ref msg, keyData);
}
I have a simple increment on textbox by pressing down arrow key which are as below.
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == Keys.Down)
{
int c = int.Parse(textBox1.Text);
c++;
textBox1.Text = c.ToString();
}
}
The above works on pressing double down arrow key instead of single pressing down arrow key.
Note: The above code is on UserControl. And I have tried it on simple winform application on form keydown EventHandller and the same is works fine.
How to overcome?.
You'll need to handle other commands that existed before and return when you handle ones you are looking for. Try changing it to this and see if that helps:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (msg.WParam.ToInt32() == (int)Keys.Down)
{
int c = int.Parse(textBox1.Text);
c++;
textBox1.Text = c.ToString();
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}