2016-08-30 8 views
0
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를 끌 수 있지만 두 줄 사이의 링크가 제대로 작동하지 않습니다.패널 컨트롤 안에 둘 이상의 드래그 가능한 선 그리기

+2

또한 Paint 이벤트와 해당 e.Graphics 객체를 코딩하지 않아도됩니다. DrawLine 메소드의 결과는 비 지속 적입니다. (플러스 : 폐기 코드가 누락 및/또는 잘못 ..) – TaW

답변

1
  • DrawLine 코드는 잘못된 및/또는 귀하의 코드가 여기에

는 제안이다 상당히 중복 Dispose

  • 누락 된 꺼져; 최초의 적절한 using 조항 : 제외

    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); 
         } 
        } 
    

    으로 DrawLine 코드를 정리하자 : 이것은 당신이 control.CreateGraphics()을 사용하고자하는 드문 경우 중 하나입니다 참고; 마지막으로

    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); 
    } 
    

    :

    다음의 제네릭 마우스 이벤트를 만들어 보자 .. 결과 그래픽은 시스템이 양식을 다시 그려 whener가 사라집니다 즉, 비 영구적입니다,하지만 우리가 여기서 원하는 것입니다 우리는 후킹 같은 일반적인 이벤트에 모두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을 어떻게 만들 었는지 주목하십시오.

  • +0

    하지만 내가 texbox를 드래그하면 펜이 다시 한 번 라인을 다시 그려 넣습니다. 텍스트 상자를 끌 때 선의 동적 시작점과 끝 위치를 변경하려고합니다. – Vinoth

    +0

    오, TextBox를 이동 한 다음 사라지는 동안에 만 선이 표시된다는 것을 의미합니까? 이를 위해 MouseUp 이벤트의 끝 부분에'panel1.Invalidate();'를 삽입하면됩니다. 중복성을 제거하는 업데이트 대답을 참조하십시오 .. – TaW

    +0

    잘 작동합니다. 고맙습니다. – Vinoth