Avatar billede MikkelNielsen Nybegynder
27. oktober 2010 - 23:55 Der er 13 kommentarer

Forhindre at panel scroller med mousewheel

Hej,

Jeg har en form med et panel, hvorpå der er en PictureBox. Meningen er, mousewheel her skal have 2 funktioner:

Funktion 1: Hvis billedet er stort, skal panelet scrolle op eller ned.

Funktion 2: Hvis man holder ALT-knappen inde, skal billedet zoome ind eller ud, men panelet må IKKE scrolle.

Hvordan gør jeg det? Jeg har manuelt sat panelet i fokus, så den modtager events i min event handler:

public MainForm()
{
    InitializeComponent();
    panelImage.Focus();
    this.panelImage.MouseWheel += new MouseEventHandler( panelImage_MouseWheel );
}

private void panelImage_MouseWheel( object sender, MouseEventArgs e )
{
    if( Control.ModifierKeys == Keys.Alt )
    {
        // Do something and prevent scroll.
        // ...
        ( (HandledMouseEventArgs) e ).Handled = true;
    }
    else
    {
        // Scroll normally.
        ( (HandledMouseEventArgs) e ).Handled = false;
    }
}

Problemet er, at ovenstående bare ikke virker helt. Den gør det, den skal, når man holder ALT inde og bruger mousewheel, men den scroller desværre også.

Hvordan får man den til at lade være med det? :)

På forhånd tak.
Avatar billede Syska Mester
28. oktober 2010 - 00:04 #1
Er der ikke en Scoll event på det Panel? eller andet hvor du kan markere den event som Handled ?

mvh
Avatar billede MikkelNielsen Nybegynder
28. oktober 2010 - 00:35 #3
buzzzz

Virker desværre heller ikke, jf. dokumentationen:

Scroll: Occurs when the user moves the scroll box.

Det vil sige, at jeg får eventen, hvis brugeren klikker på scroll-"håndtaget", men jeg får IKKE eventen, hvis jeg blot bruger mousewheel.

Æv. :(
Avatar billede Syska Mester
28. oktober 2010 - 00:47 #4
Men der står jo også:
The Scroll event occurs when the user scrolls through the client area by interacting with the scroll bars, or when the user navigates between controls and the active control scrolls into view. The Scroll event also occurs when you write code, such as setting the AutoScrollPosition property, that scrolls through the client area.

Derfor jeg ville mene det virker, da du med mouse wheel jo styrer dine scrollbars.

mvh
Avatar billede bkp Nybegynder
28. oktober 2010 - 07:39 #5
Problemet ligger faktisk et helt andet sted!!
En Panel kan ikke få fokus, så derfor trigger den slet ikke MouseWheel eventen, så du skal køre din event på Formen istedet, og tjekke om Panel er under musen, det kan gøres således:


public MainForm()
{
    InitializeComponent();
    this.MouseWheel += new MouseEventHandler(panelImage_MouseWheel);
}
private Control GetCtrlUnderMouse()
{
    return this.Controls.Cast<Control>().FirstOrDefault(c => c.Bounds.Contains(this.PointToClient(MousePosition)));
}
private void panelImage_MouseWheel(object sender, MouseEventArgs e)
{
    var ctrl = GetCtrlUnderMouse();
    if (ctrl == null) return;
    if (!ctrl.Equals(panelImage)) return;
    if (Control.ModifierKeys == Keys.Alt)
    {
        // Do something and prevent scroll.
        // ...
        ((HandledMouseEventArgs)e).Handled = true;
    }
    else
    {
        // Scroll normally.
        ((HandledMouseEventArgs)e).Handled = false;
    }
}
Avatar billede bkp Nybegynder
28. oktober 2010 - 07:45 #6
Ovenstående er den nemmeste måde at tjekke for om panel er under musen, men du kan sikkert gøre det med MouseHover og MouseLeave eventen, det er i sidste ende nok mere resoucebesparende for din App.

Dette har jeg ikke testet, men det burde virke ;-)

private bool _panelHasFocus = false;
private void panelImage_MouseHover(object sender, EventArgs e)
{
    _panelHasFocus = true;       
}
private void panelImage_MouseLeave(object sender, EventArgs e)
{
    _panelHasFocus = false;
}
Avatar billede bkp Nybegynder
28. oktober 2010 - 08:49 #7
Lige en ting mere, der skal også tjekkes op imod din picturebox, for hvis din mus er over din picturebox, så du bliver nok nødt til at lave en MouseOver og MouseLeave på din picturebox ditto, så du sikrer dig at _panelHasFocus er sat korrekt, så det kunne gøres således:

