c# drawing line

c# - Cómo dibujar una línea de actualización



drawing line (1)

Mi objetivo es muy simple. Imagine abrir MSPaint, hacer clic en la herramienta de línea, mantener presionado el mouse y arrastrarlo. Ancla las coordenadas iniciales donde hizo clic con el mouse hacia abajo y constantemente dibuja y vuelve a dibujar una línea a su posición actual.

Excepto que tratar de hacer esto en C # no funciona tan bien como esperaba.

[DllImport("user32.dll")] static extern IntPtr GetDC(IntPtr hWnd); [DllImport("User32.dll")] static extern int ReleaseDC(IntPtr hwnd, IntPtr dc); protected override void OnPaint(PaintEventArgs e) { endingPoint = GetMouseCoords(); DrawLine(startingPoint, endingPoint); } private void DrawLine(Point startingCoords, Point endingCoords) { IntPtr desktop = GetDC(IntPtr.Zero); Pen pen = new Pen(Brushes.Red, 3); using (Graphics g = Graphics.FromHdc(desktop)) { g.DrawLine(pen, startingCoords.X, startingCoords.Y, endingCoords.X, endingCoords.Y); g.Dispose(); } ReleaseDC(IntPtr.Zero, desktop); }

Utilizándolo de esta manera, solo obtengo la línea dibujada una vez. Sin embargo, si muevo DrawLine () a un evento más estático como MouseUp, lo dibujará y luego desaparecerá después de aproximadamente un cuarto de segundo.

¿Cuál sería la mejor manera de lograr mi objetivo aquí?

Creo que cualquier evento que se esté utilizando para hacer que la línea desaparezca es a lo que me gustaría unir el dibujo de la línea en primer lugar.


Necesita tener dos llamadas de dibujo:

  • Uno para la línea no persistente que sigue al cursor en MouseMove usando someControls.CreateGraphics

  • la otra para la línea persistente , activada en MouseUp , donde

    • almacenas las coordenadas y
    • llame a Invalidate en su control de lienzo y
    • dibuje en el evento Paint de su lienzo utilizando su objeto e.Graphics .

Aquí hay un código de ejemplo mínimo:

List<Point> allPoints = new List<Point>(); Point mDown = Point.Empty; private void pictureBox1_MouseDown(object sender, MouseEventArgs e) { mDown = e.Location; } private void pictureBox1_MouseUp(object sender, MouseEventArgs e) { allPoints.Add(e.Location); pictureBox1.Invalidate(); } private void pictureBox1_MouseMove(object sender, MouseEventArgs e) { if (e.Button.HasFlag(MouseButtons.Left)) { pictureBox1.Refresh(); using (Graphics G = pictureBox1.CreateGraphics()) G.DrawLine(Pens.Red, mDown, e.Location); } } private void pictureBox1_Paint(object sender, PaintEventArgs e) { if (allPoints.Count > 1) e.Graphics.DrawLines(Pens.Black, allPoints.ToArray()); }

Tenga en cuenta que esto utiliza un PictureBox como control de lienzo. Es el control destinado a este tipo de interacción. Su código parece dibujar en el escritorio, que no le pertenece. Dibujar sobre él de manera persistente no se parece en nada a lo que haría con la / cualquier aplicación Paint.

También tenga en cuenta que mi ejemplo almacena una lista de puntos y los dibuja como una polilínea no cerrada . Para dibujarlos, intercambie DrawLines por DrawPolygon . Para dibujar varias de estas polilíneas o polígonos, debes ...

  • .. decida la interfaz de usuario para ello, tal vez agregue puntos de segmento solo mientras se presiona la tecla de control y de lo contrario termine la polilínea actual
  • almacenar los puntos en una List<List, Point>>

También tenga en cuenta que este es uno de los raros ejemplos en los que se control.CreateGraphics uso de control.CreateGraphics , ya que realmente desea un dibujo no persistente mientras el usuario mueve el mouse.

En la mayoría de los otros casos, se aplica la regla básica de gráficos de Winforms # 1:

Nunca use el control.CreateGraphics . ¡ control.CreateGraphics ! ¡Nunca intentes almacenar en caché un objeto Graphics ! Dibuje en un Bitmap bmp usando un Graphics g = Graphics.FromImage(bmp) o en el evento Paint de un control, usando el parámetro e.Graphics .