1. 程式人生 > >C# 中手動新增Mousewheel滑鼠滾輪事件

C# 中手動新增Mousewheel滑鼠滾輪事件

如果將窗體或容器控制元件(如Panel控制元件)的AutoScroll屬性設定為True時,那麼當窗體或Panel容不下其中的子控制元件時就會出現 滾動條,通過移動滾動條可以上下顯示出窗體或Panel中的全部內容。但是預設情況下滾動條的移動只能通過滑鼠直接拖動滾動條來實現,而不能通過滑鼠的滾 輪來實現上下移動,因此需要手動新增程式碼來實現這個功能。

滾動滑鼠的滾輪,觸發的是窗體或控制元件上的 MouseWheel 事件。但是在VS.net2005中,窗體和控制元件的事件列表中卻不包含 MouseWheel 事件,因此關於這個事件的全部程式碼必須手動輸入。這裡以新增一個Panel的 MouseWheel 事件為例。首先在窗體的建構函式或InitializeComponent函式中,新增對MouseWheel 事件的訂閱:

this.Panel.MouseWheel+=newSystem.Windows.Forms.MouseEventHandler(this.Panel_MouseWheel);

這樣只是使Panel能接收滑鼠的滾動事件,但還不能實現滾動條的上下移動,因此還需要新增以下程式碼:

privatevoidPanel_MouseWheel(object sender,MouseEventArgs e){Panel.VerticalScroll.Value+=10;Panel.Refresh();Panel.Invalidate();Panel.Update();}

如果添加了以上程式碼,就認為萬事大吉了,那就大錯特錯了。執行以上的程式,可以發現,Panel控制元件並不能對滑鼠滾輪事件做出反應,原因是 Panel控制元件預設不能獲得焦點,因此它就不能捕獲滑鼠,也就不能捕獲滑鼠的滾輪事件。解決方法是讓Panel控制元件先獲得焦點,可以通過Panel的 MouseClick事件或MouseEnter事件來執行this.Panel.Focus()以達到目的。這樣當滑鼠點選了Panel控制元件或移動到 Panel控制元件上時它就獲得了焦點。因此還需要新增以下程式碼:

privatevoidPanel_MouseClick(object sender,MouseEventArgs e){this.Panel.Focus();}

這樣再執行程式,就可以達到通過滑鼠滾動來移動滾動條的目的了。

除此之外還要說的一點是,觸發滑鼠的滾動事件後,處理事件的函式引數 MouseEventArgs e 中有個Delta屬性,預設情況下向上滾動e.Delta=120,向下滾動e.Delta=-120。

以上的程式還不是特別完美,因為當Panel控制元件較大而沒有顯示滾動條時,或滾動條已在最上方而滾輪又是向上滾動,或滾動條已在最下方而滾輪又 是向下滾動時,同樣會執行Panel.Refresh();Panel.Invalidate();Panel.Update();等窗體重繪程式碼,佔用 較多資源。因此可以在執行這些程式碼前先對Panel的當前狀況做判斷。完整的程式程式碼如下:

程式碼

publicpartialclassPlotInfoForm.Form{int lastRightPanelVerticalScrollValue=-1;//為滑鼠滾動事件提供一個靜態變數,用來儲存上次滾動後的VerticalScroll.ValuepublicPlotInfoForm(){InitializeComponent();this.rightPanel.MouseWheel+=newSystem.Windows.Forms.MouseEventHandler(this.rightPanel_MouseWheel);}//當滑鼠在右側面板上單擊時,啟用其滾動事件privatevoid rightPanel_MouseClick(object sender,MouseEventArgs e){this.rightPanel.Focus();}privatevoid rightPanel_MouseWheel(object sender,MouseEventArgs e){if(!(rightPanel.VerticalScroll.Visible==false||(rightPanel.VerticalScroll.Value==0&&e.Delta>0)||(rightPanel.VerticalScroll.Value==lastRightPanelVerticalScrollValue&&e.Delta<0))){
      rightPanel.VerticalScroll.Value+=10;
      lastRightPanelVerticalScrollValue=rightPanel.VerticalScroll.Value;
      rightPanel.Refresh();
      rightPanel.Invalidate();
      rightPanel.Update();}}}