為了實現滑動的功能,需要用到【Timer對象】的協助。為此需要在【表單類的建構函式】裡面添加一下代碼:
//必須要在此顯式聲明這個用於滑動的Timer控制項,才能減少每次調用的延遲。 myTimer = new Timer(); myTimer.Interval = intTimerInterval; myTimer.Tick += new System.EventHandler(this.myTimer_Tick);
以下代碼直接綁定到你想要添加此功能的按鈕的相應事件上即可:
#region 可移動 + 滑動 + 反彈按鈕“相關代碼” #region 變數聲明區 /// <summary> /// 設定單擊哪個按鍵可以移動按鈕 /// </summary> MouseButtons MouseButton = MouseButtons.Right; //傳遞當前的按鈕。 Button btnTemp = null; //用於滑動的計算的計時器。 Timer myTimer = null; //計時器的每次觸發間隔(毫秒單位) int intTimerInterval = 20; //按鈕滑動的幀數,越大過渡越平滑。 static int intNum = 30; //幀數的臨時變數 int intTimer = intNum; //移動前後的時間。 DateTime datBegin,datEnd; //移動前後的座標 Point poiBegin,poiEnd; //加速度以0.12倍數變小 //阻力的加速度 double intB = 0.12; //滑動的增幅大小,越大則滑動速度越快越遠。 //末速度 double xV; double yV; //X和Y的加速度。 double xA; double yA; //記錄當前滑鼠相對於按鈕的位置。 Point mouse_offset = new Point(); bool bolMove=false; //是否允許反彈 bool bolReturn = true; #endregion #region 相關事件區 private void Button_MouseDown(object sender , MouseEventArgs e) { if ( e.Button == MouseButton ) { btnTemp = (Button)sender; //bolMove = true; //將當前滑鼠相對於“表單”左上方的座標賦值給mouse_offset mouse_offset = e.Location; //記下系統時間。以便計算速度 datBegin = DateTime.Now; poiBegin = btnTemp.Location; } } private void Button_MouseUp(object sender , MouseEventArgs e) { if ( bolMove && e.Button == MouseButton ) { //bolMove = false; //記下末後的座標 poiEnd = ( (Button)sender ).Location; datEnd = DateTime.Now; #region 加速度相關公式 //開始計算X和Y的加速度。 //S=VoT+1/2AT*T //末速度V = VoT + AT //當Vo = 0時,A = 2S/(T*T);V = 2S/T #endregion int xS = poiEnd.X - poiBegin.X; int yS = poiEnd.Y - poiBegin.Y; double t = datEnd.Subtract(datBegin).TotalMilliseconds; xA = ( 2 * xS ) / ( t * t ); yA = ( 2 * yS ) / ( t * t ); xV = ( 2 * xS ) / t; yV = ( 2 * yS ) / t; //重設為預設幀數。 intTimer = intNum; //啟動Timer控制項,開始緩緩滑動… myTimer.Enabled = true; } } private void Button_MouseMove(object sender , MouseEventArgs e) { if ( e.Button == MouseButton ) { bolMove = true; //將相對螢幕座標轉換為相對工作區的座標。 int left = PointToClient(Control.MousePosition).X - mouse_offset.X; int top = PointToClient(Control.MousePosition).Y - mouse_offset.Y; //左右可能越界 if ( left < 0 ) left = 0; if ( left > this.Width ) left = this.Width - ( (Button)sender ).Width; //上下可能越界 if ( top < 0 ) top = 0; if ( top > this.Height ) top = this.Height - ( (Button)sender ).Height; ( (Button)sender ).Left = left; ( (Button)sender ).Top = top; } } private void myTimer_Tick(object sender , EventArgs e) { //只要進入滑動模式,則代表滑鼠(手動)移動的停止。 if ( bolMove ) bolMove = false; if ( intTimer == 0 || xA == 0 || yA == 0 ) { myTimer.Enabled = false; } else { intTimer--; if ( xA < 0 ) btnTemp.Left = btnTemp.Left - (int)( xA * xV * 1000 ); else btnTemp.Left = btnTemp.Left + (int)( xA * xV * 1000 ); if ( yA < 0 ) btnTemp.Top = btnTemp.Top - (int)( yA * yV * 1000 ); else btnTemp.Top = btnTemp.Top + (int)( yA * yV * 1000 ); xA = xA * ( 1 - intB ); yA = yA * ( 1 - intB ); //左右可能越界,改變符號後實現碰壁之後自動“反彈”; if ( btnTemp.Left < 0 ) { btnTemp.Left = 0; if ( bolReturn ) { xA = -xA; xV = -xV; } } if ( btnTemp.Left > this.Width - btnTemp.Width ) { btnTemp.Left = this.Width - btnTemp.Width; if ( bolReturn ) { xA = -xA; xV = -xV; } } //上下可能越界 if ( btnTemp.Top < 0 ) { btnTemp.Top = 0; if ( bolReturn ) { yA = -yA; yV = -yV; } } if ( btnTemp.Top > this.Height - btnTemp.Height ) { btnTemp.Top = this.Height - btnTemp.Height; if ( bolReturn ) { yA = -yA; yV = -yV; } } } } #endregion #endregion
[By:Asion Tang] 部落格園 標籤: c#,個人程式碼程式庫