2016-07-29 35 views
2

Wie zeichnet man eine Linie wie die Windows Paint, klicken Sie einfach für einen festen ersten Punkt, und der zweite Punkt (und die Linie) bewegt sich mit der Maus, ein weiterer Klick behebt die Linie.C# Linien zeichnen mit ziehen

int x = 0, y = 0; 
protected override void OnMouseMove(MouseEventArgs e) 
{ 
    base.OnMouseMove(e); 
    // Create the graphics object 
    Graphics g = CreateGraphics(); 
    // Create the pen that will draw the line 
    Pen p = new Pen(Color.Navy); 
    // Create the pen that will erase the line 
    Pen erase = new Pen(Color.White); 
    g.DrawLine(erase, 0, 0, x, y); 
    // Save the mouse coordinates 
    x = e.X; y = e.Y; 
    g.DrawLine(p, 0, 0, x, y); 
} 

Das Klicken Ereignis Teil ist in Ordnung, aber mit dieser Methode oben ist die Löschleitung tatsächlich weiße Linien, die auf anderem Hintergrundbild überlappt und vorher blaue Linien aufgetragen.

Gibt es einen überschaubaren Weg, dies zu erreichen? Danke

+0

suchen Sie, um das resultierende Bild anschließend zu speichern? – Takarii

Antwort

1

Jede Zeichnung im Formular-Client-Bereich sollte im OnPaint-Ereignis implementiert werden, um irgendwelche seltsamen Effekte zu vermeiden. Betrachten Sie das folgende Codefragment:

Point Latest { get; set; } 

List<Point> _points = new List<Point>(); 

protected override void OnMouseMove(MouseEventArgs e) 
{ 
    base.OnMouseMove(e); 

    // Save the mouse coordinates 
    Latest = new Point(e.X, e.Y); 

    // Force to invalidate the form client area and immediately redraw itself. 
    Refresh(); 
} 

protected override void OnPaint(PaintEventArgs e) 
{ 
    var g = e.Graphics; 
    base.OnPaint(e); 

    if (_points.Count > 0) 
    { 
     var pen = new Pen(Color.Navy); 
     var pt = _points[0]; 
     for(var i=1; _points.Count > i; i++) 
     { 
      var next = _points[i]; 
      g.DrawLine(pen, pt, next); 
      pt = next; 
     } 

     g.DrawLine(pen, pt, Latest); 
    } 
} 

private void Form1_MouseClick(object sender, MouseEventArgs e) 
{ 
    Latest = new Point(e.X, e.Y); 
    _points.Add(Latest); 
    Refresh(); 
} 
+0

Danke, ich habe es gerade ausprobiert. Es ist ziemlich ordentlich, aber mit der Refresh-Methode behält es keine vorherigen Zeilen. Sobald ich eine neue Linienzeichnung starte, ist die vorherige weg. Gibt es eine Möglichkeit, alle vorherigen Zeilen zu behalten? – tomu

+0

Dann können Sie alle vorherigen Punkte aus dem Ereignis ** OnClick() ** in einer Liste speichern und dann aus dem ** OnPaint() ** zeichnen. – Jackdaw

+0

Bitte beachten Sie das aktualisierte Code-Fragment oben in der Antwort. – Jackdaw

1

Versuchen Sie nicht, die Linien zu löschen, indem Sie auf sie zeichnen. Sie sind besser dran, wenn Sie in einen Offscreen-Puffer zeichnen und bei jedem Zeichenaufruf diese Bitmap auf das Steuerelement malen. Auf diese Weise erhalten Sie flimmerfreie Grafiken und eine klare Linie, die genau so funktioniert, wie Sie es möchten.

Werfen Sie einen Blick auf this forum post für eine gute Erklärung, wie Sie die Klasse Graphics verwenden und Zeichnung im Allgemeinen tun sollten. Es gibt auch ein gutes Beispielprogramm am Ende des Posts. Ich schlage vor, dass Sie sich den Quellcode ansehen, nachdem Sie die Anweisungen durchgelesen haben.