Kbase P177931: Keypress event on .NET Form overrides keypress event on control
Autor |
  Progress Software Corporation - Progress |
Acesso |
  Público |
Publicação |
  21/01/2011 |
|
Status: Unverified
SYMPTOM(s):
Keypress event on .NET Form overrides keypress event on control
Event handler for a key set on control in .NET form
Event handler for the same key set on .NET form itself
.NET form:KeyPreview property = TRUE
Pressing key when control has focus fires event handler set for the form first
FACT(s) (Environment):
OpenEdge 10.2x
Windows
CAUSE:
This is expected behavior as defined by the .NET framework:
"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."
This is the opposite of comparable ABL functionality; when dealing with ABL widgets it will be the focussed widget that receives the event first, and the event is propagated to the containing frame only if no triggers on the widget handle it.
FIX:
There are two approaches to avoid the .NET form event handler from interfering with the control-level handlers.
1. Avoiding the use of the form:KeyPreview property
Using this approach, controls that have specific logic use their own event handlers, all other controls use the same generic handler to ensure the form-level logic is executed.
Compared to pure ABL, this is analogue with replacing an ABL "ON <event> OF FRAME ANYWHERE" construct with an "ON <event> OF widget1 OR <event> OF widget2 OR ..."
2. Replying on the form:KeyPreview property
In this case the form-level handler needs to check which control has focus, and return immediately without executing further code.
The code for the form-level handler would be similar to:
METHOD PRIVATE VOID FormKeypressHandler( INPUT sender AS System.Object, INPUT e AS System.Windows.Forms.KeyPressEventArgs ):
/* Exclude the controls that have triggers defined. This relies on the object names (as specified in the properties for
this form). */
IF THIS-OBJECT:ActiveControl:Name = "myCustomControl1" OR
THIS-OBJECT:ActiveControl:Name = "myControl1" THEN RETURN.
/* the code for the form-level action goes here */
MESSAGE "In handler for form" e:KeyChar SKIP THIS-OBJECT:ActiveControl:Name
VIEW-AS ALERT-BOX.
RETURN.
END METHOD.