【问题标题】:Raising WPF MouseLeftButtonDownEvent event引发 WPF MouseLeftButtonDownEvent 事件
【发布时间】:2011-01-26 03:37:38
【问题描述】:

我正在尝试通过在 Visual 树上冒泡来引发 MouseLeftButtonDownEvent 使用以下代码。

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

由于某种原因,更高级别的组件没有收到此冒泡事件。 我是否忽略了某些东西,或者无法引发此鼠标事件

【问题讨论】:

    标签: wpf events raise


    【解决方案1】:

    您的问题是您正在引发一个不会冒泡的事件。

    MouseLeftButtonDownEvent 定义为RoutingStrategy.Direct,这意味着它只路由到接收事件的控件。

    您想改用Mouse.MouseDownEvent 事件。 UIElement 和其他类在内部将其转换为 MouseLeftButtonDownEvent。确保将 e.ChangedButton 设置为 MouseButton.Left:

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

    【讨论】:

      【解决方案2】:

      在我看来我可能是错的 - 但至少我前一段时间看过InputManager

      我的简历是:冒泡和隧道是由InputManager 完成的。但是,调用 uielement.Raise() 只会直接传递事件(不管 Ray Burns 提到的 RoutingStrategy)。

      但是(猜测)InputManagerCompositionRootVisualTreeHlper.Hittest()-ed 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);
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-03-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多