以编程方式引发WPF MouseLeftButtonDownEvent事件

tf7tbtn2  于 2022-11-18  发布在  其他
关注(0)|答案(2)|浏览(203)

我尝试使用以下代码通过将MouseLeftButtonDownEvent向上冒泡到可视树来引发它。

var args = new MouseButtonEventArgs(Mouse.PrimaryDevice,0,MouseButton.Left);
args.RoutedEvent = UIElement.MouseLeftButtonDownEvent;
args.Source = this;
RaiseEvent(args);

由于某种原因,较高级别的组件没有接收到此冒泡事件。是我忽略了什么还是无法引发此鼠标事件

yhqotfr8

yhqotfr81#

您的问题是您正在引发一个不冒泡的事件。
MouseLeftButtonDownEvent被定义为RoutingStrategy.Direct,这意味着它只被路由到接收事件的控件。
您希望使用Mouse.MouseDownEvent事件。UIElement和其他类在内部将其转换为MouseLeftButtonDownEvent。请确保将e.ChangedButton设置为MouseButton.Left

RaiseEvent(new MouseButtonEventArgs(Mouse.PrimaryDevice, 0, MouseButton.Left)
{
  RoutedEvent = Mouse.MouseDownEvent,
  Source = this,
});
56lgkhnf

56lgkhnf2#

我可能是错误的,在我看来-但至少我看了相当长的一段时间前到InputManager
我的简历是:冒泡和隧道是由InputManager完成的。但是调用uielement.Raise()只会直接传递事件(不管Ray Burns提到的RoutingStrategy是什么)。
但是(猜测)根据RoutingStrategyInputManagerCompositionRootVisualTreeHlper.Hittest()-艾德Visual之间的可视树中上下移动,并提供隧道和气泡事件。
有一种方法可以通过InputManager引发事件,但它不是官方的,需要反思(我从另一个Stackoverflow帖子中得到了它):

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

相关问题