当鼠标指针不在窗口中时,如何接收鼠标滚轮事件?

时间:2023-01-28 10:37:21

I noticed that my MouseWheel event handler is only executed when the mouse pointer is in the window. I want it to run the handler even when the pointer is outside the window.

我注意到,我的鼠标滚轮事件处理程序只在鼠标指针位于窗口时执行。我想让它运行处理器,即使指针在窗口之外。

I only have one window in my program and its XAML is structured as below:

我的程序中只有一个窗口,它的XAML结构如下:

<Window ...
 MouseWheel = "Window_MouseWheel">
....
</Window>

1 个解决方案

#1


0  

In order to receive mouse events when the cursor leaves the window, the window needs to "capture" the mouse. It does this by passing itself to the Mouse.Capture() method.

为了在光标离开窗口时接收鼠标事件,窗口需要“捕获”鼠标。它通过将自己传递给Mouse.Capture()方法来实现这一点。

Note that if your program window loses activation (i.e. the user task-switches to some other program), it will lose the mouse capture. If you want to automatically track the mouse wheel again when the window is later reactivated by the user, you'll need to handle that specifically (i.e. handle the Activated event).

注意,如果您的程序窗口失去了激活(例如,用户任务切换到其他程序),它将失去鼠标捕获。如果您希望在用户稍后重新激活窗口时再次自动跟踪鼠标滚轮,则需要特别处理该操作(即处理已激活的事件)。

Finally note that with mouse capture enabled, the normal interaction with the window via the mouse doesn't work, nor will Alt-F4. You will need to provide the user with some mechanism for additionally interacting with the program (e.g. handle key events).

最后请注意,在启用了鼠标捕获后,通过鼠标与窗口的正常交互不起作用,Alt-F4也不会。您需要为用户提供一些与程序交互的机制(例如处理关键事件)。

Below is a simple example program that shows the basic idea:

下面是一个简单的示例程序,展示了基本思想:

XAML:

XAML:

<Window x:Class="TestSO30866523CaptureMouseWheel.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:l="clr-namespace:TestSO30866523CaptureMouseWheel"
        DataContext="{Binding RelativeSource={RelativeSource Self}}"
        Activated="Window_Activated"
        KeyDown="Window_KeyDown"
        MouseWheel="Window_MouseWheel"
        Title="MainWindow" Height="350" Width="525">
  <StackPanel x:Name="stackPanel1">
    <TextBlock Text="The window cannot be closed while mouse is captured."/>
    <TextBlock Text="Press Escape to stop capture. Press Return to resume capture."/>
    <TextBlock Text="{Binding Value, StringFormat=Value: {0}}"/>
    <TextBlock Text="{Binding MouseCaptured, StringFormat=Mouse is captured: {0}}"/>
  </StackPanel>
</Window>

C#:

c#:

public partial class MainWindow : Window
{
    public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(
        "Value", typeof(int), typeof(MainWindow), new PropertyMetadata(0));
    public static readonly DependencyProperty MouseCapturedProperty = DependencyProperty.Register(
        "MouseCaptured", typeof(bool), typeof(MainWindow));

    public int Value
    {
        get { return (int)GetValue(ValueProperty); }
        set { SetValue(ValueProperty, value); }
    }

    public bool MouseCaptured
    {
        get { return (bool)GetValue(MouseCapturedProperty); }
        set { SetValue(MouseCapturedProperty, value); }
    }

    private readonly IInputElement _captureElement;

    public MainWindow()
    {
        InitializeComponent();

        _captureElement = this;

        Mouse.AddGotMouseCaptureHandler((DependencyObject)_captureElement, stackPanel1_GotLostMouseCapture);
        Mouse.AddLostMouseCaptureHandler((DependencyObject)_captureElement, stackPanel1_GotLostMouseCapture);
        Mouse.Capture(_captureElement);
        MouseCaptured = Mouse.Captured != null;
    }

    private void stackPanel1_GotLostMouseCapture(object sender, MouseEventArgs e)
    {
        MouseCaptured = Mouse.Captured != null;
    }

    private void Window_MouseWheel(object sender, MouseWheelEventArgs e)
    {
        Value += e.Delta;
    }

    private void Window_Activated(object sender, EventArgs e)
    {
        Mouse.Capture(_captureElement);
    }

    private void Window_KeyDown(object sender, KeyEventArgs e)
    {
        switch (e.Key)
        {
        case Key.Escape:
            Mouse.Capture(null);
            break;
        case Key.Return:
            Mouse.Capture(_captureElement);
            break;
        }
    }
}

