I have the following code that has worked twice and then quit working altogether after I modified the underlying form controls. I can't see what's wrong with the code or why changing the underlying controls would matter to the form.
What do I have to do to get ProcessCmdKey to work reliably?
namespace xyz
{
public partial class DaysNHours : Form
{
public DaysNHours()
{
this.KeyPreview = true;
InitializeComponent();
}
// Detect alt-key presses directed to checkboxes and time boxes
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == (Keys.Control | Keys.F))
{
MessageBox.Show("What the Ctrl+f?");
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
}
}
Related
I'm working on a MDI winforms project, I want to user uses F3 shortcut to open a search form in every where in application, so I used following code in my MDI parent form and set the parent form's KeyPreview to true:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == (Keys.F3)) {
//Show search form
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
The shortcut works in MDI parent and child forms, but If I open a form from one of MDI child forms using .ShowDialog() the shortcut doesn't work in last form, in the other word, the shortcut, works in childForm:
//in the parent form
var childForm = new Form1();
childForm.MdiParent = parentForm;
childForm.KeyPreview = true;
childForm.Show();
but doesn't work in grandChildForm form:
//in the child form
var grandChildForm = new Form2();
grandChildForm.KeyPreview = true;
grandChildForm.ShowDialog();
How can I solve the problem, without repeating ProcessCmdKey() method in all forms?
Create a baseForm:
public partial class baseForm : Form
{
public baseForm()
{
InitializeComponent();
}
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == (Keys.F3))
{
//Show search form
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
}
And let all your others forms inherit from it:
public partial class Form1 : baseForm
Then any common functionality you want can be added to baseForm.
I have a form that creates a class. This class processes events that are fired on the form. The problem is I am trying to use the KeyDown event, but it isn't working because there are buttons on the form and they are capturing the KeyDown. I found the solution on another post was to override the ProcessCmdKey. The problem is I don't know how to override a method from inside another class. Can anyone tell me how I can capture all KeyDown events from inside my other class?
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == Keys.Left)
{
MoveLeft(); DrawGame(); DoWhatever();
return true; //for the active control to see the keypress, return false
}
else if (keyData == Keys.Right)
{
MoveRight(); DrawGame(); DoWhatever();
return true; //for the active control to see the keypress, return false
}
else if (keyData == Keys.Up)
{
MoveUp(); DrawGame(); DoWhatever();
return true; //for the active control to see the keypress, return false
}
else if (keyData == Keys.Down)
{
MoveDown(); DrawGame(); DoWhatever();
return true; //for the active control to see the keypress, return false
}
else
return base.ProcessCmdKey(ref msg, keyData);
}
The easiest way to do this would be to expose the KeyDown from Button on the containing form.
class MyForm : Form {
Button m_button;
public event KeyEventHandler ButtonKeyDown;
public MyForm() {
m_button = ...;
m_button.KeyDown += delegate (object, e) {
KeyEventHandler saved = ButtonKeyDown;
if (saved != null) {
saved(object, e);
}
};
}
}
Now the calling code can simple hook into the MyForm::ButtonKeyDown event
I'm not sure how you're wiring up the events with your class, but if you set the KeyPreview property of the form to True, you can grab a hold of the event there and then pass it along to your class that is processing the events. So even when the button has the focus, the KeyDown will fire the event on the form.
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
... Invoke your class
}
I have a windows form, i need when user press Enter set focus to next control.
Any idea how to achive this
(without using Key Press events)
You can catch the KeyPreview of your form. Set KeyPreview to true in the constructor and then you can use this:
protected override bool ProcessKeyPreview(ref Message m)
{
if (m.Msg == 0x0100 && (int)m.WParam == 13)
{
this.ProcessTabKey(true);
}
return base.ProcessKeyPreview(ref m);
}
You can use ProcessCmdKey checking if keyData contains the Enter Key then using the SelectNextControl Method to set your focus.
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData.HasFlag(Keys.Enter))
{
SelectNextControl(ActiveControl,true,true,true,true);
return true; //Stops the beeping
}
return base.ProcessCmdKey(ref msg, keyData);
}
If you dont want to use key press events you will have to override ProcessCmdKey
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == Keys.Return)
{
MessageBox.Show("You pressed the Enter key");
}
return base.ProcessCmdKey(ref msg, keyData);
}
I want to move some graphics in a winfor application. To do this I need to know if any of the cursor keys are being pressed. I tried to override ProcessCmdKey but no success.
Any tips/ideas how to implement this?
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
switch (keyData)
{
case Keys.Left:
// while Left is down
// call this method repeadetdly
buttonGoLeft();
// when key is up stop calling this method
// and check for other keys
return true;
//Other cases
}
}
this works!
using System.Windows.Forms;
namespace WindowsFormsApplication5
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
KeyPreview = true;
}
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
switch (keyData)
{
case Keys.Left:
// while Left is down
// call this method repeadetdly
MessageBox.Show("its left", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information);
// when key is up stop calling this method
// and check for other keys
return true;
default:
return false;
}
}
}
}
I use DataGridView, and in some places I add control to it (e.g. textbox, combobox)
dataGridView1.Controls.Add(comboBox);
comboBox.Focus();
The problem is that using this control, and than commiting choice by using ENTER cause the DataGridView to "handle" the key -> after clickng enter instead of choosing sth from combobox, the selection in datagridview changes( moves to next cell).
I use sth like :
public class MyDataGridView:DataGridView
{
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if(keyData == Keys.Enter)
{
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
}
But it cause that datagridview and combobox doesn't answer to ENTER, and other keys...
Additional infromation: I must use ComboBox class, instead of DataGridViewCombobox. Can anyone help me how to handle ENTER in my comobox?
Try:
if((keyData == Keys.Enter) && (MyComboBox.Focused))
so DataGridView responds to ENTER except when your control is focused.
I am not sure the following code fits your situation, but maybe you could try something like:
public class MyDataGridView:DataGridView
{
public ComboBox MyComboBox { get; set; } //in case you had no other way to refer to it
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if((keyData == Keys.Enter) && (MyComboBox.Focused))
{
//commit choice logic
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
}
and from your form, if it needs, set the reference to your ComboBox:
dataGridView1.Controls.Add(comboBox);
dataGridView1.MyComboBox = comboBox;
comboBox.Focus();