I have a from that has a text box and I'm trying to determine if Ctrl-R is pressed within this text box. I can detect the keys separately using:
private void CheckKeys(object sender, System.Windows.Forms.KeyPressEventArgs e)
{
if(e.KeyChar == (char)Keys.R)
{
// ...
}
if ((Control.ModifierKeys & Keys.Control) == Keys.Control)
{
// ...
}
}
How do I determine if they pressed at the same time?
If possible, change your event to KeyDown/KeyUp, everything will be easier. (Note that this solution is not always applicable)
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyData == (Keys.Control | Keys.R))
{
}
}
See Mitch's answer on how to construct the bit flag logic correctly, as long as he undeletes it. Here's something that will work, if he doesn't decide to. You basically need to check if both conditions are true at the same time:
bool isRKeyPressed = e.KeyChar == (char)Keys.R;
bool isControlKeyPressed = (Control.ModifierKeys & Keys.Control) == Keys.Control;
if (isRKeyPressed && isControlKeyPressed)
{
// Both ...
}
else if (isRKeyPressed)
{
// R key only ...
}
else if (isControlKeyPressed)
{
// CTRL key only ...
}
else
{
// None of these...
}
Throw away any of these checks that you don't care about.
Also, you might want out check out this alternative approach:
http://www.codeguru.com/columns/experts/article.php/c4639
They override the ProcessCmdKey method on their form (possibly on individual controls?):
http://msdn.microsoft.com/en-us/library/system.windows.forms.control.processcmdkey.aspx
Related
I have a small projet in which I want several buttons to behave differently when Clicked or Ctrl+Clicked. To achieve that, each of those buttons has this kind of function attached to their Click() event :
private void Button1_Click(object sender, EventArgs e)
{
int value = 10 //default value
bool boool = false;
if (ModifierKeys == Keys.Control)
{
using (var form = new NUP_Popup(0, value, value, "maximum ?"))
{ //creates a simple window that allows user to change the value of 'value'
form.ShowDialog();
if (form.DialogResult == DialogResult.OK)
{
value = form.retVal;
boool = true;
}
else return;
}
}
//do stuff here, either with default or user value
}
Now, Clicking or Ctrl+Clicking behaves as intended with this function. My problem is that this behaviour doesn't apply when my buttons are activated using the Enter key : Enter key alone triggers the "normal" behaviour but Ctrl+Enter does nothing (button is not activated).
I already have overriden the ProcessDialogKey() function to close the window when Escape is pressed, so I thought I could use it to make Enter key presses trigger the Click() event function :
protected override bool ProcessDialogKey(Keys keyData) //Allows quit when Esc is pressed
{
if (Form.ModifierKeys == Keys.None && keyData == Keys.Escape)
{
this.Close();
return true;
}
if (keyData == Keys.Return)
{
this.OnClick(new EventArgs());
}
return base.ProcessDialogKey(keyData);
}
And that's where I'm stuck. Of course this doesn't do anything but I don't really have an idea of what to type inside my second condition to make it work.
Maybe I'm using the wrong approach ? Can someone point me in the right direction to do it ?
Assuming you placed a Label with ID Label1 and a button with ID Button1, following will do:
private void button1_Click(object sender, EventArgs e)
{
label1.Text = "Button Clicked";
if (Control.ModifierKeys == Keys.Control) label1.Text += " with Ctrl";
}
private void button1_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == '\n') button1_Click(sender, new EventArgs());
}
to your solution, simply add a KeyPress event to your Button1 and apply following code inside the keypress event Button1_KeyPress:
if (e.KeyChar == '\n') Button1_Click(sender, new EventArgs());
Okay, so I finally found a working solution by adding this to my overriden ProcessDialogKey() method :
if (keyData == (Keys.Enter | Keys.Control))
{
(this.ActiveControl as Button).PerformClick();
}
I don't know if it qualifies as "clean" code, but it has the merit of fulfilling my 2 requirements : making Ctrl+Enter function as Ctrl+Click without having to declare 2 methods per Button.
I found a solution that enables you to either click Enter or Ctrl+Enter:
private void txtIP_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == '\n' || e.KeyChar == '\r') btnStart_Click(sender, new EventArgs());
}
I have a MaskedTextBox that formats text to look like (###) ###-####
After entering the first 3 digits, they like to press "TAB" to the next set. Unfortunately by pressing TAB, they are in the next field.
So my boss asked me to modify the application so that the users remain in the same field but the cursor is in the next group.
private void maskedTextBoxHomePhone_KeyPress(object sender, KeyPressEventArgs e)
{
MaskedTextBox mtb = (MaskedTextBox)sender;
if (e.KeyChar == (char)Keys.Tab)
{
if (mtb.TextLength == 3)
{
mtb.SelectionStart = 4;
}
}
}
I've also tried
private void maskedTextBoxHomePhone_KeyDown(object sender, KeyEventArgs e)
{
MaskedTextBox mtb = (MaskedTextBox)sender;
if (e.KeyCode == Keys.Tab)
{
if (mtb.TextLength == 3)
{
mtb.SelectionStart = 4;
}
}
}
Tabs have a special meaning, that will cause the focus to change, so the event handler won't get called.
You could work around this by using the Leave event of a text box and counting the textlength that you have stored in some local variable:
private void maskedTextBoxHomePhone_Leave(object sender, EventArgs e)
{
if (_mtbTextLength == 3) { //change selection start and goes back to masked text box }
}
Anyway, actually I would try to convince my boss otherwise. Do you
really need this? Tabs are always used to change fields, you can get
your users confused.
Another option would be to change the Tab behaviour by overriding the ProcessCmdKey:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == Keys.Tab)
{
//Do something
}
}
I am creating a simple practice program where if I am going to press "Enter" the first message that will be displayed is "Enter a word", then if I press again "Enter", the second message will be "Hello." I am really new to KeyDown events and I'm just starting to learn it bit by bit. Any help is appreciated.
Here's the code that I've tried so far. But the output is not what I wanted to be.
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
if (textBox1.Text == "1")
{
MessageBox.Show("Enter a word");
}
else if (textBox1.Text == "1")
{
MessageBox.Show("Hello");
}
}
}
You would really need to save your state before you press Enter key second time. In the following implementation I saved the state in boolean "State" variable, as task only requires there to be 2 possible states.
private bool State = false;
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
if (State == false)
{
MessageBox.Show("Enter a word");
State = true;
}
else if (State == true)
{
MessageBox.Show("Hello");
State = false;
}
}
}
If you had more states, you could use different variable like string or use private method which performs some work to determine next state.
Your two if clauses are the same (textBox1.Text == "1"). You shouldn't use a TextBox to track your state, anyway. Try creating a private int time = 1; field in your form source code and check it instead. Don't forget to increase it by 1 every time you find out you pressed "Enter".
I have a TextBox in a C#/XAML desktop app and I want to detect the Shift+Enter command. How can I do this?
So far I have only been able to find information on commands like Ctrl+A, etc.
ModifierKeys.Shift allows you to identify key pressed combinations which includes Shift:
private void HandleKeyDownEvent(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter && (Keyboard.Modifiers == ModifierKeys.Shift))
{
// Handle..
}
}
Another option is Keyboard.IsKeyDown static method (see Shoe's answer).
if (Keyboard.Modifiers == ModifierKeys.Shift && Keyboard.IsKeyDown(Key.Enter))
{
MessageBox.Show("test");
}
A good example can be found here.
public void TextBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if ((Control.ModifierKeys & Keys.Shift) == Keys.Shift)
{
MessageBox.Show("Pressed " + Keys.Shift);
}
}
In my application I have:
private bool _clear = true;
This boolean is used to see if a textbox should be cleared or not when user enters a new text into it (by pressing on a TreeNode in a TreeView).
Then I have these two events for my form:
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.Modifiers == Keys.Control)
{
_clear = false;
}
}
private void Form1_KeyUp(object sender, KeyEventArgs e)
{
if (e.Modifiers == Keys.Control)
{
_clear = true;
}
}
I want it somehow when user is holding the CTRL key, clear be FALSE and when CTRL is released, clear goes back to TRUE.
Obviously the code I wrote here, does not work! what can be wrong and/or is there a better way?
It's a simple fix, as when you release the key, the KeyUp event does not receive any info of the key released itself, so just set the property to true:
private void Form1_KeyUp(object sender, KeyEventArgs e)
{
_clear = true;
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.Modifiers == Keys.Control)
{
_clear = false;
}
}
If you want to see it work in real time, add a label to your form and add this under each setting of the '_clear' variable:
label1.Text = _clear.ToString();
Per your comment, change the second code block to:
if (e.KeyData.ToString() == "ControlKey, Control")
{
_clear = false;
}
else if(other shortcut conditionals go here or on other else if's)
{
_clear = true;
}
The only time this conditional will hold true is when control is held by itself. The else case is there for the purpose of setting _clear to true when you press ctrl followed by another key, due to the fact that as soon as you press control, it will fire the KeyDown event.
Based on this change, as long as you take care of the key presses following that if statement, (such as else if()'s), you will not need to set anything in the KeyUp event.
See my answer here to the intricacies of keys and their properties if you want some more in-depth info.
Edit #3 :
As long as you set the _clear to true on the first line in each conditional, you should be able to avoid the problem you are facing in your comment:
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyData.ToString() == "ControlKey, Control")
{
_clear = false;
}
else if(e.KeyData.ToString() == "O, Control")
{
_clear = true;
//Do other stuff here, such as opening a file dialog
}
}
It is much easier if you do this the other way around. Check if the CTRL key is down in the treeview's event. Something like this:
private void treeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e) {
if ((Control.ModifierKeys & Keys.Control) == Keys.Control) {
// Control key is down, do something...
}
}
You need to change the KeyPreview property of your form to True.