When the mouse is captured, the window will respond to mouse wheel events regardless of where the cursor is placed. When the mouse is not captured, it responds to the mouse wheel events only when the cursor is over the window.

当鼠标被捕获时,无论光标放在哪里,窗口都会对鼠标滚轮事件做出响应。当鼠标未被捕获时,它只在光标位于窗口上方时才对鼠标滚轮事件做出响应。

#1


0  

In order to receive mouse events when the cursor leaves the window, the window needs to "capture" the mouse. It does this by passing itself to the Mouse.Capture() method.

为了在光标离开窗口时接收鼠标事件,窗口需要“捕获”鼠标。它通过将自己传递给Mouse.Capture()方法来实现这一点。

Note that if your program window loses activation (i.e. the user task-switches to some other program), it will lose the mouse capture. If you want to automatically track the mouse wheel again when the window is later reactivated by the user, you'll need to handle that specifically (i.e. handle the Activated event).

注意,如果您的程序窗口失去了激活(例如,用户任务切换到其他程序),它将失去鼠标捕获。如果您希望在用户稍后重新激活窗口时再次自动跟踪鼠标滚轮,则需要特别处理该操作(即处理已激活的事件)。

Finally note that with mouse capture enabled, the normal interaction with the window via the mouse doesn't work, nor will Alt-F4. You will need to provide the user with some mechanism for additionally interacting with the program (e.g. handle key events).

最后请注意,在启用了鼠标捕获后,通过鼠标与窗口的正常交互不起作用,Alt-F4也不会。您需要为用户提供一些与程序交互的机制(例如处理关键事件)。

Below is a simple example program that shows the basic idea:

下面是一个简单的示例程序,展示了基本思想:

XAML:

XAML:

<Window x:Class="TestSO30866523CaptureMouseWheel.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:l="clr-namespace:TestSO30866523CaptureMouseWheel"
        DataContext="{Binding RelativeSource={RelativeSource Self}}"
        Activated="Window_Activated"
        KeyDown="Window_KeyDown"
        MouseWheel="Window_MouseWheel"
        Title="MainWindow" Height="350" Width="525">
  <StackPanel x:Name="stackPanel1">
    <TextBlock Text="The window cannot be closed while mouse is captured."/>
    <TextBlock Text="Press Escape to stop capture. Press Return to resume capture."/>
    <TextBlock Text="{Binding Value, StringFormat=Value: {0}}"/>
    <TextBlock Text="{Binding MouseCaptured, StringFormat=Mouse is captured: {0}}"/>
  </StackPanel>
</Window>

C#:

c#:

public partial class MainWindow : Window
{
    public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(
        "Value", typeof(int), typeof(MainWindow), new PropertyMetadata(0));
    public static readonly DependencyProperty MouseCapturedProperty = DependencyProperty.Register(
        "MouseCaptured", typeof(bool), typeof(MainWindow));

    public int Value
    {
        get { return (int)GetValue(ValueProperty); }
        set { SetValue(ValueProperty, value); }
    }

    public bool MouseCaptured
    {
        get { return (bool)GetValue(MouseCapturedProperty); }
        set { SetValue(MouseCapturedProperty, value); }
    }

    private readonly IInputElement _captureElement;

    public MainWindow()
    {
        InitializeComponent();

        _captureElement = this;

        Mouse.AddGotMouseCaptureHandler((DependencyObject)_captureElement, stackPanel1_GotLostMouseCapture);
        Mouse.AddLostMouseCaptureHandler((DependencyObject)_captureElement, stackPanel1_GotLostMouseCapture);
        Mouse.Capture(_captureElement);
        MouseCaptured = Mouse.Captured != null;
    }

    private void stackPanel1_GotLostMouseCapture(object sender, MouseEventArgs e)
    {
        MouseCaptured = Mouse.Captured != null;
    }

    private void Window_MouseWheel(object sender, MouseWheelEventArgs e)
    {
        Value += e.Delta;
    }

    private void Window_Activated(object sender, EventArgs e)
    {
        Mouse.Capture(_captureElement);
    }

    private void Window_KeyDown(object sender, KeyEventArgs e)
    {
        switch (e.Key)
        {
        case Key.Escape:
            Mouse.Capture(null);
            break;
        case Key.Return:
            Mouse.Capture(_captureElement);
            break;
        }
    }
}

When the mouse is captured, the window will respond to mouse wheel events regardless of where the cursor is placed. When the mouse is not captured, it responds to the mouse wheel events only when the cursor is over the window.

当鼠标被捕获时,无论光标放在哪里,窗口都会对鼠标滚轮事件做出响应。当鼠标未被捕获时,它只在光标位于窗口上方时才对鼠标滚轮事件做出响应。