Как получить событие MouseWheel, когда указатель мыши отсутствует в окне?
Я заметил, что мой MouseWheel
Обработчик событий выполняется только тогда, когда указатель мыши находится в окне. Я хочу, чтобы он запускал обработчик, даже когда указатель находится за пределами окна.
У меня есть только одно окно в моей программе, и его XAML имеет следующую структуру:
<Window ...
MouseWheel = "Window_MouseWheel">
....
</Window>
1 ответ
Чтобы получать события мыши, когда курсор покидает окно, в окне необходимо "захватить" мышь. Это делается путем передачи себя Mouse.Capture()
метод.
Обратите внимание, что если окно вашей программы теряет активацию (т. Е. Пользовательская задача переключается на какую-то другую программу), оно теряет захват мыши. Если вы хотите автоматически отслеживать колесо мыши снова, когда окно впоследствии повторно активируется пользователем, вам нужно будет обработать это специально (т.е. обработать Activated
событие).
Наконец, обратите внимание, что при включенном захвате мыши нормальное взаимодействие с окном с помощью мыши не работает, равно как и Alt - F4. Вам нужно будет предоставить пользователю некоторый механизм для дополнительного взаимодействия с программой (например, обрабатывать ключевые события).
Ниже приведен простой пример программы, которая показывает основную идею:
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#:
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;
}
}
}
Когда мышь захвачена, окно будет реагировать на события колеса мыши независимо от того, где находится курсор. Когда мышь не захвачена, она реагирует на события колеса мыши только тогда, когда курсор находится над окном.