Key event handlers don't fire at the form level - winforms

{Form constructor}
this->KeyDown += gcnew KeyEventHandler(this, &Form::Form_KeyDown);
...
void Form1::Form_KeyDown(Object^ Sender, KeyEventArgs^ E)
{
MessageBox::Show("Key = " + E->KeyCode.ToString(), "Test");
}
The above event handler never fires. But the form's child controls' handler does. What would be the problem ?

In addition to having your event handler, you need to set the form's KeyPreview property to true. According to MSDN:
When this property is set to true, the form will receive all KeyPress, KeyDown, and KeyUp events. After the form's event handlers have completed processing the keystroke, the keystroke is then assigned to the control with focus.

Related

PreviewlostkeyboardFocus event fires twice when I click on combobox WPF

I have wired PreviewLostKeyboardFocus event to TextBox. I handled the event. When I click on the ComboBox control, it fires twice.
If I not handled it fires only one time.
private void TextBox_PreviewLostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
e.Handled = true;
}
Can someone please help resolve this issue ?
When you set:
e.Handled = True;
You are effectively preventing the focus leaving the TextBox.
So if focus is in this TextBox and you click on another field (e.g. ComboBox) it will cause the event to fire, but the cursor will remain forever in the TextBox.
Remove this or make it conditional.

XAML Window MouseDown event beats Image event

I'm using WPF to design a borderless, movable application window.
In order to manually perform the ability to drag and drop the window, I've added an OnMouseDown event to the <Window> element, that executes a corresponding C# function (this.DragMove()).
Additionally, I need an <Image> button to allow some operation (with the OnMouseUp event this time). Note that it has to be an Image tag, and not a Button.
Unfortunately, the Image event fired only when the right mouse button is clicked, probably because the left button is held to the window event. Am I right?
When someone clicks the Image button, I want only the Image event to be triggered. How can I do it?
Problem you're facing is most probably related to event routing. The idea is that if your handler doesn't mark event as a Handled it will be routed to the next listener unless reach end of chain or one of listeners/handlers will set it as Hadnled.
So if you have MouseDown event handler for both Window and Image you should keep in mind that routing will stop at a point when you will set e.Handled = true;:
private void Window_OnMouseDown(object sender, KeyEventArgs e)
{
e.Handled = false; // will NOT break event chain;
}
You can always check a type of sender so it will make possible for you to differ Image and Window events:
private void Image_OnMouseDown(object sender, KeyEventArgs e)
{
if (sender is Image)
{
// Handle Image.MouseDown
e.Handled = true; // we don't need to push event further;
}
}
Its because of WPF bubbling and tunnelling events. so what u can do is whenever u handle event on button use bubbling for that means you can use previewevents for that for both button and window and whenever you just want to handle event for button then after last line of code in button click just write down like this.
e.handled=true;
// here e is the event argument which u will get in your preview event.so now window dragging event will not work.
i would just suggest first clear the idea of bubbling(preview mouse event) and tunneling in wpf.
Difference between Bubbling and Tunneling events
and go through some of the example of bubbling and tunnelling. you will get better idea.
http://www.codeproject.com/Articles/464926/To-bubble-or-tunnel-basic-WPF-events

Why does the KeyDown event bubble up from a TextBox?

If I type a letter into a TextBox, and its content changes according to my keypress, why does the KeyDown event continue bubbling up? I would have thought this would be 'handled' at this stage.
Since KeyDown event is a bubbling event, that's why its bubbled to its parent in your case Window. If you don't want that to bubbled to your window, you need to mark it as handled in your textBox handler itself like this -
private void TextBox_KeyDown(object sender, KeyEventArgs e)
{
e.Handled = true;
}
Whereas, if you try to hook the event PreviewKeyDown in your textBox, you will see that - Window's PreviewKeyDownEvent gets called first and later that of your textBox. Reason behind that is, it's a tunelling event. For routing strategies, refer to this link - Routing Strategies
EDIT
Morevoer, if you want to check if the KeyDown event comes from textBox, you can check the OriginalSource of your eventArgs -
private void Window_KeyDown(object sender, KeyEventArgs e)
{
// Check to make sure event comes from window and not from textbox.
if(e.OriginalSource is Window)
{
}
}

How to handle both the KeyDown and KeyUp events in a Silverlight 3 TextBox

I am attaching handlers to the KeyDown and KeyUp events of a Silverlight 3 TextBox as so:
_masterTextBox.KeyDown += (s, args) =>
{
CheckForUserEnteredText(MasterTextBox.Text);
args.Handled = false;
};
_masterTextBox.KeyUp += (s, args) => { UpdateText(MasterTextBox.Text); };
When I comment out the KeyDown handler, then the KeyUp will trap the event, otherwise, only the KeyDown handler is triggered.
Can someone explain why the KeyUp event handler is not firing after the KeyDown handler does?
Thanks.
I think you need to look inside your CheckForUserEnteredText function. Certainly there is no reason from the posted code alone for KeyUp not to fire and it does in my testing.
Perhaps CheckForUserEnteredText does something to prevent it? You seem to have both a public field/property called MasterTextBox and one called _masterTextBox, do you need both? Could it be the KeyUp is firing but UpdateText isn't doing what you expect? The list could go on, the bottom line is there isn't a problem with the code you've posted.
It turns out that the problem was that I was setting a break point in the keydown method. Apparently, when you set a break point, it misses the keyup event.

Detect when application becomes active

In MDI application which event can the child Form class use to detect when the application becomes active?
I tried Form.Acivated event but it occurs only when the form is activated and doesn't when the application gets focus.
It is the MDI parent form that gets the Activated event. You can subscribe to the event in your child form's Load event. Be careful, you have to make sure you unsubscribe the event when the child gets closed or you'll leak the child form instance. Make it look like this:
protected override void OnLoad(EventArgs e) {
var main = this.MdiParent;
main.Activated += main_AppActivated;
this.FormClosed += (o, ea) => main.Activated -= main_AppActivated;
}
void main_AppActivated(object sender, EventArgs e) {
// Etc...
}
Have you tried the GotFocus event?
While WPF has such a notion, WinForms does not to the best of my knowledge; you'd need to use Form-level events (like GotFocus from the earlier answer).

Resources