I need to disable changing focus with arrows on form. Is there an easy way how to do it?
Thank you
Something along the lines of:
private void Form1_Load(object sender, EventArgs e)
{
foreach (Control control in this.Controls)
{
control.PreviewKeyDown += new PreviewKeyDownEventHandler(control_PreviewKeyDown);
}
}
void control_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
if (e.KeyCode == Keys.Up || e.KeyCode == Keys.Down || e.KeyCode == Keys.Left || e.KeyCode == Keys.Right)
{
e.IsInputKey = true;
}
}
I've ended up with the code below which set the feature to EVERY control on form:
(The code is based on the one from andynormancx)
private void Form1_Load(object sender, EventArgs e)
{
SetFeatureToAllControls(this.Controls);
}
private void SetFeatureToAllControls(Control.ControlCollection cc)
{
if (cc != null)
{
foreach (Control control in cc)
{
control.PreviewKeyDown += new PreviewKeyDownEventHandler(control_PreviewKeyDown);
SetFeatureToAllControls(control.Controls);
}
}
}
void control_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
if (e.KeyCode == Keys.Up || e.KeyCode == Keys.Down || e.KeyCode == Keys.Left || e.KeyCode == Keys.Right)
{
e.IsInputKey = true;
}
}
I tried this aproach, where the form handles the preview event once. It generates less code than the other options.
Just add this method to the PreviewKeyDown event of your form, and set the KeyPreview property to true.
private void form1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
switch (e.KeyCode)
{
case Keys.Up:
case Keys.Down:
case Keys.Left:
case Keys.Right:
e.IsInputKey = true;
break;
default:
break;
}
}
You should set KeyPreview to true on the form. Handle the KeyDown/KeyUp/KeyPress event and set the e.Handled in the eventhandler to true for the keys you want to be ignored.
Related
I have set KeyPreview property of the form to true in order to call keyboard events of the form before control events.
Both the form and the control in the form have KeyDown event like:
form:
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control && (e.KeyCode == Keys.Enter || e.KeyCode == Keys.Return)) {
MessageBox.Show("Control + Enter (Form)");
}
}
control:
private void TextBox1_KeyDown(object sender, KeyEventArgs e)
{
if (!e.Control && (e.KeyCode == Keys.Enter || e.KeyCode == Keys.Return)) {
MessageBox.Show("Control + Enter (TextBox)");
}
}
As you see the difference between these two parts of code is that in the form event code I need to call the KeyDown event when the user presses CTRL and Enter keys at the same time,
In the TextBox event code, I need to call the event when the user presses Enter key without holding CTRL-key.
The problem is that when I press Ctrl and Enter keys at the same time both of the above events will call.
How to prevent call both events?
I suggest you use the textBox1_KeyUp event. You can refer to the following code. My test was successful.
public Form1()
{
InitializeComponent();
this.KeyPreview = true;
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control && (e.KeyCode == Keys.Enter || e.KeyCode == Keys.Return))
{
MessageBox.Show("Control + Enter (Form)");
}
}
private void textBox1_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Control)
{
e.Handled = true;
}
else if (e.KeyCode == Keys.Enter)
{
MessageBox.Show("Control + Enter (TextBox)");
}
}
Use the ProcessCmdKey and like this.
protected override bool ProcessCmdKey(ref Message msg, System.Windows.Forms.Keys keyData)
{
int WM_ALRT_DOWN = 0x0104;
int WM_KEYDOWN = 0x0100;
if (msg.Msg == WM_ALRT_DOWN && (int)msg.WParam == (int)Keys.F4) //Alt + F4
{
return true; // The key is manually processed
}
if (msg.Msg == WM_KEYDOWN && (int)msg.WParam == (int)Keys.Escape) //Esc
{
return true; // The key is manually processed
}
if (msg.Msg == WM_KEYDOWN && (int)msg.WParam == (int)Keys.Space) //Space
{
return true; // The key is manually processed
}
}
I have this code in a windows form that calls a function that calculates a number:
private void KeyDown_Accion_Teclas(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Add || e.KeyCode == Keys.Oemplus)
{
cmdAlta_Click(sender, e);
}
}
But in any textbox that is focused or selected, when I press the + button to call the function, its writes the symbol of +.
I only want to call the function but not to write the + symbol. Nothing I've tried has worked.
Any ideas?
private void KeyDown_Accion_Teclas(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Add || e.KeyCode == Keys.Oemplus)
{
cmdAlta_Click(sender, e);
e.SuppressKeyPress = true;
}
}
Or maybe:
private void KeyDown_Accion_Teclas(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Add || e.KeyCode == Keys.Oemplus)
{
e.SuppressKeyPress = true;
cmdAlta_Click(sender, null);
}
}
I am trying to disable people from deleting a textbox in a richtextbox. The project is using windows form.
Here is the code I have:
private void Form1_Load(object sender, EventArgs e)
{
richTextBox1.KeyPress += new KeyPressEventHandler(richTextBox1_KeyPress);
}
void richTextBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == (char)8)
{
e.Handled = true;
MessageBox.Show("Try not to delete... write freely and openly");
//The msgbox shows, but the delete still happens within the form.
}
}
Does not show messagebox and does not stop the delete:
private void Form1_Load(object sender, EventArgs e)
{
richTextBox1.KeyDown += new KeyEventHandler(richTextBox1_KeyDown);
}
private void richTextBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Delete)
{
e.Handled = true;
MessageBox.Show("Delete Pressed");
// Does not show message box...
}
}
Per the MSDN documentation on KeyPressEventArgs.KeyChar, you cannot get or set the DELETE key using that event. You will need to use the KeyEventArgs.KeyCode instead, subscribing to the KeyDown and KeyUp events.
My solution:
void richTextBox1_TextChanged(object sender, EventArgs e) {
richTextBox1.SelectAll();
richTextBox1.SelectionProtected = true;
richTextBox1.Select(richTextBox1.Text.Length, 0);
}
Side note: yes, this will flicker. Proof of concept only. To avoid the flicker, see How to append text to RichTextBox without scrolling and losing selection?
Instead Of KeyPress event use KeyDown In RichText Box.
try this to prevent from deleting text in RichText Box
private void richTextBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyValue == 46)
e.Handled = true;
}
If you want to disallow both delete and backspace You Can Change KeyDown Event as follows
private void richTextBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyValue == 8 || e.KeyValue == 46)
e.Handled = true;
}
You must add Back key to prevent delete :
private void richTextBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Back || e.KeyCode == Keys.Delete)
{
e.Handled = true;
MessageBox.Show("Delete Pressed");
// Does not show message box...
}
}
Edit:
Non-selectable RichTextBox :
public class ViewOnlyRichTextBox : System.Windows.Forms.RichTextBox {
// constants for the message sending
const int WM_SETFOCUS = 0x0007;
const int WM_KILLFOCUS = 0x0008;
protected override void WndProc(ref Message m) {
if(m.Msg == WM_SETFOCUS) m.Msg = WM_KILLFOCUS;
base.WndProc (ref m);
}
}
My solution is some kind of the combination of SerkanOzvatan's and LarsTech's answers. Here is the code:
private void richTextBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Back || e.KeyCode == Keys.Delete)
{
e.Handled = true;
MessageBox.Show("Try not to delete... write freely and openly");
// Does not show message box...
}
}
private void richTextBox1_SelectionChanged(object sender, EventArgs e)
{
richTextBox1.SelectionProtected = richTextBox1.SelectionLength > 0;
}
It works great :)
And here is another solution of my own which also works great, especially if you want to do with a TextBox (not a RichTextBox), it doesn't have a SelectionProtected, and this is used OK for both TextBox and RichTextBox (just change the class name in the following code accordingly):
public class WritableRichTextBox : RichTextBox
{
protected override bool ProcessKeyMessage(ref Message m)
{
int virtualKey = m.WParam.ToInt32();
if (SelectionLength > 0 || virtualKey == 0x08 || virtualKey == 0x2e)
{
if (virtualKey != 0x25 && virtualKey != 0x26 && virtualKey != 0x27 && virtualKey != 0x28)
return true;
}
return base.ProcessKeyMessage(ref m);
}
}
Is there any way to customize datagridview column to accept only numeric values. Also if user press any other character other than numbers nothing must type on the current cell.Is there any way to solve this problem
private void gvAppSummary_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
if (gvAppSummary.CurrentCell.ColumnIndex == intRate)
{
e.Control.KeyPress += new KeyPressEventHandler(gvAppSummary_KeyPress);
}
}
private void gvAppSummary_KeyPress(object sender, KeyPressEventArgs e)
{
if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar) && e.KeyChar != '.')
{
e.Handled = true;
}
}
With the previous solutions, every time you enter the EditingControlShowing event, you will add the KeyPressEvent in «the list» of events to perform on KeyPress. This can easily be checked by setting a breakpoint in the KeyPress event.
Better solution would be:
private static KeyPressEventHandler NumericCheckHandler = new KeyPressEventHandler(NumericCheck);
private void dataGrid_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
if (dataGrid.CurrentCell.ColumnIndex == numericColumn.Index)
{
e.Control.KeyPress -= NumericCheckHandler;
e.Control.KeyPress += NumericCheckHandler;
}
}
And the Event NumericCheck:
private static void NumericCheck(object sender, KeyPressEventArgs e)
{
DataGridViewTextBoxEditingControl s = sender as DataGridViewTextBoxEditingControl;
if (s != null && (e.KeyChar == '.' || e.KeyChar == ','))
{
e.KeyChar = System.Threading.Thread.CurrentThread.CurrentCulture.NumberFormat.NumberDecimalSeparator[0];
e.Handled = s.Text.Contains(e.KeyChar);
}
else
e.Handled = !char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar);
}
Use datagridview Editingcontrolshowing .. Basicly like this
private void dataGridView1_EditingControlShowing(object sender,
DataGridViewEditingControlShowingEventArgs e)
{
String sCellName = dataGridView1.Columns(e.ColumnIndex).Name;
If (UCase(sCellName) == "QUANTITY") //----change with yours
{
e.Control.KeyPress += new KeyPressEventHandler(CheckKey);
}
}
private void CheckKey(object sender, KeyPressEventArgs e)
{
if (!char.IsControl(e.KeyChar)
&& !char.IsDigit(e.KeyChar)
&& e.KeyChar != '.')
{
e.Handled = true;
}
}
You can improve this CheckKey ...
e.Control.KeyPress -= new KeyPressEventHandler(Column18qty_KeyPress);
if (dgvProduct.CurrentCell.ColumnIndex == 18) //dgvtxtQty
{
TextBox tb = e.Control as TextBox;
if (tb != null)
{
tb.KeyPress += new KeyPressEventHandler(Column18qty_KeyPress);
}
}
private void Column18qty_KeyPress(object sender, KeyPressEventArgs e)
{
if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar)
&& e.KeyChar != '.')
{
e.Handled = true;
}
// only allow one decimal point
if (e.KeyChar == '.'
&& (sender as TextBox).Text.IndexOf('.') > -1)
{
e.Handled = true;
}
}
I need to have a text box on which events of Delete and Backspace works.Is it possible to have such a text box in C#,or restrict the behavior of text box in such a way. Other keys do not work.
Use TextBox.KeyPress event:
private void textBox1_KeyPress(object sender, System.Windows.Forms.KeyEventArgs e)
{
if (e.KeyCode == Keys.Delete || e.KeyCode == Keys.Back)
{
// your stuff
}
e.Handled = true;
}
For winforms you can do it like this:
protected void myTextBox_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
{
e.Handled = !IsValidCharacter(e.KeyChar);
}
private bool IsValidCharacter(Keys c)
{
bool isValid = false;
if (c == Keys.Space)
{
isValid = true;
}
return isValid;
}
If you want delete key works ..
private void textBox1_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{
Keys k = e.KeyCode
If Not (k = Keys.Back Or k = Keys.Delete)
{
e.Handled = True
}
}