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
usandosomeControls.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 objetoe.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
.