C# 元件拖拉移動(C# ~ riser diagram)
C# 元件拖拉移動(C# ~ riser diagram)
GITHUB : https://github.com/jash-git/CS-riser-diagram
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Drawing.Drawing2D;
namespace Graphic
{
public partial class FrmSchema : Form//主表單
{
public FrmSchema()
{
InitializeComponent();
this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);//表單繪圖不閃爍_step01
}
private const int Nmax = 50;//容器的最大數量
public GScenario GNetwork;//元件紀錄容器
private const int XTextPixelOffset = 0;
private const int YTextPixelOffset = 80;//元件文字敘述的Y軸距離
private const int XManageFormPixelOffset = 10;//管理表單像素偏移量
private const int YManageFormPixelOffset = 10;//管理表單像素偏移量
private int CurrObjDragIndx = 0;
private int Xdown = 0;
private int Ydown = 0;
private DateTime Tdown;
private int DragTimeMin = 300; // milliseconds
private bool Dragging = false;
private void Form1_Load(object sender, EventArgs e)//程式進入點
{
GNetwork = new GScenario(Nmax);//建立元件紀錄容器
GNetwork.Clear();//清空元件紀錄容器
GNetwork.CurrObjIndx = 0;//元件紀錄容器
}
private void AddText(int Xbase, int Ybase, string Msg, bool UseOffset)//元件的名稱文字新增函數(此範例是直接在表單上建立畫布並直接顯示)
{
Graphics g = this.CreateGraphics();//直接是在表單建立畫布
Font CurrFont = new Font("Arial", 8);
int x = 0;
int y = 0;
if (UseOffset == true)
{
x = Xbase + XTextPixelOffset;
y = Ybase + YTextPixelOffset;
}
else
{
x = Xbase;
y = Ybase;
}
g.DrawString(Msg, CurrFont, new SolidBrush(Color.Black), x, y);
}
private void AddText(Graphics g1,int Xbase, int Ybase, string Msg, bool UseOffset)//元件的名稱文字新增函數(此範例是直接在表單上建立畫布並直接顯示)
{
Graphics g = g1;//= this.CreateGraphics();//直接是在表單建立畫布
Font CurrFont = new Font("Arial", 8);
int x = 0;
int y = 0;
if (UseOffset==true)
{
x = Xbase + XTextPixelOffset;
y = Ybase + YTextPixelOffset;
}
else
{
x = Xbase;
y = Ybase;
}
g.DrawString(Msg, CurrFont, new SolidBrush(Color.Black), x, y);
}
public void AddGObject(int x1, int y1, int x2, int y2, string ObjType)//增加元件
{
Graphics g = this.CreateGraphics();//直接是在表單建立畫布
Rectangle ObjRct = new Rectangle();//建立一個矩形變數
Pen p = new Pen(Color.Blue);//建立藍色畫筆
Image ObjImg;//建立圖片元件
string ObjName = ObjType + "_" + GNetwork.LastIndexOfGObject(ObjType).ToString();//建立預設元件名稱
//
if (ObjType == "Line")//如果類型是線段
{
g.DrawLine(p, x1, y1, x2, y2);//把線段畫出來(藍色)
int xm = (x1 + x2) / 2;
int ym = (y1 + y2) / 2;
AddText(xm, ym, ObjName, false);//新增文字
}
else
{
ObjImg = FindGObjectTypeImage(ObjType);//載入對應圖片
ObjRct.X = x1;//設定矩形變數大小
ObjRct.Y = y1;//設定矩形變數大小
ObjRct.Height = ObjImg.Height;//設定矩形變數大小
ObjRct.Width = ObjImg.Width;//設定矩形變數大小
g.DrawImage(ObjImg, ObjRct);//匯出徒刑
AddText(x1, y1, ObjName, true);//新增文字
x2 = x1 + ObjRct.Width;//按照圖片實際大小修正參數
y2 = y1 + ObjRct.Height;//按照圖片實際大小修正參數
}
//
GNetwork.AddGObject(ObjName, ObjType, x1, y1, x2, y2);//新增元件
}
private Image FindGObjectTypeImage(string ObjType)//載入對應圖片函數
{
Image RetImg = null;
switch (ObjType)
{
case "Network":
RetImg = imageList1.Images[0];
break;
case "Router" :
RetImg = imageList1.Images[1];
break;
case "Emitter":
RetImg = imageList1.Images[2];
break;
case "Receiver":
RetImg = imageList1.Images[3];
break;
}
return RetImg;
}
private void ReDrawAll(PaintEventArgs e)//重會所有元件
{
//--
//表單繪圖不閃爍_step02
BufferedGraphicsContext currentContext = BufferedGraphicsManager.Current;
BufferedGraphics myBuffer = currentContext.Allocate(e.Graphics, e.ClipRectangle);
Graphics g = myBuffer.Graphics;
g.SmoothingMode = SmoothingMode.HighQuality;
g.PixelOffsetMode = PixelOffsetMode.HighSpeed;
g.Clear(this.BackColor);
//--
//Graphics g = this.CreateGraphics();//直接是在表單建立畫布
GObject CurrObj = new GObject();//建立元件
Rectangle Rct = new Rectangle();//建立矩形元件
Pen p = new Pen(Color.Blue);//建立畫筆
Image ObjImg;
int xm = 0;
int ym = 0;
string IsLine = "";
for (int i=0; i < GNetwork.Nobj;i++ )//依序取出元件
{
CurrObj = GNetwork.GObjects[i];
//
if (CurrObj.Type == "") IsLine = "N/D";
if (CurrObj.Type == "Line") IsLine = "Y";
if ((CurrObj.Type != "Line") && (CurrObj.Type != "")) IsLine = "N";
//
switch (IsLine)
{
case "Y":
g.DrawLine(p, CurrObj.x1, CurrObj.y1, CurrObj.x2, CurrObj.y2);
xm = (CurrObj.x1+CurrObj.x2)/2;
ym = (CurrObj.y1 + CurrObj.y2) / 2;
AddText(g,xm, ym, CurrObj.Name,false);
break;
case "N":
Rct.X = CurrObj.x1;
Rct.Y = CurrObj.y1;
Rct.Width = CurrObj.x2 - CurrObj.x1;
Rct.Height = CurrObj.y2 - CurrObj.y1;
if (CurrObj.Type != String.Empty)
{
ObjImg = FindGObjectTypeImage(CurrObj.Type);
g.DrawImage(ObjImg, Rct);
AddText(g,CurrObj.x1, CurrObj.y1, CurrObj.Name, true);
GNetwork.AdjustLinkedTo(CurrObj.Name);
}
break;
}
}
//--
//表單繪圖不閃爍_step03
myBuffer.Render(e.Graphics);
g.Dispose();
myBuffer.Dispose();//释放资源
//--
}
private void Form1_Paint(object sender, PaintEventArgs e)//防止C#,在FORM畫完圖後,將視窗縮小再放大,圖就消失
{
ReDrawAll(e);
}
private void Form1_MouseDoubleClick(object sender, MouseEventArgs e)
{
int Xclicked = 0;
int Yclicked = 0;
Dragging = false;
Xclicked = e.X;
Yclicked = e.Y;
GObject GContainer = new GObject();
GObject GModified = new GObject();
int Container = GNetwork.FindContainerObject(Xclicked, Yclicked, ref GContainer, false);
if (Container>-1)
{
GModified = GContainer;
FrmManageObject Manage = new FrmManageObject();
Manage.GObjName = GContainer.Name;
Manage.GObjType = GContainer.Type;
Point IniPoint = new Point(Xclicked + XManageFormPixelOffset, Yclicked + YManageFormPixelOffset);
Manage.StartPosition = FormStartPosition.Manual;
Manage.Location = IniPoint;
Manage.ShowDialog();
switch (Manage.OperationToDo)
{
case "Modify":
//
// Load New Data from the Manage Form
//
GModified.Name = Manage.GObjName;
GNetwork.ModifyGObject(GContainer, GModified);
break;
case "Delete":
//
// Delete the object with the original name
// not with then eventually modified name!
//
GNetwork.DeleteGObject(GContainer);
break;
}
this.Invalidate();
}
else
{
//
// nothing to do
//
}
}
private void routerToolStripMenuItem_Click(object sender, EventArgs e)//增加Router元件
{
int X = 0;
int Y = 25;
AddGObject(X, Y, 0, 0, "Router");
}
private void linkToolStripMenuItem_Click(object sender, EventArgs e)//增加Line元件
{
int X1 = 0;
int Y1 = 0;
int X2 = 100;
int Y2 = 100;
AddGObject(X1, Y1, X2, Y2, "Line");
}
private void Form1_MouseMove(object sender, MouseEventArgs e)//單純顯示座標到下面顯示區
{
string CoordsMsg = "";
CoordsMsg = "x = " + e.X.ToString() + " : y = " + e.Y.ToString();
toolStripStatusLabel1.Text = CoordsMsg;
MouseObject(e);
}
private void Form1_MouseDown(object sender, MouseEventArgs e)//判斷有無選到元件,並做變數變動
{
Xdown = e.X;
Ydown = e.Y;
Tdown = DateTime.Now;
GObject GContainer = new GObject();
int Container = GNetwork.FindContainerObject(Xdown, Ydown, ref GContainer,false);//判斷是否有選到元件
if (Container > -1)
{
Dragging = true;//拖曳成立
Cursor.Current = Cursors.Hand;//變換滑鼠
CurrObjDragIndx = Container;//紀錄目前元件的INDEX到全域變數
}
else
{
// Click out of all objects
}
}
public void MouseObject(MouseEventArgs e)
{
int H = 0;
int W = 0;
GObject GContainer = new GObject();
GObject GToDrag = new GObject();
GToDrag = GNetwork.GObjects[CurrObjDragIndx];//取出該元件實體
double d1 = 0;
double d2 = 0;
TimeSpan DTDrag = new TimeSpan();
DTDrag = DateTime.Now.Subtract(Tdown);//計算時間間隔
if ((Dragging == true) && (DTDrag.Milliseconds > DragTimeMin))
{
if ((GNetwork.GObjects[CurrObjDragIndx].Type == "Line")
&& (GNetwork.FindContainerObject(e.X, e.Y, ref GContainer, true) > -1))
{
//
// What is the point of the line to link ?
// The nearest to (Xdown,Ydown)
//
d1 = CommFnc.distance(Xdown, Ydown, GToDrag.x1, GToDrag.y1);
d2 = CommFnc.distance(Xdown, Ydown, GToDrag.x2, GToDrag.y2);
if (d1 <= d2)
{
GToDrag.x1 = (GContainer.x1 + GContainer.x2) / 2;
GToDrag.y1 = (GContainer.y1 + GContainer.y2) / 2;
GToDrag.Lnk1 = GContainer.Name;
}
else
{
GToDrag.x2 = (GContainer.x1 + GContainer.x2) / 2;
GToDrag.y2 = (GContainer.y1 + GContainer.y2) / 2;
GToDrag.Lnk2 = GContainer.Name;
}
}
else
{
W = GToDrag.x2 - GToDrag.x1;//移動元件的位置計算
H = GToDrag.y2 - GToDrag.y1;//移動元件的位置計算
GToDrag.x1 = e.X;//移動元件的位置計算
GToDrag.y1 = e.Y;//移動元件的位置計算
GToDrag.x2 = e.X + W;//移動元件的位置計算
GToDrag.y2 = e.Y + H;//移動元件的位置計算
GNetwork.AdjustLinkedTo(GToDrag.Name);
}
this.Refresh();//觸發重繪
}
}
private void Form1_MouseUp(object sender, MouseEventArgs e)//
{
MouseObject(e);
Cursor.Current = Cursors.Default;//換回滑鼠游標
Dragging = false;
}
private void exitToolStripMenuItem_Click(object sender, EventArgs e)//關閉程式
{
Application.Exit();
}
private void emitterToolStripMenuItem_Click(object sender, EventArgs e)//增加Emitter元件
{
int X = 0;
int Y = 25;
AddGObject(X, Y, 0, 0, "Emitter");
}
private void receiverToolStripMenuItem_Click(object sender, EventArgs e)//增加Receiver元件
{
int X = 25;//0;
int Y = 25;
AddGObject(X, Y, 0, 0, "Receiver");
}
private void loadToolStripMenuItem_Click(object sender, EventArgs e)//載入檔案
{
string LoadFileName = "";
string ErrLoading = "";
LoadFileName = CommFnc.FindFileToOpen();
GNetwork.Clear();
if (GNetwork.LoadFile(LoadFileName, ref ErrLoading) == true)
{
toolStripStatusLabel1.Text = "File loaded in memory.";
this.Refresh();//觸發重繪 //作者忘了寫(可能是故意的)
}
else
{
toolStripStatusLabel1.Text = ErrLoading;
}
}
private void saveToFileToolStripMenuItem_Click(object sender, EventArgs e)//儲存檔案
{
string SaveFileName = "";
string ErrSaving = "";
SaveFileName = CommFnc.AssignFileToSave();
if (GNetwork.SaveFile(SaveFileName, ref ErrSaving) == true)
{
toolStripStatusLabel1.Text = "File saved.";
}
else
{
toolStripStatusLabel1.Text = ErrSaving;
}
}
}
}
One thought on “C# 元件拖拉移動(C# ~ riser diagram)”
C# riser diagram 電子地圖