Поднятие события WPF MouseLeftButtonDownEvent
Я пытаюсь поднять MouseLeftButtonDownEvent, продувив его в дереве Visual
со следующим кодом.
MouseButtonEventArgs args = new MouseButtonEventArgs(Mouse.PrimaryDevice,0, MouseButton.Left);
args.RoutedEvent = UIElement.MouseLeftButtonDownEvent;
args.Source = this;
RaiseEvent(args);
По какой-то причине компоненты более высокого уровня не получают это событие с пузырьками.
Я что-то пропускаю или не могу поднять это событие мыши.
Ответы
Ответ 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()
будет только когда-либо доставлять событие напрямую (независимо от RoutingStrategy
, как упоминалось в Ray Burns).
Но (угадывание) в зависимости от RoutingStrategy
InputManager
идет вверх и вниз по визуальному дереву между CompositionRoot
и VisualTreeHlper.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);
}