Событие MouseWheel с Picturebox?

Я хочу навести курсор на окно с картинками (или на все картинки и основную форму) и использовать колесо мыши для прокрутки. Однако мне не повезло. Написал pictureBox1.MouseWheel и проверяю дельту. Я установил точку останова, когда он! = 0. До сих пор, что бы я ни делал, ничего не получалось. Я тоже попробовал mousemove, и это не сработало. Однако нарушение оператора if работает. Я просто не могу заставить колесо работать.

Как сделать, чтобы окно изображения (или любой элемент управления в форме) вызывало событие колеса мыши?

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


person Community    schedule 03.08.2010    source источник
comment
Я знаю, что это старый вопрос. Но это было изменено для Windows 10. В Windows 10 все элементы управления, на которые наведена мышь, получают событие колесика мыши.   -  person LxL    schedule 16.06.2016


Ответы (5)


Windows не отправляет сообщение прокрутки мыши элементу управления, на который наведен курсор, оно отправляется элементу управления с фокусом. Вы уже знаете, как исправить фокус.

Такое поведение становится не интуитивно понятным из-за того, как работают браузеры и программы Office. Вы найдете код для изменения этого в моем ответе на странице эта ветка. Помните, что он работает в любом окне вашего приложения. Если это нежелательно, вам придется добавить фильтрацию к значению дескриптора.


ОБНОВЛЕНИЕ: это поведение было изменено в Win10. В нем есть новая системная настройка под названием «Прокручивать неактивные окна при наведении на них курсора», которая включена по умолчанию. Так что фокус больше не имеет значения, и теперь он работает очень похоже на то, как он ведет себя в браузере. Тестирование вашего приложения важно, вы можете увидеть, что происходит в более старой версии Windows, временно отключив системный параметр.

person Hans Passant    schedule 03.08.2010
comment
Отличный ответ. Вы действительно помогли мне со всеми потребностями в графическом интерфейсе. - person ; 04.08.2010

В этом ответе объясняется, как это сделать. Короче говоря, создайте событие MouseEnter для графического блока, которое просто фокусирует его. Тогда окно с картинками будет нормально получать события MouseWheel.

person ulatekh    schedule 23.01.2014
comment
Никогда не отнимайте у пользователя фокус клавиатуры из-за того, что была перемещена мышь! Это действительно очень-очень неприятный обходной путь. Не делай это! Кроме того, у меня это не работает. Даже если я установил фокус на pictureBox, я не получаю событие wheel. - person Elmue; 20.05.2015

Ответы здесь не работают для меня. У меня есть окно с картинками на прокручиваемой панели, и для правильного функционирования нужно еще немного поработать.

Что вам нужно сделать, так это перезаписать функцию OnMouseWheel() в форме. Там вы получаете событие колеса, и вы должны проверить, находится ли мышь внутри окна с картинками. Но этого недостаточно. Представьте, что вы показываете изображение размером 5000 x 5000 пикселей внутри прокручиваемой панели, которая показывает только небольшую часть изображения. Затем вы также должны проверить, находится ли указатель мыши над панелью и всеми ее родителями. Приведенный ниже код работает независимо от положения прокрутки полос прокрутки любого из родительских элементов управления pictureBox.

/// <summary>
/// This must be overridden in the Form because the pictureBox never receives MouseWheel messages
/// </summary>
protected override void OnMouseWheel(MouseEventArgs e)
{
    // Do not use MouseEventArgs.X, Y because they are relative!
    Point pt_MouseAbs = Control.MousePosition; 
    Control i_Ctrl = pictureBox;
    do
    {
        Rectangle r_Ctrl = i_Ctrl.RectangleToScreen(i_Ctrl.ClientRectangle);
        if (!r_Ctrl.Contains(pt_MouseAbs))
        {
            base.OnMouseWheel(e);
            return; // mouse position is outside the picturebox or it's parents
        }
        i_Ctrl = i_Ctrl.Parent;
    }
    while (i_Ctrl != null && i_Ctrl != this);

    // here you have the mouse position relative to the pictureBox if you need it
    Point pt_MouseRel = pictureBox.PointToClient(pt_MouseAbs);

    // Do your work here
    ....
}
person Elmue    schedule 20.05.2015

Просто переопределите MouseWheel формы и проверьте, находятся ли e.X и e.Y внутри области расположения PictureBox.

  protected override void OnMouseWheel(MouseEventArgs e)
    {
        if (e.X >= soundGraph.Location.X && e.X <= soundGraph.Location.X + soundGraph.Width
            &&
            e.Y >= soundGraph.Location.Y && e.Y <= soundGraph.Location.Y + soundGraph.Height)
        { // do what you have to
        }
        base.OnMouseWheel(e);
    }
person LolliPop    schedule 09.03.2019

Это также работает, если блок изображения не находится в позиции 0,0 в форме.

' =====================================================================================
'  Windows10 has a new system setting 
'   named "Scroll inactive windows when I hover over them", turned on by default.
' -------------------------------------------------------------------------------------
'  The following correction does the same for Windows 8 / 7 / XP
' =====================================================================================
Protected Overrides Sub OnMouseWheel(ByVal e As MouseEventArgs)
    Dim p As Point
    p = pbox_Graph.PointToClient(Me.PointToScreen(e.Location))
    If pbox_Graph.ClientRectangle.Contains(p) Then
        pbox_TimeGraph_MouseWheel(Me, e)
    Else
        MyBase.OnMouseWheel(e)
    End If
End Sub
person Livio Cicala    schedule 02.05.2020