Вызов события WPF MouseLeftButtonDownEvent - PullRequest
12 голосов
/ 11 марта 2010

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

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

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

Ответы [ 2 ]

21 голосов
/ 11 марта 2010

Ваша проблема в том, что вы инициируете событие, которое не всплывает.

MouseLeftButtonDownEvent определяется как RoutingStrategy.Direct, что означает, что оно направляется только в элемент управления, получающий событие.

Вместо этого вы хотите использовать событие Mouse.MouseDownEvent.UIElement и другие классы внутренне преобразуют это в MouseLeftButtonDownEvent.Убедитесь, что для e.ChangedButton установлено значение MouseButton.Left:

RaiseEvent(new MouseButtonEventArgs(Mouse.PrimaryDevice, 0, MouseButton.Left)
{
  RoutedEvent = Mouse.MouseDownEvent,
  Source = this,
});
0 голосов
/ 16 октября 2015

Возможно, я ошибаюсь, но, по крайней мере, некоторое время назад я довольно долго смотрел на InputManager.

Мое резюме по этому вопросу: пузыри и туннелирование сделаны InputManager. Однако при вызове uielement.Raise() событие будет доставлено только напрямую (независимо от RoutingStrategy, о котором говорил Рэй Бернс).

Но (догадываясь) в зависимости от 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);
    }
...