私の意見は間違っているかもしれませんが、少なくとも、かなり前にかなり長い間 を調べましたInputManager
。
それからの私の履歴書は次のとおりです。バブリングとトンネリングはによって行われInputManager
ます。ただし、呼び出しuielement.Raise()
はイベントを直接配信するだけです ( RoutingStrategy
Ray Burns が言及したものに関係なく)。
しかし (推測) によって、RoutingStrategy
とed VisualInputManager
の間のビジュアル ツリーが上下に移動し、トンネリング イベントとバブリング イベントが配信されます。CompositionRoot
VisualTreeHlper.Hittest()-
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);
}