2010-03-10 31 views
12

我試圖通過用下面的代碼冒泡它到Visual樹 來引發MouseLeftButtonDownEvent事件。提高WPF MouseLeftButtonDownEvent事件

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

由於某些原因,較高級別的組件未收到此冒泡事件。 我可以忽略一些事情嗎?是不是可以提高這個鼠標事件?

回答

20

你的問題是你正在引發一個不起泡的事件。

MouseLeftButtonDownEvent被定義爲RoutingStrategy.Direct,這意味着它只被路由到接收事件的控件。

您想改爲使用Mouse.MouseDownEvent事件。 UIElement和其他類在內部將其轉換爲MouseLeftButtonDownEvent。請確保您設置e.ChangedButton到MouseButton.Left

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

我可能是錯在我看來 - 但至少之前我看了一段時間相當長的一段長度爲InputManager

我的簡歷是:冒泡和隧道是由InputManager完成的。然而,致電uielement.Raise()將只能直接發送活動(不管RoutingStrategy爲Ray Burns mentioed)。

但根據RoutingStrategyInputManager(猜測)上升和下降CompositionRoot之間的視覺樹和VisualTreeHlper.Hittest()-編視覺並提供隧道和bublling事件。

有一種方法通過輸入管理,以提高活動,但它不是官方的,需要反思(我把它從另一個崗位#1):

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