HI,
I have a form in C# app. On this form I capture a KeyDown event Alt+U which will open a second form. In the second form I have a toolStripButton with shortcutkey Alt+U (the same which I used to open the form with) which prints a document. Now, my problem is when I open the second form It will automatically trigger the event of clicking toolstripbutton since it has the same shortcutkey as I used to open the form with. How can I prevent this from happen.
Regards Johan
This doesn't answer your question, but you really should think about making two different shortcut keys for these two very different actions. Having two identical shortcut keys that do two entirely different actions is very confusing IMO.
To answer your question though, I would have some property on the second form like "ShouldRaise" or something, and only raise the Alt + U event in the second form if that flag is true. Set it to false initially, but then in the KeyUp in the first form, set it to true.
Would it not just be easier to change the shortcut of one to something else? I agree with BFree its not the best design have the same shortcut for 2 completely different functions. All shortcuts/accelerator keys should be unique.
Why not change the shortcut for the form page changing to something like:
Ctrl+Right (Go to next page)
Ctrl+Left (Go to previous page)
On the second form do you actually have a ToolStripMenuItem instead? (a ToolStripButton doesn't have the ShortcutKeys property).
Do you instantiate a new form when the user presses Alt-U on the parent form?
Did you check the sender object on the handler that prints the document to see if it was the parent form?
Can't seem to reproduce your problem; a little explaining would help.
Another easy solution is to do some check of what form you are in from the event listener. You could just return inside the event handler inside your second form.
Again not the most elegant solution but should be a decent fix.
Related
I am making a game, and to open up and close the store, you press S. While in the store, you have six different choices to buy from, but they are all buttons.
However, once you buy something, the focus is no longer on the form, but on the button, and the key down event is part of the form, therefore, because the focus gets switched from the form to the button, the key down event no longer works, and disables you from closing the store and continuing on with the game.
My question is how to set the focus back to a form once a button is press? I started out with visual basic, and the code would be something along the lines of form1.setfocus, but its totally different in c#.
I have tried Activating the form, .focus, a lot, and nothing seems to be setting the focus back to the form. Help would be greatly appreciated.
Form1.focus();
But I think, to get keyboard events on Form itself, you need KeyPreview set to true for the Form so that Form gets Keys first and then other controls.
Try:
form.Focus();
MSDN:
The Focus method returns true if the control successfully received input focus. The control can have the input focus while not displaying any visual cues of having the focus. This behavior is primarily observed by the nonselectable controls listed below, or any controls derived from them.
Tell me more
You can add the key down event to the buttons too.
I'm relatively new to C# and I want to know how can I press a key on my keyboard say the Q key and have it preform a list of functions?
I want to form a list of function under neath it. Anybody have any idea how to do this? thanks
//Something like this
if keyboard_down(Q)
{
//Do events here
}
I know this isn't the right function but that is basically what i want it to do. Winforms
You didn't mention which technology you work with.
I will assume that you are using Winforms.
In order to react to Key Press event you need to use Control.OnKeyPress - See here
See also this example which shows how to handle 'enter' key press
Depends on the way you want it.
Do you want them to fire while the form got focus or even without any focus to the form?
With focus:
Click your form in the form-designer and then go to the properties-tab. Click that little lightning bolt on top of it. There are a lot of events in that list. Double click "Keypress" and it will create an event automaticly and open the right code-snipped for you.
Depending on the focus you want, you can also mark controlls inside the form designer and then create the keypress event.
Without focus:
This would be a bit more difficultly. Here you would need to use a global keyboard hook to permanently grab pressed keys. Google for "c# keyboard hook". There are some examples out there.
I have succesfully replaced the Windows Shell following the approach given in this SO question.
However, I have detected that the first key press is lost and is a bit of an annoyance for the user. The solution we have tried is to activate the form in the OnShown event:
private void OnShownLoginForm(object z_sender, EventArgs z_e)
{
Activate();
m_loginTextBox.Focus();
}
But this hasn't solved the problem. Do you have any clue of what is happening?
You could try using the System.Windows.Forms.SendKeys Class (MSDN Documentation) to send a key press event to the form when in the Form Load event. If that doesn't help, try sending the keyboard events in the Form.Shown event since Form.Shown is the last event in the form start-up process.
Sounds like something caused by maybe another control getting focus first. Does the textbox have a taborder, and can you set it to 0? Focus should then be on it after the form loads.
Otherwise try creating a new form to test with, it really doesn't seem reproducible.
I do not know if it is related but I had a similar problem where the tabindex property of a webform did not work by pressing the TAB key, after focusing on the first input at page load, until the user first clicked on the form with the mouse.
I did not have access to the source code so I tried solving it with javascript.
Until the first mouse click, all keyboard strokes, including the TAB key, activated the keypress event, TAB key was undetected by keydown/keyup on page load.
I learned that the TAB key activated the keypress event and I could access the keycode through it. simply registering the keypress event and manually switching to the next input with jQuery worked.
after the first mouse click the form behaved as expected, TAB key was no longer caught by keypress event.
here is a code sample:
function tabNext(e){
if(e.keyCode == 9){
// do work
}
}
$('input').keypress(tabNext);
On my main form, there is another (floatable) window. This floatable window works sort of like a popupwindow in that it will close when the user clicks somewhere else outside of this window. This is handled by the Deactivate event. But what I want to do is, if the user clicks on a different control (say a button), I want to both close this float window and then activate that button with just one click. Currently, the user has to click twice (one to deactivate the window and once more to activate the desired button). Is there a way to do this with just one click?
foreach(Control c in parentForm.Controls)
{
c.Click += delegate(object sender, EventArgs e)
{
if(floatyWindow != null && floatyWindow.IsFloating)
{
floatyWindow.Close();
}
};
}
And then add your handlers as normal. This additional handler can close the floaty window.
Make sure you floaty window isn't a dialog too as this will not allow your parent form's controls to be clicked.
I had a slightly hacky solution. In your Deactivate event, fire another custom event to your main form. Then when you main form is handling the custom event, enumerate through your control(this.Controls) and locate the control under the mouse by checking all their bound then call Focus(). You might need to sort by the one with the smallest surface area, or you can have a separate list of "focus-able" control like button just for this purpose.
Another way might be to switch focus to your main form immediately after OnMouseLeave of the floatable window, or OnMouseHover of your main window, but keep the floatable windows on top, just no focus. Handle the global mouse down of your main form, and close the floatable window by then.
These are just theories, not tested.
I had an issue like this once too, when a customer wanted "floaty" windows all over there application. I used used an approach similar to the one described in this article:
http://www.vbaccelerator.com/home/NET/Code/Controls/Popup_Windows/Popup_Windows/article.asp
Code sample available here:
http://www.vbaccelerator.com/home/NET/Code/Controls/Popup_Windows/Popup_Windows/Popup_Form_Demonstration.asp
By extending this a bit we created "floaty" windows similar to the ones VS uses when you get a runtime error while debugging code.
At the very least reading the code may give you some insight, however, quarrelsome's response may be the more simple solution.
We need to handle this event in the base form, regardless of which controls currently have focus. We have a couple of global key commands that need to work regardless of control focus.
This works by handling the PreviewKeyDown event in the form normally. When we add a user control to the form, the event no longer fires.
Am I missing something trivial here? Or do we need to handle the event in the user control first?
Thanks for your help!
Thanks Factor. When I get more time :) I'll get it working 'properley'!
The hidden menu you are using works fine for shortcuts that are valid menu item shortcuts, but if you want to use any key as a shortcut (such as Page Up/Page Down), you'll need a different trick.
Another way to do this that doesn't involve P/Invoke is to set the Form.KeyPreview property of your form to true. This will cause all key presses to be sent to the form first, regardless of which control has focus. You can then override OnKeyDown, OnKeyPress, and/or OnKeyUp to handle the key press before any of your controls.
This is probably not the best way of doing it, but the first way that comes to mind.
In your forms constructor, after you call InitializeComponent(); do something like this:
foreach (Control control in this.Controls)
{
control.PreviewKeyDown += new PreviewKeyDownEventHandler(HandlePreviewKeyDown);
}
I THINK that should do the trick. In your HandlePreviewKeyDown method you can then do your work and it should trigger regardless of which control has focus.
PreviewKeyDown only works when the control has focus. It sounds like you should look into an application level hook for a special shortcut keys. You'll have to do it with a P/Invoke. SetWindowsHookEx on pinvoke.net is a good place for an example. Here's a MS KB article about a mouse hook in c#, which appears to be expanded to a keyboard hook in this article.
We ended up doing this:
I found a workaround for this by setting up a hidden menu item by setting:
ToolStripMenuItem.Visible = false
(Thanks to this article).
It appears that the Main Menu of a form always gets searched for your shortcut key combination. This works regardless of whick control has focus