private bool _panelHasFocus = false;
public MainForm()
{
    InitializeComponent();
    this.MouseWheel += new MouseEventHandler(OnMouseWheel);
    panelImage.MouseHover +=new EventHandler(OnMouseHover);
    panelImage.MouseLeave += new EventHandler(OnMouseLeave);
    pictureBox1.MouseHover += new EventHandler(OnMouseHover);
    pictureBox1.MouseLeave += new EventHandler(OnMouseLeave);
}
private void OnMouseWheel(object sender, MouseEventArgs e)
{
    if (!_panelHasFocus) return;
    if (Control.ModifierKeys == Keys.Alt)
    {
        // Do something and prevent scroll.
        ((HandledMouseEventArgs)e).Handled = true;
    }
    else
    {
        // Scroll normally.
        ((HandledMouseEventArgs)e).Handled = false;
    }
}
private void OnMouseHover(object sender, EventArgs e)
{
    _panelHasFocus = true;
}
private void OnMouseLeave(object sender, EventArgs e)
{
    _panelHasFocus = false;
}
Avatar billede bkp Nybegynder
28. oktober 2010 - 08:53 #8
Æh, det skal egentlig nok være MouseEnter istedet for MouseHover da den køres når mus bevæges, så det er ikke nødvendigt.
Avatar billede bkp Nybegynder
28. oktober 2010 - 08:57 #9
Så for lige at gøre en kort historie lang - og så håber vi browseren kan scrolle helt herned :-) - så kommer mit endelige forslag her:

