Raising WPF MouseLeftButtonDownEvent event

二次信任 提交于 2019-11-29 06:06:10

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,
});

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);
    }
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!