Focus changes even after setting e.Handled = true - c#

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);
}
}

Related

How to disable scrolling of comboBox from keys arrow Up\Down when it closed?

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);
}

Prevent Arrow Keys from changing focus while still allowing functionality of the keys

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);
}

Avoiding alert on key board shortcut of C# winform

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);
}

Stop a key from firing an event in C# using ProcessCmdKey?

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.
}
}

Unable to capture Enter Key

I have a simple form by which I take input:
12 Buttons, 1 Textbox (disabled & read-only)
this is what I do to handle input
Login_KeyDown() is common method I call for all the KeyDown of every UI component & the form itself..
private void Login_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Escape)
{
Application.Exit();
}
else if (e.KeyCode == Keys.NumPad9 || e.KeyCode == Keys.D9)
{
button3.BackgroundImage = Properties.Resources.button_hover;
button3.ForeColor = Color.White;
pin.Text = pin.Text + "9";
}
else if (e.KeyCode == Keys.Back)
{
button11.BackgroundImage = Properties.Resources.button_hover;
button11.ForeColor = Color.White;
if (pin.Text.Length > 0)
pin.Text = pin.Text.Substring(0, pin.Text.Length - 1);
}
else if (e.KeyCode == Keys.Enter)
{
MessageBox.Show(pin.Text);
}
}
This code works fine when I start the app but after I have clicked on any component, rest of the code works fine but "Enter Key Condition" doesn't work.
My guess is as "Enter Key Condition" is not working for UI components or something like that.
I have also tried using "Key Press Event" which uses KeyPressEventArgs then checking KeyChar == 13 but that is also not working.
What is the problem, and how can I solve it?
p.s.
I have not set any button click events for any button, the app is 100% KBoard based.
Check out PreviewKeyDown. Return raises that event on button controls.
private void Form1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
if (e.KeyCode == Keys.Return)
MessageBox.Show("I found return");
}
Or alternatively you can force it to raise those special keys in the KeyDown Event by using:
private void Form1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
if (e.KeyCode == Keys.Return)
e.IsInputKey = true;
}
More information: http://msdn.microsoft.com/en-us/library/system.windows.forms.control.previewkeydown.aspx
Have you tried to use
Keys.Return
Instead
Edit:
Just thought of this. Do you have the acceptbutton set for the main form?
This is because your Form has AcceptButton defined. For example, you have a "OK", "Accept" or "Confirm" button with DialogResult set to "OK". This tells its parent form that there is an AcceptButton, and the Enter event on the form would go to this button.
What you should do is to catch the Enter key at form level. Add this code to the form:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if ((this.ActiveControl == myTextBox) && (keyData == Keys.Return))
{
//do something
return true;
}
else
{
return base.ProcessCmdKey(ref msg, keyData);
}
}

Categories

Resources