private bool _panelHasFocus = false;
public FormMain()
{
    InitializeComponent();
    panelImage.Focus();
    this.MouseWheel += new MouseEventHandler(OnMouseWheel);
    panelImage.MouseEnter +=new EventHandler(OnMouseEnter);
    panelImage.MouseLeave += new EventHandler(OnMouseLeave);
    pictureBox1.MouseEnter += new EventHandler(OnMouseEnter);
    pictureBox1.MouseLeave += new EventHandler(OnMouseLeave);
}
private void OnMouseWheel(object sender, MouseEventArgs e)
{
    if (!_panelHasFocus) return;
    if (Control.ModifierKeys == Keys.Alt)
    {
        // Do something and prevent scroll.
        ((HandledMouseEventArgs)e).Handled = true;
    }
    else
    {
        // Scroll normally.
        ((HandledMouseEventArgs)e).Handled = false;
    }
}
private void OnMouseEnter(object sender, EventArgs e)
{
    _panelHasFocus = true;
}
private void OnMouseLeave(object sender, EventArgs e)
{
    _panelHasFocus = false;
}
Avatar billede MikkelNielsen Nybegynder
02. november 2010 - 23:18 #10
Undskyld at jeg ikke svarer før nu. :(

Bkp, du skal have stor tak for din indsats. Jeg er imidlertid bange for, at du misforstår mit problem lidt, for det virker på mig som om du tror, at min app. slet ikke får mouse-wheel eventen. Men det gør den. Og panelet scroller. Og det er netop det, jeg vil kunne slå til og fra, som jeg har lyst.

Jeg TROEDE, som skrevet i mit første indlæg, at jeg kunne slippe afsted med

( (HandledMouseEventArgs) e ).Handled = true;

i min mouse-wheel event handler, men det har ingen synlig effekt.

Mvh. Jan
Avatar billede Syska Mester
02. november 2010 - 23:22 #11
Hej,

Kan du lave et lille kode eksempel, så vil jeg se om jeg kan finde lidt tid til at lege med det ... det må kunne lade sig gøre.

mvh
Avatar billede bkp Nybegynder
03. november 2010 - 08:51 #12
I det eksempel jeg sendte tidligere, virker det for mig.
Hvilken .net version bruger du?

Prøv også at tjekke disse links:
http://stackoverflow.com/questions/479284/mouse-wheel-event-c
http://stackoverflow.com/questions/2432076/c-i-am-trying-to-make-a-zoom-effect

Har du afprøvet følgende:

private bool _panelHasFocus = false;
public FormMain()
{
    InitializeComponent();
    panelImage.Focus();
    this.MouseWheel += new MouseEventHandler(OnMouseWheel);
    panelImage.MouseEnter +=new EventHandler(OnMouseEnter);
    panelImage.MouseLeave += new EventHandler(OnMouseLeave);
    pictureBox1.MouseEnter += new EventHandler(OnMouseEnter);
    pictureBox1.MouseLeave += new EventHandler(OnMouseLeave);
}
private void OnMouseWheel(object sender, MouseEventArgs e)
{
    if (!_panelHasFocus) return;
    if (Control.ModifierKeys == Keys.Alt)
    {
        // Do something and prevent scroll.
        ((HandledMouseEventArgs)e).Handled = true;
    }
    else
    {
        // Scroll normally.
        ((HandledMouseEventArgs)e).Handled = false;
    }
}
private void OnMouseEnter(object sender, EventArgs e)
{
    _panelHasFocus = true;
}
private void OnMouseLeave(object sender, EventArgs e)
{
    _panelHasFocus = false;
}
Avatar billede MikkelNielsen Nybegynder
06. november 2010 - 15:03 #13
Jeg har prøvet med .net 2.0 og 4.0, men der er ikke nogen umiddelbar forskel på de to mht. opførsel. Intet virker!! Her er min fremgangsmåde:

Nyt projekt -> Windows App
Smid et panel på formen. Dock = Fill og AutoScroll = true.
Smid en picturebox på panelet. Dock = Fill og SizeMode = AutoSize. ImageLocation skal pege på et eller andet billede, der er for stort til at kunne vises i pictureboxen.

Kør programmet. Flyt musen ind på billedet. Brug scroll-wheel på musen. Intet sker. Hold ALT nede og brug scroll-wheelet. Intet sker.

Her er den komplette kode:

namespace PanelScrollTest
{
    partial class Form1
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose( bool disposing )
        {
            if( disposing && ( components != null ) )
            {
                components.Dispose();
            }
            base.Dispose( disposing );
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.panelImage = new System.Windows.Forms.Panel();
            this.pictureBox1 = new System.Windows.Forms.PictureBox();
            this.panelImage.SuspendLayout();
            ( (System.ComponentModel.ISupportInitialize) ( this.pictureBox1 ) ).BeginInit();
            this.SuspendLayout();
            //
            // panelImage
            //
            this.panelImage.AutoScroll = true;
            this.panelImage.Controls.Add( this.pictureBox1 );
            this.panelImage.Dock = System.Windows.Forms.DockStyle.Fill;
            this.panelImage.Location = new System.Drawing.Point( 0, 0 );
            this.panelImage.Name = "panelImage";
            this.panelImage.Size = new System.Drawing.Size( 394, 350 );
            this.panelImage.TabIndex = 0;
            //
            // pictureBox1
            //
            this.pictureBox1.ImageLocation = "c:\\largeImage.png";
            this.pictureBox1.Location = new System.Drawing.Point( 3, 3 );
            this.pictureBox1.Name = "pictureBox1";
            this.pictureBox1.Size = new System.Drawing.Size( 1531, 1114 );
            this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
            this.pictureBox1.TabIndex = 0;
            this.pictureBox1.TabStop = false;
            //
            // Form1
            //
            this.AutoScaleDimensions = new System.Drawing.SizeF( 6F, 13F );
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size( 394, 350 );
            this.Controls.Add( this.panelImage );
            this.Name = "Form1";
            this.Text = "Form1";
            this.panelImage.ResumeLayout( false );
            this.panelImage.PerformLayout();
            ( (System.ComponentModel.ISupportInitialize) ( this.pictureBox1 ) ).EndInit();
            this.ResumeLayout( false );

        }

        #endregion

        private System.Windows.Forms.Panel panelImage;
        private System.Windows.Forms.PictureBox pictureBox1;
    }
}

Ovenstående er det kode, designeren genererer. Her følger det kode, bkp og jeg har skrevet:

private bool _panelHasFocus = false;
public FormMain()
{
    InitializeComponent();
    panelImage.Focus();
    this.MouseWheel += new MouseEventHandler(OnMouseWheel);
    panelImage.MouseEnter +=new EventHandler(OnMouseEnter);
    panelImage.MouseLeave += new EventHandler(OnMouseLeave);
    pictureBox1.MouseEnter += new EventHandler(OnMouseEnter);
    pictureBox1.MouseLeave += new EventHandler(OnMouseLeave);
}
private void OnMouseWheel(object sender, MouseEventArgs e)
{
    if (!_panelHasFocus) return;
    if (Control.ModifierKeys == Keys.Alt)
    {
        // Do something and prevent scroll.
        ((HandledMouseEventArgs)e).Handled = true;
    }
    else
    {
        // Scroll normally.
        ((HandledMouseEventArgs)e).Handled = false;
    }
}

private void OnMouseEnter(object sender, EventArgs e)
{
    _panelHasFocus = true;
}

private void OnMouseLeave(object sender, EventArgs e)
{
    _panelHasFocus = false;
}
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester