最近在工作上需要 用到 可移動的直線 與 可 改變的圓
網路上很多介紹可以用 API 畫,但我真的不想用 gdi32
也都沒找到 相關的介紹 或 範例,只好自己想辦法寫了一個
整體的演算法
建立一個可移動的小框(做直線兩端選取用)
兩個小框中心畫一直線
點選小框時,可移動,同時重繪 小框 與 直線
需先引用
System.Drawing
System.Drawing.Drawing2D
會使用到的技巧 GraphicPath
首先建立一個 小框的 Class
/// <summary>
/// 會移動的方框
/// </summary>
public class MovePoint
{
public Point p; //紀錄方框中心的位置
public Rectangle rect; //依中心位置要畫出的筐
//-----------------------------------------------------------------------------------------------------------------------------
public Rectangle Rect
{
get { return rect;}
set { rect = value;}
}
/// <summary>
/// 當移動方框十 方框位置重定
/// </summary>
/// <param name="p"></param>
public MovePoint(Point p)
{
this.p = p;
rect = new Rectangle(p.X - 3, p.Y - 3, 6, 6);
}
//-----------------------------------------------------------------------------------------------------------------------------
/// <summary>
/// 確定是否被選到
/// </summary>
/// <param name="e"></param>
/// <returns></returns>
public bool CheckSelect(Point e)
{
if (rect.Contains(e))
return true;
else
return false;
}
//-----------------------------------------------------------------------------------------------------------------------------
/// <summary>
/// 移動時重繪
/// </summary>
/// <param name="e"></param>
public void move(Point e)
{
this.p = e;
rect = new Rectangle(p.X - 3, p.Y - 3, 6, 6);
}
}
然後在 Form 上建立一個 Picturebox (個人喜歡用 Bitmap 繪圖)
然後在 Picturebox 上建立 Mouse_Down Mouse_up Mouse_Move 事件
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
Bitmap bm;
Graphics g;
GraphicsPath gp;
int mp_select = -1; //選擇方框的指標
bool dragging = false; //是否拖曳
Pen pen1 = new Pen(Color.Blue , 1); //化方框的筆
List<CDraw.MovePoint> mp = new List<CDraw.MovePoint>(); //儲存方框的List
//===================================================================================================================================
private void Form1_Load(object sender, EventArgs e)
{
//一啟動 就在上面先畫出 直線與兩個小框
bm = new Bitmap(pictureBox1.Width, pictureBox1.Height);
g = Graphics.FromImage(bm);
gp = new GraphicsPath();
CDraw.MovePoint MoveP;
MoveP = new CDraw.MovePoint(new Point(10, 100)); //第一個方框的中心,新建立時會自動設定大小
mp.Add(MoveP);
MoveP = new CDraw.MovePoint(new Point(400, 100)); //第一個方框的中心,新建立時會自動設定大小
mp.Add(MoveP);
gp.AddLine(mp[0].p, mp[1].p); //兩個方框中新 畫出一直線
gp.AddRectangle(mp[0].Rect); //將方框加入
gp.AddRectangle(mp[1].Rect);
g.DrawPath(pen1, gp); //將 GraphicPath 畫在畫布
pictureBox1.BackgroundImage = bm;
}
//===================================================================================================================================
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
for (int i = 0; i < 2; i++)
{
if (mp[i].CheckSelect(e.Location))
{ //檢查點選位置是否在某個小框
mp_select = i; //選到的小框編號
dragging = true; //有選到 可以拖曳
break;
}
}
}
//===================================================================================================================================
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
dragging = false;
}
//===================================================================================================================================
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (dragging)
{
mp[mp_select].move(e.Location);
bm = new Bitmap(pictureBox1.Width, pictureBox1.Height);
g = Graphics.FromImage(bm);
gp.Reset();
gp.AddLine(mp[0].p, mp[1].p);
foreach (CDraw.MovePoint mpp in mp)
{
gp.AddRectangle(mpp.Rect);
}
g.DrawPath(pen1, gp);
pictureBox1.BackgroundImage = bm;
}
}
}
程式啟動
改變線的位置 與 長短