C# 元件拖拉移動(C# ~ riser diagram)

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)

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *