簡體   English   中英

在面板控件內繪制多條可拖動線

[英]Draw more than one draggable line inside the panel control

namespace DraggableControls
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private Control activeControl;
        private Point previousLocation;

        void txt1_MouseDown(object sender, MouseEventArgs e)
        {
            activeControl = sender as Control;
            previousLocation = e.Location;
            Cursor = Cursors.Hand;            
        }
        void txt1_MouseUp(object sender, MouseEventArgs e)
        {
            activeControl = null;
            Cursor = Cursors.Default;
        }
        void txt1_MouseMove(object sender, MouseEventArgs e)
        {
            if (activeControl == null || activeControl != sender)
                return;
            Point location = activeControl.Location;
            location.Offset(e.Location.X - previousLocation.X, 
                            e.Location.Y - previousLocation.Y);
            activeControl.Location = location;
            DrawLine(txt1.Location, txt2.Location, panel1);
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            txt1.MouseDown += new MouseEventHandler(txt1_MouseDown);
            txt1.MouseMove += new MouseEventHandler(txt1_MouseMove);
            txt1.MouseUp += new MouseEventHandler(txt1_MouseUp);


            txt3.MouseDown += new MouseEventHandler(txt3_MouseDown);
            txt3.MouseMove += new MouseEventHandler(txt3_MouseMove);
            txt3.MouseUp += new MouseEventHandler(txt3_MouseUp);
        }



        void txt3_MouseDown(object sender, MouseEventArgs e)
        {
            activeControl = sender as Control;
            previousLocation = e.Location;
            Cursor = Cursors.Hand;
        }
        void txt3_MouseUp(object sender, MouseEventArgs e)
        {
            activeControl = null;
            Cursor = Cursors.Default;
        }
        void txt3_MouseMove(object sender, MouseEventArgs e)
        {
            if (activeControl == null || activeControl != sender)
                return;
            Point location = activeControl.Location;
            location.Offset(e.Location.X - previousLocation.X, 
                            e.Location.Y - previousLocation.Y);
            activeControl.Location = location;
            DrawLine(txt3.Location, txt4.Location, panel1);
        }

        public void DrawLine(Point start, Point end, Panel ctrl)
        {
            ctrl.Refresh();
            Pen P = new Pen(Color.Red, 3);
            P.StartCap = System.Drawing.Drawing2D.LineCap.NoAnchor;
            P.CustomEndCap = 
              new System.Drawing.Drawing2D.AdjustableArrowCap(4, 8, false);
            ctrl.CreateGraphics().DrawLine(P, start, end);
            ctrl.PerformLayout();
            ctrl.CreateGraphics().Dispose();
        }
    }
}

我想繪制一個可拖動的文本框並鏈接兩個文本框。 在這段代碼中,我可以拖動一個TextBox,但是兩行之間的鏈接不能正常工作。

  • DrawLine代碼因錯誤和/或缺少Dispose和而關閉
  • 您的代碼是多余的

這是一個建議; 首先讓我們使用適當的using子句清理DrawLine代碼:

    public void DrawLine(Point start, Point end, Control ctrl)
    {
        ctrl.Refresh();
        using ( Graphics g = activeControl.CreateGraphics())
        using ( Pen P = new Pen(Color.Red, 3) )
        {
          P.StartCap = System.Drawing.Drawing2D.LineCap.NoAnchor;
          P.CustomEndCap = 
            new System.Drawing.Drawing2D.AdjustableArrowCap(4, 8, false);
          g.DrawLine(P, start, end);
        }
    }

另外:請注意,這是您要使用control.CreateGraphics()的罕見情況之一; 生成的圖形是非持久的,即當系統重畫Form時,它們將消失,但這正是我們想要的。

接下來,讓鼠標事件具有通用性:

void txt_MouseDown(object sender, MouseEventArgs e)
{
    activeControl = sender as Control;
    previousLocation = e.Location;
    Cursor = Cursors.Hand;
}

void txt_MouseUp(object sender, MouseEventArgs e)
{
    activeControl = null;
    Cursor = Cursors.Default;
    panel1.Invalidate();
}

void txt_MouseMove(object sender, MouseEventArgs e)
{
    if (activeControl == null || activeControl != sender)
        return;
    Control tgtCtl = activeControl.Tag as Control;  // check the..
    if (tgtCtl == null) return;                     // target!

    Point location = activeControl.Location;
    location.Offset(e.Location.X - previousLocation.X, 
                    e.Location.Y - previousLocation.Y);
    activeControl.Location = location;

    DrawLine(location, tgtCtl.Location, activeControl.Parent);
}

最后,我們准備通過掛鈎兩個 TextBoxes相同的一般事件,並告訴每一個,這是其他TextBox將成為它的目標通過設置它的Tag

private void Form1_Load(object sender, EventArgs e)
{
    txt1.Tag = txt2;
    txt3.Tag = txt4;

    txt1.MouseDown += new MouseEventHandler(txt_MouseDown);
    txt1.MouseMove += new MouseEventHandler(txt_MouseMove);
    txt1.MouseUp += new MouseEventHandler(txt_MouseUp);

    txt3.MouseDown += new MouseEventHandler(txt_MouseDown);
    txt3.MouseMove += new MouseEventHandler(txt_MouseMove);
    txt3.MouseUp += new MouseEventHandler(txt_MouseUp);

    .. 
  }

還要注意我是如何通過使用activeControl.Parent使Panel通用的,可以是任何東西。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM