Подтвердить что ты не робот

Поднятие события WPF MouseLeftButtonDownEvent

Я пытаюсь поднять MouseLeftButtonDownEvent, продувив его в дереве Visual со следующим кодом.

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

По какой-то причине компоненты более высокого уровня не получают это событие с пузырьками. Я что-то пропускаю или не могу поднять это событие мыши.

4b9b3361

Ответ 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);
    }