C# Prevent Hotkeys while TextBox focus - c#

I have a program containing multiple C# Forms TextBoxes. I've set up Hotkeys for the entire form activating certain functions. My problem is that my Hotkeys have been set onto the Form KeyDown event and they activate if I write something on a TextBox.
Example: One Hotkey might be I. Everytime I write the letter onto a textbox the Hotkey activates.
Alterior solutions and problems: I've thought about putting a Key in front of the Hotkey like CTRL+Hotkey, but these also present problems as CTRL+C is Windows Copy command etc. SHIFT is an UpperKey button.
Question: Can I prevent Hotkeys from activating when I am writing onto a TextBox without having to go through all of them in the form?
EDIT: Some code as requested. The button codes come from a stored XML file or the Hotkeys Form+Class (separate) where I've set up a window for them.
public Hotkeys hotkeysForm = new Hotkeys();
void Form1_KeyDown(object sender, KeyEventArgs e)
{
toggleInformation = hotkeysForm.toggleInformation;
if (e.Control && e.KeyCode == toggleInformation)
{
showInfo(true);
}
else if (e.KeyCode == toggleInformation)
{
if (!isInfoActive)
showInfo();
else
hideInfo();
}
}

You can disable hotkeys while texbox is an active control. Add the Enter and Leave events for all textboxes:
private void textBox_Enter(object sender, EventArgs e)
{
KeyPreview = false;
}
private void textBox_Leave(object sender, EventArgs e)
{
KeyPreview = true;
}

You should try this hack, if it could solve your problem,
Create a Extented TextBox and use it in your code. you can handle whether to write the pressed key in textbox or not in hotkeyPressed check.
public class ETextBox : System.Windows.Forms.TextBox
{
protected override void OnKeyDown(System.Windows.Forms.KeyEventArgs e)
{
if (hotKeyPressed) // this is the condition when you don't want to write in text.
{
//Do whatever you want to do in this case.
}
else
{
base.OnKeyDown(e);
}
}
}

Related

Windows form only executs when I press the buttons with the mouse

I m working at an uni project and I encountered a problem.(I m also a beginner with C#).
I created a windows form menu and I have to choose options via keyboard. But my program won't let me choose unless i clicked on the option prior. (I have to click the option then press the key, otherwise I can even spam the key and nothing will happen).
private void button1_KeyDown(object sender, KeyEventArgs e)
{
if( e.KeyCode==Keys.D1 || e.KeyCode==Keys.NumPad1)
{
SidePanel.Height = button1.Height;
SidePanel.Top = button1.Top;
firstCustomControl1.BringToFront();
}
}
Here's a code snippet of how i choose an option based on the number.
Thank you :)
Firstly Set "KeyPreview" Option of your form on which you tend to perform action to true, it is false by default. It needs to be true to perform any function based on any keyboard event.
Secondly add Keydown event on same form.
private void YourForm_KeyDown(object sender, KeyEventArgs e)
{
YourCodeHere();
}
don't use the Keydown event on your Button!
Select the Form in the designer and add Keydown Event for entire Form.
Add Key Down Event on Form 1
then add your Code to the following auto generated Method
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
YourCodeHere();
}

Put focus back on previously focused control on a button click event C# winforms

