问题
I am trying ot raise a MouseLeftButtonDownEvent by bubbling it up the Visual tree with the following code.
MouseButtonEventArgs args = new MouseButtonEventArgs(Mouse.PrimaryDevice,0, MouseButton.Left);
args.RoutedEvent = UIElement.MouseLeftButtonDownEvent;
args.Source = this;
RaiseEvent(args);
For some reason the higher level components are not receiving this bubbled event. Am I overlooking something or is it not possible to raise this Mouse event
回答1:
Your problem is that you are raising an event that does not bubble.
MouseLeftButtonDownEvent
is defined as RoutingStrategy.Direct
, which means it is routed to only the control receiving the event.
You want to use Mouse.MouseDownEvent
event instead. UIElement
and other classes internally convert this into a MouseLeftButtonDownEvent
. Make sure you set e.ChangedButton to MouseButton.Left
:
RaiseEvent(new MouseButtonEventArgs(Mouse.PrimaryDevice, 0, MouseButton.Left)
{
RoutedEvent = Mouse.MouseDownEvent,
Source = this,
});
回答2:
I might be wrong in my opinion - but at least I looked some time ago for quite some length into InputManager
.
My resume from that is: The bubbling and tunneling is done by InputManager
. However calling uielement.Raise()
will only ever deliver the event directly (regardless of the RoutingStrategy
as Ray Burns mentioed).
But (guessing) depending on RoutingStrategy
the InputManager
goes up and down the visual tree between CompositionRoot
and the VisualTreeHlper.Hittest()-
ed Visual and delivers tunneling and bublling events.
There is a way to raise Events via the InputManager, but it is not official and needs reflection (I have it from another Stackoverflow post):
void RaiseMouseInputReportEvent(Visual eventSource, int timestamp, int pointX, int pointY, int wheel)
{
Assembly targetAssembly = Assembly.GetAssembly(typeof(InputEventArgs));
Type mouseInputReportType = targetAssembly.GetType("System.Windows.Input.RawMouseInputReport");
Object mouseInputReport = mouseInputReportType.GetConstructors()[0].Invoke(new Object[] {
InputMode.Foreground, timestamp, PresentationSource.FromVisual(eventSource),
RawMouseActions.AbsoluteMove | RawMouseActions.Activate,
pointX, pointY, wheel, IntPtr.Zero });
mouseInputReportType.GetField("_isSynchronize", BindingFlags.NonPublic | BindingFlags.Instance)
.SetValue(mouseInputReport, true);
InputEventArgs inputReportEventArgs = (InputEventArgs)targetAssembly
.GetType("System.Windows.Input.InputReportEventArgs")
.GetConstructors()[0]
.Invoke(new Object[] {
Mouse.PrimaryDevice,
mouseInputReport });
inputReportEventArgs.RoutedEvent = (RoutedEvent)typeof(InputManager)
.GetField("PreviewInputReportEvent", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)
.GetValue(null);
bool handled = InputManager.Current.ProcessInput((InputEventArgs)inputReportEventArgs);
}
来源:https://stackoverflow.com/questions/2421304/raising-wpf-mouseleftbuttondownevent-event