Window Closing Event and KeyPress - c#

<Window Closing="Window_Closing"></Window>
Assuming keys are used to close the window. Is there a way to determine which keys were used?
I know you can with the KeyDown event but need to do so in the Closing event.
Thank you!

Rather than trying to determine the cause of a closing event to disable certain keystrokes, disable all methods for closing until your "secret" keystroke is entered.
Use a KeyDown event to intercept and record all keystrokes, and have it set a flag if the secret combination is entered, and then call Close().
In your Closing event, always set e.Cancel = true unless that flag is set.
Here's a simple example:
bool _allowClose = false;
void OnKeyDown(object sender, KeyEventArgs e)
{
if (DetectSecretCombo(e)) //Implement however you see fit.
{
_allowClose = true;
Close();
}
}
void OnClosing(object sender, ClosingEventArgs e)
{
_e.Cancel = !_allowClose;
}

Related

How to stop key Down of the form

I have a Form1_KeyDown event for form1, but while I am typing some text in the Textbox on the Form, the event gets triggered.
How can I stop that event when I am typing inside the textboxes on the form.
There are two ways:
Set form's KeyPreview to false. Which is the default, so you must have explicitly changed it, presumably for a reason. Otherwise the controls of on the form always get the keyboard events first.
Add an active control check in Form1_KeyDown, like this:
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (this.ActiveControl == textBox1) return;
var k = e.KeyCode;
}

Get keydown event without a textbox

Im trying to do like that: If I press the key "P" a messagebox will open in the screen.But I need to do it without a textbox or other tool, I want to do that direct in the form.
I tried:
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.P)
{ MessageBox.Show("Key P pressed"); }
}
Try with the KeyPress Event of the form. It just works fine.
Assuming this is Winforms, on the form you're trying to catch the event on, make sure to set
Form1.KeyPreview = true;
KeyPreview ensures that keyboard events anywhere on the particular form (such as to a textbox with focus) will still count as a keyboard event for the form itself.

Keydown Event fires twice

On a Windows store App, I have this simple TextBox
<TextBox Name="TextBoxUser" HorizontalAlignment="Right" Width="147" Margin="20,0,0,0" KeyDown="TextBox_KeyDown" /
That has a KeyDown Event associated with it.
private async void TextBox_KeyDown(object sender, KeyRoutedEventArgs e)
{
if (e.Key == Windows.System.VirtualKey.Enter)
{
Debug.WriteLine("LA");
}
}
And the output of this function is:
LALA
although I press Enter only once, it prints 2 times.
Any reason for that or am I doing something wrong?
This should only fire the event once, so if it is firing twice I would check a couple of things.
Check that you aren't handling the key down event on a parent control. This could be a panel or the containing window. Events will bubble down through the visual tree. For example a key down on a textbox will also be a keydown on the window containing the textbox.
To stop this happening you can mark the event as handled as below;
e.Handled = true;
The other thing to check is that you aren't subscribing to the event twice. The XAML will do the same as;
TextBoxUser.KeyDown += TextBox_KeyDown
so check that you don't have this in your code behind.
You can check the sender and e.OriginalSource property to see where the event is being fired from.
This is a known bug in Windows RT.You can handle it by checking the Key RepeatCount `
if (e.KeyStatus.RepeatCount == 1)
{
//Execute code
}
I finally realized that there is probably a bug in the KeyDown event.
When I set, as #daniellepelley said,
e.Handled = true;
the event still propagates: other buttons will intercept it, also if they shouldn't.
In my code, I just replaced KeyDown event with KeyUp event and everything works fine (always setting Handled to True value)!
This might be too late, but e.preventDefault() worked for me. Especially in React - TypeScript.
(e: KeyboardEvent) => {
e.preventDefault();
console.log(e);
};
void onKeyPressEvent(object sender, KeyEventArgs e)
{
if(e.Handled)
return;
{
//
// the block of codes to be executed on the key press
// should added here.
//
}
e.Handled = true;
}
I had this same issue in Xamarin.Android where the keypress event fired twice.
In my case it is because the KeyDown and KeyUp are two separate actions which both call the same event. I only respond to one action as below:
private void KeyPress(object sender, View.KeyEventArgs e)
{
if (e.KeyCode == Keycode.Enter)
{
if (e.Event.Action == KeyEventActions.Down)
{
Event();
}
}
}
i was seeing this issue in javascript, where keydown event handler is fired twice, and was able to fix by using .off().on()
$('.text_area').off().on('keydown', function (e) {
// do something
)};
what it does is that, it switches off the extra events and the takes the latest keydown action and executes the handler for it
for me only this solution worked well
thanks

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?

Troubles with onFormClosing in c#

I'm trying to implement some code that asks if the user wants to exit the application I've made.
It's in c# and is a windows form application.
I've had very little sleep this week and can't seem to get my head around the onFormClosing event. Could some please give me the exact code I should use to have code executed when the user clicks on the close button (the 'x' in the top right).
Please find it in your heart to help a sleep deprived moron.
Double-click the form's FormClosed event in the events tab of the Properties window in the designer.
The FormClosing event allows you to prevent the form from closing by setting e.Cancel = true.
Well, the event is called FormClosing and is cancellable. Subscribe to it, do your stuff and let the user close their form. This event is fired if the "x" button is used or if you close the form yourself.
You can subscribe to it in the designer by highlighting the form and looking in the events tab of the properties window, as SLaks says, then double-click it. You don't need to do anything special to cope with the "x" button.
The easiest way is to activate the form in the designer and find the event FormClosing in the properties windows and then just double click the event.
Then just do the following:
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (e.CloseReason == CloseReason.UserClosing)
{
var result = MessageBox.Show("Are you sure you want to exit?", "Exit", MessageBoxButtons.YesNo);
if (result != System.Windows.Forms.DialogResult.Yes)
{
e.Cancel = true;
}
}
}
If you do not specify that the reason has to be UserClosing, it will stop windows from shutting down if you do not exit the program first which is not a good practice.
public Form1()
{
InitializeComponent();
this.FormClosing += new FormClosingEventHandler(Form1_FormClosing);
}
void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (MessageBox.Show("Are you sure that you wan't to close this app", "Question", MessageBoxButtons.OKCancel) == DialogResult.Cancel)
e.Cancel = true;
}
I hope this helps
You can add event handler manually. Example to add event handler in constructor:
public frmMain()
{
InitializeComponent();
FormClosing += frmMain_FormClosing;
}
private void frmMain_FormClosing(object sender, FormClosingEventArgs e)
{
//your code
}
Make derive your form fromf the System.Windows.Forms.Form and put this override:
protected override void OnFormClosing(CancelEventArgs e)
{
if (bWrongClose)
{
bWrongClose = false;
e.Cancel = true; // this blocks the `Form` from closing
}
base.OnFormClosing(e);
}

Categories