I have made a custom Number Keypad control that I want to place in my winform application. All of the buttons have an OnClick event to send a value to the focused textbox in my form where I have placed my custom control. Like this:
private void btnNum1_Click(object sender, EventArgs e)
{
if (focusedCtrl != null && focusedCtrl is TextBox)
{
focusedCtrl.Focus();
SendKeys.Send("1");
}
}
focusedCtrl is supposed to be set on the MouseDown event of the button like this:
private void btnNum1_MouseDown(object sender, EventArgs e)
{
focusedCtrl = this.ActiveControl;
}
where this.ActiveControl represents the active control on the form.
My problem is that the button always receives the focus before the event detects what the focused control was previously. How can I detect which control had the focus before the button got the focus? Is there another event I should be using? Thanks in advance!
EDIT: Also, I would rather not use the GotFocus event on each textbox in the form to set focusedCtrl since that can be tedious and because I would like to have all the coding of my custom control be in the control itself and not on the form where it is placed. (I will do this, though, if there is no other practical way to do what I am asking)
Your requirement is fairly unwise, you'll want some kind of guarantee that your button isn't going to poke text into inappropriate places. You really do need to have the form co-operate, only it knows what places are appropriate.
But it is not impossible, you can sniff at input events before they are dispatched to the control with the focus. In other words, record which control has the focus before the focusing event is fired. That's possible in Winforms with the IMessageFilter interface.
Add a new class to your project and paste the code shown below. Compile. Drop the new control from the top of the toolbox onto your form, replacing your existing buttons.
using System;
using System.Windows.Forms;
class CalculatorButton : Button, IMessageFilter {
public string Digit { get; set; }
protected override void OnClick(EventArgs e) {
var box = lastFocused as TextBoxBase;
if (box != null) {
box.AppendText(this.Digit);
box.SelectionStart = box.Text.Length;
box.Focus();
}
base.OnClick(e);
}
protected override void OnHandleCreated(EventArgs e) {
if (!this.DesignMode) Application.AddMessageFilter(this);
base.OnHandleCreated(e);
}
protected override void OnHandleDestroyed(EventArgs e) {
Application.RemoveMessageFilter(this);
base.OnHandleDestroyed(e);
}
bool IMessageFilter.PreFilterMessage(ref Message m) {
var focused = this.FindForm().ActiveControl;
if (focused != null && focused.GetType() != this.GetType()) lastFocused = focused;
return false;
}
private Control lastFocused;
}
Control focusedCtrl;
//Enter event handler for all your TextBoxes
private void TextBoxesEnter(object sender, EventArgs e){
focusedCtrl = sender as TextBox;
}
//Click event handler for your btnNum1
private void btnNum1_Click(object sender, EventArgs e)
{
if (focusedCtrl != null){
focusedCtrl.Focus();
SendKeys.Send("1");
}
}
you have an event called lostFocus you can use
button1.LostFocus +=new EventHandler(dataGridView1_LostFocus);
and in the event:
Control lastFocused;
void dataGridView1_LostFocus(object sender, EventArgs e)
{
lastFocused = sender as Control;
}
in that way you can always know what is the Control that was focused previously
now, correct me if i'm wrong, but you do it for the SendKeys.Send("1"); to know which textBox need to receive the number. for that you can use GotFocus event and register only the textBoxs to it.
you can also do what windows is doing and use just one textbox like here:
if it's fits your needs
What about using this with the parameter forward = false?
Control.SelectNextControl Method
You'd probably call it on your "custom Number Keypad control".

How can I make Ctrl+M an event that brings up a form?

I have this code:
private void button5_Click(object sender, EventArgs e)
{
Magnifier20070401.MagnifierForm mf = new Magnifier20070401.MagnifierForm();
mf.Show();
}
It shows the target form correctly. But instead of using a button click, I want to use Ctrl+M to show this form. If the users types Ctrl+M again, I want to close the the form.
How can I do this?
Edit:
This is what i did wich is working :
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control && e.KeyCode.ToString() == "M")
{
Magnifier20070401.MagnifierForm mf = new Magnifier20070401.MagnifierForm();
mf.Show();
}
}
In the constructor of Form1 i added:
this.KeyPreview = true;
So now when i click on Ctrl+M i see the new Form.
What i need now is how to make that if i click again on Ctrl+M it will close the new Form.
Maybe using a flag ?
Edit:
This is what i did now:
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control && e.KeyCode.ToString() == "M")
{
if (mf == null)
{
mf = new Magnifier20070401.MagnifierForm();
mf.Show();
}
else
{
mf.Close();
this.Invalidate();
}
}
}
But even doing this.Invalidate(); i don't see the new Form closed.
But if im using put a breakpoint on the mf.Close(); and step into(F11) i see it close when making continue.
Why it dosen't close without using a breakpoint ?
You can add onKeyPress or onKeyDown
and check if Ctrl+M were pressed
private void OnKeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
if (((Control.ModifierKeys & Keys.Control) == Keys.Control)
&& (e.KeyChar == 'M'|| e.KeyChar == 'm'))
{
mf.Show();
}
You would use the InputBindings object. I think in your case, probably best to put that at the Window level (Window.InputBindings). More information here:
http://msdn.microsoft.com/en-us/library/system.windows.input.inputbinding.aspx
You can solve this in 2 ways.
If you are using a GUI interface, add a MenuItem control on your Menu, and put the Shortcut property to Ctrl+M then double click the MenuItem to edit the code, then call your launchMagnifier() function. If you do NOT want your menu to show, just set the visible properties to false. This keeps the menu hidden if you do not want it, yet still holds the functionality.
If you do not want the MenuItem, you can catch keys that are pressed in your form. So in your frmMain.cs form, add an event to capture keys, then when Ctrl+M is pressed, invoke launchMagnifier()
A few ways to do that.
On your form set the KeyPreview Property to true
Then add an OnKeyPress or OnKeyDown event handler to the form.
In that test for Ctrl-M and show / destroy the form and set handled (e.Handled) to true.
Any other keypress will be passed on to the currently focused control as it hasn't been handled.

