During the initial development of my .NET application (using WinForms), I had to go in and create common editing shortcuts such as CTRL-A, CTRL-C, and CTRL-V because they are not enabled by default. Now that my application has grown to quite a few text boxes, I am trying to figure out how to refactor the following code. Can someone help please?
private void textBox1_results_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control && e.KeyCode == Keys.A)
{
textBox1_results.SelectAll();
e.SuppressKeyPress = true;
}
if (e.Control && e.KeyCode == Keys.C)
{
textBox1_results.Copy();
e.SuppressKeyPress = true;
}
if (e.Control && e.KeyCode == Keys.V)
{
textBox1_results.Text = Clipboard.GetText();
e.SuppressKeyPress = true;
}
}
If you have a BaseForm that all your forms inherit from try moving the above code to it and call it from all the text box event handlers.
public partial class Form2 : Form1
{
public Form2()
{
InitializeComponent();
}
private void Form2_Load(object sender, EventArgs e)
{
}
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
base.TextKeyDown(sender, e);
}
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public void TextKeyDown(object sender, KeyEventArgs e)
{
if (e.Control && e.KeyCode == Keys.A)
{
((TextBox) sender).SelectAll();
e.SuppressKeyPress = true;
}
if (e.Control && e.KeyCode == Keys.C)
{
((TextBox)sender).Copy();
e.SuppressKeyPress = true;
}
if (e.Control && e.KeyCode == Keys.V)
{
((TextBox)sender).Text = Clipboard.GetText();
e.SuppressKeyPress = true;
}
}
}
Well, there are two main approaches to this.
Create your own text box control by inheriting from System.Windows.Forms.TextBox and adding your own implementation of the KeyDown (still calling base.KeyDown()) with the short cuts enabled
Create a helper class that you call in each form's Load even that iterates through all controls on the form and adds a handler to your code.
Option 1 would be something like;
public class ShortcutTextBox : TextBox
{
protected override void OnKeyDown(KeyEventArgs e)
{
if (e.Control && e.KeyCode == Keys.A)
{
SelectAll();
e.SuppressKeyPress = true;
}
else if (e.Control && e.KeyCode == Keys.C)
{
Copy();
e.SuppressKeyPress = true;
}
else if (e.Control && e.KeyCode == Keys.V)
{
Text = Clipboard.GetText();
e.SuppressKeyPress = true;
}
base.OnKeyDown(e);
}
}
Though this comes with the caveat that you'd need to replace every instance of TextBox with ShortcutTextBox.
Option two still involves refactoring but it's a once per form option. Create a helper class like the following;
public abstract class ControlUtilities
{
public static void AddTextBoxShortcuts(Control.ControlCollection controls)
{
foreach (Control c in controls)
{
if (c is TextBox)
{
TextBox txt = (TextBox)c;
txt.KeyDown += textBox_KeyDown;
}
else if (c.Controls != null && c.Controls.Count > 0)
{
// recursively look for text boxes
AddTextBoxShortcuts(c.Controls);
}
}
}
private static void textBox_KeyDown(object sender, KeyEventArgs e)
{
TextBox txt = (TextBox)sender;
if (e.Control && e.KeyCode == Keys.A)
{
txt.SelectAll();
e.SuppressKeyPress = true;
}
else if (e.Control && e.KeyCode == Keys.C)
{
txt.Copy();
e.SuppressKeyPress = true;
}
else if (e.Control && e.KeyCode == Keys.V)
{
txt.Text = Clipboard.GetText();
e.SuppressKeyPress = true;
}
}
}
and call it in your form's Load event like;
private void Form1_Load(object sender, EventArgs e)
{
ControlUtilities.AddTextBoxShortcuts(this.Controls);
}
Probably something like this:
private static void Shortcut_KeyDown(object sender, KeyEventArgs e)
{
var textBox = (TextBox)sender;
if (e.Control && e.KeyCode == Keys.A)
{
textBox.SelectAll();
e.SuppressKeyPress = true;
}
if (e.Control && e.KeyCode == Keys.C)
{
textBox.Copy();
e.SuppressKeyPress = true;
}
if (e.Control && e.KeyCode == Keys.V)
{
textBox.Text = Clipboard.GetText();
e.SuppressKeyPress = true;
}
}
And apply it:
textBox1.KeyDown += Shortcut_KeyDown;
textBox2.KeyDown += Shortcut_KeyDown;
// etc...
Although I'm not sure why you would need to write this at all - this behavior is standard to Winforms TextBox as far as I know.
Related
I have a textbox with a OnKeyPress event. In this textbox I wish to input only numbers, and for some specific letters like t or m, I would want to execute a code without that letter being typed in the textbox. Small sample of what I am trying to do:
//OnKeyPressed:
void TextBox1KeyDown(object sender, KeyEventArgs e)
{
if(e.KeyCode == Keys.T || e.KeyCode == Keys.M) Button1Click(this, EventArgs.Empty);
}
This unfortunately does not prevent the input of the letter..
Set the SuppressKeyPress property from KeyEventArgs to true, like below:
private void TextBox1KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.T || e.KeyCode == Keys.M)
{
e.SuppressKeyPress = true;
Button1Click(this, EventArgs.Empty);
}
}
You could always run the TryParse on the keyDown event so as to validate as the data gets entered. It saves the user an additional UI interaction.
private void TextBox1KeyDown(object sender, KeyEventArgs e)
{
int i;
string s = string.Empty;
s += (char)e.KeyValue;
if (!(int.TryParse(s, out i)))
{
e.SuppressKeyPress = true;
}
else if(e.KeyCode == Keys.T || e.KeyCode == Keys.M)
{
e.SuppressKeyPress = true;
Button1Click(this, EventArgs.Empty);
}
}
I want to detect if the user clicked few keys together (example: ctrl+c , alt +F4 etc..)
How can I do it??
I googled it but I got confused... :/
I tried this:
if (Control.ModifierKeys == (Keys.C) &&Control.ModifierKeys == Keys.Control)
{
MessageBox.Show("Test");
}
But it didn't worked,any ideas?
I just understood what I was should to do:
I was needed to type this:
void detectCopy(object sender, KeyEventArgs e)
{
if (Control.ModifierKeys == Keys.Control && e.KeyCode == Keys.C)
{
//work here
}
}
and this on the constructor:
public Form1()
{
InitializeComponent();
this.KeyDown += new KeyEventHandler(detectCopy);
}
Your if statement is incorrent use this:
if (e.KeyCode == Keys.C && Control.ModifierKeys == Keys.Control)
{
}
On the constructor do this:
public Form1()
{
InitializeComponent();
this.KeyDown += new KeyEventHandler(detectCopy);
KeyPreview = true;
}
And in the code do this:
void detectCopy(object sender, KeyEventArgs e)
{
if (Control.ModifierKeys == Keys.Control && e.KeyCode == Keys.C)
{
//work here
}
}
In Windows Form, the Propertie KeyPreview need be true to KeyDown Event works!!!
I have a gridview in my C# windows application ... It allowed to be edited and I want a special cell (named "Price") to just allow number on keypress ... I use the code below for texboxes to just allow numbers ... in which event of grid view should I write this code?
private void txtJustNumber_KeyPress(object sender, KeyPressEventArgs e)
{
if (!char.IsDigit((char)(e.KeyChar)) &&
e.KeyChar != ((char)(Keys.Enter)) &&
(e.KeyChar != (char)(Keys.Delete) || e.KeyChar == Char.Parse(".")) &&
e.KeyChar != (char)(Keys.Back))
{
e.Handled = true;
}
}
You can use CellValidating event of DataGridView.
private void dataGridView1_CellValidating(object sender,
DataGridViewCellValidatingEventArgs e)
{
// Validate the Price entry.
if (dataGridView1.Columns[e.ColumnIndex].Name == "Price")
{
}
}
thx guys ... I used below code and my problem resolved ...
public Form1()
{
InitializeComponent();
MyDataGridViewInitializationMethod();
}
private void MyDataGridViewInitializationMethod()
{
gvFactorItems.EditingControlShowing +=
new DataGridViewEditingControlShowingEventHandler(gvFactorItems_EditingControlShowing);
}
private void gvFactorItems_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
e.Control.KeyPress += new KeyPressEventHandler(Control_KeyPress); ;
}
private void Control_KeyPress(object sender, KeyPressEventArgs e)
{
if (!char.IsDigit((char)(e.KeyChar)) &&
e.KeyChar != ((char)(Keys.Enter)) &&
(e.KeyChar != (char)(Keys.Delete) || e.KeyChar == Char.Parse(".")) &&
e.KeyChar != (char)(Keys.Back))
{
e.Handled = true;
}
}
I think you should take a look at this, it will help :-
DataGridView keydown event not working in C#
I am working on a CustomControl and I want to register ModifierKeys in this control. I have already set the KeyPerview to True in the Form which this control is being added to.
Now I have a Boolean named _ctrl and I want this boolean to be true when the Control key is being held down and it should be false when Control key is being released.
I tried to achive this with the conde belowe in my CustomControl but no success!
private bool _ctrl = false;
private void MyCustomControl_KeyDown(object sender, KeyEventArgs e)
{
if(e.KeyCode == Keys.Control)
{
_ctrl = true;
}
}
private void MyCustomControl_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Control)
{
_ctrl = false;
}
}
Any tips/soloution will be appriciated!
UPDATE
Ok, I decided to do the key down and up event in the form itself:
private void MainForm_KeyDown(object sender, KeyEventArgs e)
{
if (e.Modifiers == Keys.Control)
{
projectBrowser.ControlKeyIsDown = true; //bool in MyCustomControl
MessageBox.Show("CTRL is PRESSED");
}
}
private void MainForm_KeyUp(object sender, KeyEventArgs e)
{
if (e.Modifiers == Keys.Control)
{
projectBrowser.ControlKeyIsDown = false; //bool in MyCustomControl
MessageBox.Show("CTRL is DEPRESSED");
}
}
Now, The KeyDown event detects the control key and messagebox is being shown. But the KeyUp event does not work and it doesn't show the messagebox. What could be wrong?
It seems that the key up gets detected if I change the KeyUpevent like this:
private void MainForm_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.LControlKey || e.KeyCode == Keys.RControlKey || e.KeyCode == Keys.ControlKey || e.KeyCode == Keys.Control)
{
projectBrowser.ControlKeyIsDown = false;
e.Handled = true;
}
}
You can try calling the Control.ModifierKeys property:
protected override void OnKeyDown(KeyEventArgs e) {
if (Control.ModifierKeys == Keys.Control) {
MessageBox.Show("I am pressing control.");
}
base.OnKeyDown(e);
}
If you throw up a MessageBox on the KeyDown event, the KeyUp event won't get called.
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.