我正在尝试通过将其冒泡到Visual树来提升MouseLeftButtonDownEvent 使用以下代码。
MouseButtonEventArgs args = new MouseButtonEventArgs(Mouse.PrimaryDevice,0, MouseButton.Left);
args.RoutedEvent = UIElement.MouseLeftButtonDownEvent;
args.Source = this;
RaiseEvent(args);
由于某种原因,较高级别的组件未收到此冒泡事件。 我是否忽略了某些事情或者是否无法举起这个鼠标事件
答案 0 :(得分:21)
你的问题是你正在举起一个没有泡沫的事件。
MouseLeftButtonDownEvent
定义为RoutingStrategy.Direct
,这意味着它仅路由到接收事件的控件。
您想要使用Mouse.MouseDownEvent
事件。 UIElement
和其他类在内部将其转换为MouseLeftButtonDownEvent
。确保将e.ChangedButton设置为MouseButton.Left
:
RaiseEvent(new MouseButtonEventArgs(Mouse.PrimaryDevice, 0, MouseButton.Left)
{
RoutedEvent = Mouse.MouseDownEvent,
Source = this,
});
答案 1 :(得分:0)
在我看来,我可能错了 - 但至少我在前一段时间看了InputManager
。
我的简历是:冒泡和隧道掘进由InputManager
完成。但是,调用uielement.Raise()
只会直接传递事件(无论RoutingStrategy
为Ray Burns mentioed)。
但是(猜测)取决于RoutingStrategy
,InputManager
在CompositionRoot
和VisualTreeHlper.Hittest()-
ed Visual之间的可视树上上下移动,并提供隧道和冒泡事件。< / p>
有一种方法可以通过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);
}