How do I get characters from KeyEventArgs and not KeyPressEventArgs?

I know this has been asked hundred of times, but I haven't been able to find a solution that helps me. I'm using a barcode scanner and I want to be able to get the keys that are typed using just the keydown events. For some reason, I can't use both keydown and keypress events (my keypress events won't run).
I need to be able to get the characters, including hyphens, uppercase letters and dots and also need to detect the enter key.
These are my listeners:
form.KeyDown += new KeyEventHandler(Input_KeyDown);
form.KeyPress += new KeyPressEventHandler(Input_KeyPress);
And these are my methods:
private void TimedOut(object sender, EventArgs e)
{
_barcode = "";
}
private void Input_KeyDown(object sender, KeyEventArgs e)
{
_timer.Stop();
_timer.Start();
if (e.KeyData == Keys.Enter)
{
if (!_barcode.Equals(""))
{
this.BarcodeScanned(_barcode, new EventArgs());
}
}
else
{
}
}
private void Input_KeyPress(object sender, KeyPressEventArgs e)
{
_timer.Stop();
_timer.Start();
_barcode += e.KeyChar;
}
Your code above works...on a blank form. However there are several things that can interfere with the key events, especially when there are other controls on the page. Make sure that
The AcceptButton property isn't set on the form (this will trap the Enter key)
That there are no controls on the form with TabStop set to true (might not be viable but give it a go)
That the form has focus when you're typing (unlikely given the description but check anyway)
That focus is not otherwise on any control in the form when typing, e.g., a TextBox
That no other controls are trying to process the KeyPress or KeyDown events and that no other custom events are configured/set anywhere else in your code
One thing I notice is that you are registering the events like so;
form.KeyDown += new KeyEventHandler(Input_KeyDown);
This implies that you are instantiating this form from another place and trying to get it to send its key events to the calling code. Are you sure that the form instance is persisted/saved to a private class level variable or some such?

How to type text in TextBox and then be able to press return to click on Button? [duplicate]

This question already has answers here:
Windows Forms - Enter keypress activates submit button?
(9 answers)
Closed 8 years ago.
I have a TextBox and a button. In TextBox I want to type text and then be able to click enter and press my button. When I press button I can redirect to text box by using button1.Focus();
Now if I type text and press enter nothing happens. I can use tab to switch to a button, but I just wonder if I can just press enter instead.
Any ideas?
A simple solution would be:
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show("Click!");
}
private void textBox1_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
button1_Click(textBox1, new EventArgs());
}
If you are using this in more than one place I'd recommend creating a user control containing the TextBox and the Button in order to encapsulate this behavior.
In the properties of your form, set the button as the value for the AcceptButton property.
You can add a KeyPressed event to your textbox. Inside this event check if the key pressed is enter, and if it is, call the button's click event.
I think this way is a quite clever routine for your problem. This procedure allows you to check for TAB press as well. It is by the way snipped directly from:
http://msdn.microsoft.com/en-us/library/system.windows.forms.control.isinputkey.aspx
You're right on by simply changing the Keys.Tab in the microsoft sample to Key.Enter. Remember that when this textbox is used in conjunction with AutoComplete routines, it could be convenient to instantiate it outside the constructor or in a constructor overload. Here is what the instantiation of the textbox look like:
ReturnTextBox returntextbox = new ReturnTextBox();
using System.Windows.Forms;
public class Form1 : Form
{
public Form1()
{
FlowLayoutPanel panel = new FlowLayoutPanel();
ReturnTextBox returntextbox = new ReturnTextBox();
returntextbox.Text = "returntextbox";
panel.Controls.Add(returntextbox);
TextBox textBox1 = new TextBox();
textBox1.Text = "Normal TextBox";
panel.Controls.Add(textBox1);
this.Controls.Add(panel);
}
}
class ReturnTextBox : TextBox
{
protected override bool IsInputKey(Keys keyData)
{
if (keyData == Keys.Enter)
{
return true;
}
else
{
return base.IsInputKey(keyData);
}
}
protected override void OnKeyDown(KeyEventArgs e)
{
if (e.KeyData == Keys.Enter)
{
this.SelectedText = " ";
}
else
{
base.OnKeyDown(e);
}
}
}

Categories