I came across the following misunderstanding.
Preamble
I have a wpf application with the following important parts of the user interface: RadioButtons and some control that uses a popup based dropdown menu (in list order). According to some logic, each case of the PreviewMouseDown beam hook and some calculations. In the following scenario
- The user opens a pop-up window (do not select something, the pop-up window remains open)
- User clicks on the drum
PreviewMouseDown will not start for the radio unit as expected (due to the Popup function ).
And my goal is to shoot PreviewMouseDown for RadioButton , despite one.
Attempts to solve :
Quick and dirty solution: hook PreviewMouseDown for Popup and restart the PreviewMouseDown event with a new source, if required, using the radio as the source. A new source can be obtained through MouseButtonEventArgs.MouseDevice.DirectlyOver . The following code fragment does this (the event is restarted only if Popup "has" PreviewMouseDown for an external click):
private static void GrantedPopupPreviewMouseDown(object sender, MouseButtonEventArgs e) { var popup = sender as Popup; if(popup == null) return; var realSource = e.MouseDevice.DirectlyOver as FrameworkElement; if(realSource == null || !realSource.IsLoaded) return; var parent = LayoutTreeHelper.GetParent<Popup>(realSource); if(parent == null || !Equals(parent, popup )) { e.Handled = true; var args = new MouseButtonEventArgs(e.MouseDevice, e.Timestamp, e.ChangedButton) { RoutedEvent = UIElement.PreviewMouseDownEvent, Source = e.MouseDevice.DirectlyOver, }; realSource.RaiseEvent(args); } }
This one works well when I attach this handler to Popup.PreviewMouseDown directly through Behavior and does not work ( PreviewMouseDown does not start for radio EventManager.RegisterClassHandler ) if I attach one through EventManager.RegisterClassHandler (the goal is to avoid attaching behavior to each Popup that may appear on the page with these radio exchanges):
EventManager.RegisterClassHandler( typeof (Popup), PreviewMouseDownEvent, new MouseButtonEventHandler(GrantedPopupPreviewMouseDown));
The debugger showed that e.MouseDevice.DirectlyOver (see code above) is Popup , not RadioButton (as it was when I bound the handler through Behavior )!
Question
How and why can MouseButtonEventArgs be different for the same action if event binding has two different ways?
Can anyone explain this behavior?
Thank you very much.