2010-03-10 3 views
12

다음 코드를 사용하여 시각적 트리 위로 버블 링하여 MouseLeftButtonDownEvent를 발생 시키려고합니다.WPF MouseLeftButtonDownEvent 이벤트 발생

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

어떤 이유로 높은 수준의 구성 요소에이 버블 이벤트가 발생하지 않습니다. 내가 뭔가를 내려다 보았습니까? 아니면이 마우스 이벤트를 발생시킬 수 없습니까?

답변

20

당신의 문제는 거품이 나오지 않는 이벤트를 제기하는 것입니다.

MouseLeftButtonDownEventRoutingStrategy.Direct으로 정의됩니다. 이는 이벤트를 수신하는 컨트롤로만 라우팅됨을 의미합니다.

대신 Mouse.MouseDownEvent 이벤트를 사용하고 싶습니다. UIElement 및 기타 클래스는 내부적으로 이것을 MouseLeftButtonDownEvent으로 변환합니다.

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

내 의견으로는 잘못 될 수도 있습니다 -하지만 적어도 나는 InputManager에 꽤 길이 얼마 전에 보았다 : 당신이 MouseButton.Left에 e.ChangedButton을 설정해야합니다.

내 이력서는 다음과 같습니다. 버블 링 및 터널링은 InputManager입니다. 그러나 uielement.Raise()을 호출하면 이벤트가 직접 전달됩니다 (Ray Burns가 언급 한대로 RoutingStrategy에 관계없이).

그러나 RoutingStrategyInputManager에 따라 (추측하는 것은) 위로 CompositionRoot 사이의 시각적 트리 아래로 이동하고 VisualTreeHlper.Hittest()- 비주얼 에드와 터널링 및 bublling 이벤트를 제공합니다.

은 InputManager를 통해 이벤트를 발생시킬 수있는 방법이있다, 그러나 공식 아니며 (나는 다른 유래 포스트에서이) 반사를 필요 :

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