2009-12-02 19 views
5

Ho aggiunto dinamicamente 20 picturebox a un pannello e vorrei vedere il pannello scorrere quando utilizzo la rotellina del mouse. Per implementare questo ho provato a impostare lo scorrimento automatico su true sul controllo del pannello. Ecco il codice. Per i come numero intero = 1 a 20:La rotellina del mouse scorre nel pannello con i controlli della casella immagine aggiunti dinamicamente?

 Dim b As New PictureBox() 
     b.Image = Nothing 
     b.BorderStyle = BorderStyle.FixedSingle 
     b.Text = i.ToString() 
     b.Size = New Size(60, 40) 
     b.Location = New Point(0, (i * b.Height) - b.Height) 
     b.Parent = Panel1 
     Panel1.Controls.Add(b) 
    Next 

Ho fatto la stessa cosa con comando a pulsante e funziona bene. Per i come numero intero = 1 a 100:

 Dim b As New Button() 

     b.Text = i.ToString() 
     b.Size = New Size(60, 40) 
     b.Location = New Point(0, (i * b.Height) - b.Height) 
     b.Parent = Panel1 
     Panel1.Controls.Add(b) 
    Next 

Si lavora per il controllo "pulsante", ma non per il "picturebox" o controlli "etichetta"? Come posso implementare l'effetto di scorrimento usando 'rotellina'?

risposta

6

Il pannello scorre con la rotellina del mouse quando questo o un controllo al suo interno ha la messa a fuoco. Il problema che si sta verificando è che né PictureBox né il pannello ricevono lo stato attivo quando si fa clic su di esso. Se chiami select() sul pannello, vedrai che la rotellina del mouse riprenderà a funzionare.

Una possibile soluzione potrebbe essere quella di selezionare il pannello ogni volta che il cursore del mouse entra, gestendo l'evento Control.MouseEnter:

void panel1_MouseEnter(object sender, EventArgs e) 
{ 
    panel1.select(); 
} 
3

"Cwick" è giusto, i messaggi di Windows la notifica WM_MOUSWHEEL alla finestra quello ha il focus. Funziona quando si inserisce un pulsante nel pannello perché può ottenere il focus. La prossima cosa che succede è che Windows continua a cercare un controllo Parent per prendere il messaggio. Button non si preoccuperà di esso, è Parent è il pannello e sarà felice di scorrere e consumare il messaggio.

Diverso dall'assegnazione dell'abilità di controllo dei controlli figlio (è necessario sovrascriverli e chiamare SetStyle (ControlStyles.Selectable)), è possibile modificare la modalità di gestione del messaggio. Molte app commerciali apparentemente non hanno questo problema (browser, app di Office) perché hanno solo poche finestre. Le app WF di solito hanno molto, una per ogni controllo. Fatelo elaborando il messaggio in anticipo, prima che venga inviato al controllo focalizzato. L'interfaccia IMessageFilter consente questo. Questo codice di esempio scorre il controllo sotto il mouse al posto del controllo che ha il focus:

using System; 
using System.ComponentModel; 
using System.Drawing; 
using System.Windows.Forms; 
using System.Runtime.InteropServices; 

namespace WindowsApplication1 { 
    public partial class Form1 : Form, IMessageFilter { 
    public Form1() { 
     InitializeComponent(); 
     Application.AddMessageFilter(this); 
    } 

    public bool PreFilterMessage(ref Message m) { 
     if (m.Msg == 0x20a) { 
     // WM_MOUSEWHEEL, find the control at screen position m.LParam 
     Point pos = new Point(m.LParam.ToInt32()); 
     IntPtr hWnd = WindowFromPoint(pos); 
     if (hWnd != IntPtr.Zero && hWnd != m.HWnd && Control.FromHandle(hWnd) != null) { 
      SendMessage(hWnd, m.Msg, m.WParam, m.LParam); 
      return true; 
     } 
     } 
     return false; 
    } 

    // P/Invoke declarations 
    [DllImport("user32.dll")] 
    private static extern IntPtr WindowFromPoint(Point pt); 
    [DllImport("user32.dll")] 
    private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp); 
    } 
} 

Attenzione che questo codice è attivo per qualsiasi finestra nella vostra applicazione. Assicurati di provarlo e verifica che non confonderà troppo l'utente.

Problemi correlati