首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# WinForms 圖片拖曳移動完整實作範例

     編輯:關於C語言

在 Windows Forms 中實作圖片的滑鼠拖曳移動,核心在於處理 MouseDown、MouseMove、MouseUp 三個事件,並配合自訂游標提升使用者體驗。本文提供完整可執行程式碼,並說明關鍵座標轉換邏輯。

核心邏輯與座標轉換

  1. MouseDown:記錄滑鼠按下時相對 PictureBox 的位置 (pClicked),切換為「抓取」游標,設定拖曳旗標。
  2. MouseMove:若正在拖曳,將目前螢幕座標轉換為表單用戶區座標,再減去 pClicked 得到新的 PictureBox.Location。
  3. MouseUp:清除拖曳旗標,恢復預設游標。

關鍵轉換:this.PointToClient(pictureBox1.PointToScreen(new Point(e.X, e.Y))) 將 PictureBox 內的滑鼠座標轉為表單用戶區座標。

完整程式碼

using System;
using System.Drawing;
using System.Windows.Forms;

namespace WindowsApplication2
{
    public partial class Form1 : Form
    {
        // Base64 編碼的游標資料(省略內容,實際使用請替換為有效資料)
        static string strDown = @"AAACAAEAICAAAAsACQAwAQAAFgAAACgAAAAgAAAAQAAAAAEAAQAAAAAAAAIAAAAA...";
        static string strUp = @"AAACAAEAICAAAAoACAAwAQAAFgAAACgAAAAgAAAAQAAAAAEAAQAAAAAAAAIAAA...";

        Cursor curUp, curDown;
        bool bDragging = false;
        Point pClicked;

        public Form1()
        {
            InitializeComponent();
            curUp = new Cursor(new MemoryStream(Convert.FromBase64String(strUp)));
            curDown = new Cursor(new MemoryStream(Convert.FromBase64String(strDown)));
            pictureBox1.Cursor = curUp;
        }

        private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                bDragging = true;
                pClicked = new Point(e.X, e.Y);
                pictureBox1.Cursor = curDown;
            }
        }

        private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
        {
            if (bDragging)
            {
                Point screenPos = pictureBox1.PointToScreen(new Point(e.X, e.Y));
                Point clientPos = this.PointToClient(screenPos);
                clientPos.Offset(-pClicked.X, -pClicked.Y);
                pictureBox1.Location = clientPos;
            }
        }

        private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
        {
            bDragging = false;
            pictureBox1.Cursor = curUp;
        }
    }
}

進階擴充建議

  • 邊界限制:在 MouseMove 中加入邏輯防止圖片移出表單可視區域。
  • 多圖層管理:維護 List<PictureBox> 並處理 Z-Order(BringToFront/SendToBack)。
  • 吸附對齊:移動時檢測與其他控制項邊緣距離,自動對齊。
  • 效能優化:大量圖片時考慮使用 DoubleBuffered 或自繪 (OnPaint) 避免閃爍。

替代方案比較

另一種常見做法是呼叫 Windows API SendMessage(hWnd, WM_SYSCOMMAND, SC_MOVE, 0) 模擬標題列拖曳,但該方法需表單無邊框 (FormBorderStyle.None) 且游標回饋較差。本文採用的純 managed 程式碼方案更穩定、可攜且易於擴充。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved