SYSK 344: Learning WPF – What Are All These PreviewX Events?
Did you notices that there are a lot of events that start with word ‘Preview’, and all of them seem to have a “buddy” event with same name but without the ‘Preview’ prefix? For example, the following paired events are defined by the System.Windows.Window class:
PreviewDragEnter & DragEnter
PreviewDragLeave & DragLeave
PreviewDragOver & DragOver
PreviewDrop & Drop
PreviewGiveFeedback & GiveFeedback
PreviewGotKeyboardFocus & GotKeyboardFocus
PreviewKeyDown & KeyDown
PreviewKeyUp & KeyUp
PreviewLostKeyboardFocus & LostKeyboardFocus
PreviewMouseDoubleClick & MouseDoubleClick
PreviewMouseDown & MouseDown
PreviewMouseLeftButtonDown & MouseLeftButtonDown
PreviewMouseLeftButtonUp & MouseLeftButtonUp
PreviewMouseMove & MouseMove
PreviewMouseRightButtonDown & MouseRightButtonDown
PreviewMouseRightButtonUp & MouseRightButtonUp
PreviewMouseUp & MouseUp
PreviewMouseWheel & MouseWheel
PreviewQueryContinueDrag & QueryContinueDrag
PreviewStylusButtonDown & StylusButtonDown
PreviewStylusButtonUp & StylusButtonUp
PreviewStylusDown & StylusDown
PreviewStylusInAirMove & StylusInAirMove
PreviewStylusInRange & StylusInRange
PreviewStylusMove & StylusMove
PreviewStylusOutOfRange & StylusOutOfRange
PreviewStylusSystemGesture & StylusSystemGesture
PreviewStylusUp & StylusUp
PreviewTextInput & TextInput
As a rule, the events with ‘Preview’ prefix are raised starting from the root of the visual tree and on down the tree until the source element’s delegate is called (a.k.a. tunneling events) with the intent to let all the subscribers know about the event about to happen. You should not process the event (wait to do that till the “real” not the preview event notification occurs), but you can, if necessary, cancel further notifications to subscribers that only registered to receive unhandled events by setting e.Handled property to true, and it’s a great place to put validation logic.
This design pattern reminds me somewhat of the KeyDown, KeyPress, KeyUp events – you subscribe to KeyDown (not KeyPress) to do your validation; otherwise, once the key press is processed by the control, your only option is to delete the key, which is not as good as not displaying it in the first place.
Note that there are two ways to subscribe to the event:
// Don't receive handled event notifications
this.PreviewKeyDown += new KeyEventHandler(Window1_PreviewKeyDown);
or
// Receive all event notifications, handled or not
this.AddHandler(Window.PreviewKeyDownEvent, new KeyEventHandler(Window1_PreviewKeyDown), true);
One more point: the “real” event (e.g. KeyPress) is raised the same way as it was done in previous version of .NET framework -- from the source element and on up the visual tree until the root is reached (a.k.a. bubbling events).