This question already has answers here:
Disable All Events on a Windows Form
(5 answers)
Closed 10 years ago.
My Application sometimes comminucate with a Server in another Thread, while the form should be locked in this time(that means, the user cant fire any Click, KeyDown .... event). In this time, a waitoverlay with a loading circle is showing which blocks any mouse events like click or mousehover.
But the problem is, that the user can fire KeyDown events by pressing keys and the user can also make mouse clicks by pressing enter after navigating to the button with the TAB Key.
I know that Form.Enabled = true; can do the trick, but then the form is looking very ugly. I know also that I could make a bool inaction; and then look at this var in the event handler, but I think theres a better way.
Short Form: How can I block GUI Events like Click or KeyDown from a Form without .Enabled = True?
Any help will be greatly appreciated.
Edit: Solved it by adding this to the overlay control:
protected override bool ProcessKeyMessage(ref Message m)
{
return true;
}
protected override bool ProcessTabKey(bool forward)
{
return true;
}
You may set the KeyPreview property of the form to false.
When the KeyPreview is false, the form will not receive key events before the event is passed to the control that has focus. And if you change your focus to some unused control which does not interact with keys, form or any controls waiting for key events will not receive any events.
Related
I've got a winform application. In the application I have a Panel with multiple Buttons.
Now when the Buttons don't have the Focus I can capture the keypressed Events in the form itself. But when the Buttons have the Focus the form (even if the Buttons don't catch the Event explecitely) only they get the keypressed Event and not the form.
Now my question is: Is there any way to centralize the keypressed behaviour (without creating a keypressed Event for each and every button and call a central method with that Event)?
In essence only 1 method needs to be defined with the appropriate Parameters:
Example:
private void Event_Key_Press_Check(object sender, KeyPressEventArgs e)
This method then only Needs to be put in as the Name of the method used in the Event (form designer), or added as the Event.
That way only 1 method is used.
Thus there is no shorter way and the Event Needs to be defined for every single button (instead of 1 central Event that is always triggered).
Set form property KeyPreview to true and set KeyPress handler. Then form will handle this event before buttons.
See KeyPreview MSDN documentation.
I've had the same issue, and it was pretty easy to resolve :)
Check here : KeyPress at form level with controls
Just set the KeyPreview property (of your form) to True. This way your form will handle KeyPress event before any other control, even if one of them has the focus
How can I detect when a popup is about to be closed?
The Popup class does not have a Closing event in UWP, unlike in WPF where such an event exists.
I need this in order to persist the state of the Popup because the layout can be modified by the user.
As you already know, there is no Closing event. You might get lucky by registering to IsOpen property change (if IsLightDismissEnabled property is set to true...)
this.popup.RegisterPropertyChangedCallback(Popup.IsOpenProperty, (d, e) =>
{
if (!this.popup.IsOpen)
{
// do something, popup is closing?
}
});
because that happens before the LostFocus and Closed events get fired. Other than that, you can redesign the way you persist data to persist them all the time if it's not something very complex to avoid having to depend on the closing event.
This question already has answers here:
Best way to implement keyboard shortcuts in a Windows Forms application?
(9 answers)
Closed 7 years ago.
I am making a program to record the position of a mouse when someone presses the Space button.
This works fine, however when I put the cursor in any textBox in the form the code becomes useless of course because the space gets typed in the textBox. I tried to change the focus() or try other keys like LeftWin ... but none worked!
Any advice on how can I detect the Space button (or any other key) all the time in a form?
private void lebel1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Space)
{
//bla bla
}
}
The event is not firing because the Textbox is handled the event, with that being said, the event will not be propagated to the parent controls (Bubbling events).
You could use a KeyPress, which means that the event will be fired from the most outer control and will be propagated to their children. (Tunnel events)
You could learn more about here.
This is a winform C# question. I have a textbox with a validating event listener to validate the content of the textbox. Say, the textbox doesn't accept negative values. I only listen to validating event so by default, the textbox's AutoValidate property is EnablePreventFocusChange, which is totally fine for me.
The problem is, when I click the X button on the right top corner of the form, I don't want the validation to be fired because I am closing the form anyway. How can I do this? There is no control to set CauseValidation to false, which I can do if there is a closing button. Thank you very much.
Hmmm, the only way I would think to do it is to set AutoValidate on the form to false and handle validation in the controls manually. The form has .Validate() and .ValidateChildren() methods, read up on these as they are what you need to perform validation. To handle it manually, you will need to listen for when a control is losing focus - if validation fails you then need to perhaps re-focus the offending control.
Alternatively, make the form ControlBox = false; to remove the X button.
Update: Alternatively again you can use a member variable to test whether to validate or not (ie, whether the form is closing or not). You cannot do this using the FormClosing event as this fires after the validation, however you can detect form closing via WndProc. Code is provided in this post:
http://technoblot.wordpress.com/2006/09/08/winforms-causesvalidation-not-working-a-workaround/
A slightly less involved workaround.
When closing the form, the form checks if the AutoValidate property of the form has a value different from Disabled then it raises the Validating event of the focused control. Also if there is any validation error (by setting e.Cancel = true in the Validating event), it prevents closing of the form.
To prevent raising the Validating error when closing the form, you need to override WndProc and before processing WM_CLOSE message set AutoValidate to Disabled and after that, set it back to original value. The reason for setting it back to original value is because you may want to prevent closing the form and then it's expected the value of AutoValidate be the same value that the developer has been set originally:
private const int WM_CLOSE = 0x0010;
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_CLOSE)
{
var autoValidate = this.AutoValidate;
this.AutoValidate = AutoValidate.Disable;
base.WndProc(ref m);
this.AutoValidate = autoValidate;
}
else
base.WndProc(ref m);
}
Note: If you just want to allow the form get closed after click on close button, it's enough to override OnClosing method and set e.Cancel = false after calling base.OnClose. But it doesn't prevent the Validating event. It just allows the form get closed even if there is a validation error in the focused control.
You can read more about the problem in this post: Prevent raising of Validating event of focused control when Closing the form.
I solved this issue by setting the form CausesValidation property to False.
The form now closes normally when I click the X button.
I've been working for a while on my Windows Forms project, and I decided to experiment with keyboard shortcuts. After a bit of reading, I figured I had to just write an event handler and bind it to the form's KeyDown event:
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control && e.Alt && e.KeyCode == Keys.O)
{
MessageBox.Show("Ctrl+Alt+O: magic!");
}
}
I did that the good ol' way of opening the Properties panel of the Visual Studio designer, then double-clicking on the KeyDown event of my form to generate the Form1_KeyDown event handler. But on testing my application, the form doesn't respond at all to the Ctrl+Alt+O keyboard shortcut. The Visual Studio designer did generate the code to bind the event handler to the form though:
private void InitializeComponent()
{
// ...
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.Form1_KeyDown);
// ...
}
So I tried adding a Console.WriteLine() call to the handler to check that it was being called at all, but no luck on that either.
Also, I tried to set a breakpoint on the event binding call (shown just above) and found that the program reaches that breakpoint just fine. But any breakpoints I set within the method definition itself are never reached.
To make sure I was doing the first few steps correctly, I tried repeating them with:
A new form in the same solution.
Same issue: the form doesn't respond when I press my Ctrl+Alt+O keyboard shortcut and the debugger isn't even stepping into the event handler. Tried this again and it works.
A brand new WinForms solution.
It works perfectly: the message dialog appears (the Console.WriteLine() call also works).
So I'm quite lost here. What's preventing all the forms in this one project from receiving KeyDown events?
Does your form have KeyPreview property set to true?
Form.KeyPreview Property
Gets or sets a value indicating whether the form will receive key
events before the event is passed to the control that has focus.
http://msdn.microsoft.com/en-us/library/system.windows.forms.form.keypreview.aspx
The most common piece of advice for this problem on StackOverflow and the MSDN1, 2 (including the accepted answer here) is quick and easy:
KeyDown events are triggered on a Form as long as its KeyPreview property is set to true
That's adequate for most purposes, but it's risky for two reasons:
KeyDown handlers do not see all keys. Specifically, "you can't see the kind of keystrokes that are used for navigation. Like the cursor keys and Tab, Escape and Enter for a dialog."
There are a few different ways to intercept key events, and they all happen in sequence. KeyDown is handled last. Hence, KeyPreview isn't much of a preview, and the event could be silenced at a few stops on the way.
(Credit to #HansPassant for those points.)
Instead, override ProcessCmdKey in your Form:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
if (keyData == Keys.Up)
{
// Handle key at form level.
// Do not send event to focused control by returning true.
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
That way, all keys are visible to the method, and the method is first in line to see the event.
Note that you still have control over whether or not focused controls see the KeyDown event. Just return true to block the subsequent KeyDown event, rather than setting KeyPressEventArgs.Handled to true as you would in a KeyDown event handler. Here is an article with more details.
Try setting the KeyPreview property on your form to true. This worked for me for registering key presses.