Comment dessiner des formes dans WinForms

J’essaie de coder un programme semblable à une peinture. Vous pouvez dessiner des formes remplies en sélectionnant la forme souhaitée, cliquez sur la zone d’image et faites glisser la souris pour obtenir la taille souhaitée. Mais cela peut arriver quand je traîne. Quand j’utilise refresh(); , les formes précédemment dessinées se suppriment. Que dois-je faire pour dessiner des formes remplies?

 private void CizimPicture_MouseDown(object sender, MouseEventArgs e) { Cursor = Cursors.Cross; if (e.Button == MouseButtons.Left) { cizim = true; } X1 = eX; Y1 = eY; } private void CizimPicture_MouseUp(object sender, MouseEventArgs e) { Cursor = Cursors.Default; cizim = false; } private void CizimPicture_MouseMove(object sender, MouseEventArgs e) { if (!cizim) return; if (cizim == true) { X = eX; Y = eY; X2 = (eX - X1); Y2 = (Y1 - eY); if (dikdörtgen == true) { resmim.FillRectangle(renk.Brush, X1, Y1, X2, -Y2); } if (elips == true) { resmim.FillEllipse(renk.Brush, X1, Y1, X2, -Y2); } } } 

J’ai cherché un exemple de code à la fois simple et efficace, sans rien trouver. Pour cela, vous n’avez pas besoin de bitmaps hors écran ni de CreateGraphics , mais vous devez gérer le suivi de la position de la souris, le dessin à l’écran et l’ajout de formes dessinées à une liste de formes, comme le suggère Eric. Pour gérer le dessin interactif, vous devez enregistrer l’état de la souris, la position du clic initial et le rectangle actuel dans votre gestionnaire de formulaire:

 bool mouseDown; Point clickPos; Rectangle rect; 

Puis, lorsque l’utilisateur clique, rappelez-vous la position initiale:

 private void MouseDown(object sender, MouseEventArgs e) { mouseDown = true; clickPos = e.Location; rect = new Rectangle(clickPos, new Size(0, 0)); } 

Pendant que l’utilisateur fait glisser la souris vers le bas, créez un rectangle englobant les emplacements de départ et actuel:

 private void MouseMove(object sender, MouseEventArgs e) { if (mouseDown) { this.Invalidate(rect); if (e.Location.X > clickPos.X && e.Location.Y > clickPos.Y) { rect = new Rectangle(clickPos.X, clickPos.Y, e.Location.X - clickPos.X, e.Location.Y - clickPos.Y); } else if (e.Location.X > clickPos.X && e.Location.Y < clickPos.Y) { rect = new Rectangle(clickPos.X, e.Location.Y, e.Location.X - clickPos.X, clickPos.Y - e.Location.Y); } else if (e.Location.X < clickPos.X && e.Location.Y < clickPos.Y) { rect = new Rectangle(e.Location.X, e.Location.Y, clickPos.X - e.Location.X, clickPos.Y - e.Location.Y); } else if (e.Location.X < clickPos.X && e.Location.Y > clickPos.Y) { rect = new Rectangle(e.Location.X, clickPos.Y, clickPos.X - e.Location.X, e.Location.Y - clickPos.Y); } this.Invalidate(rect); } } 

Lorsque l’utilisateur relâche la souris, arrêtez de dessiner:

 private void MouseUp(object sender, MouseEventArgs e) { mouseDown = false; } 

La règle la plus importante dans Windows Forms est la suivante: dessinez uniquement à l’écran dans l’événement Paint . Ne jamais dessiner dans l’événement MouseMoved :

 private void Paint(object sender, PaintEventArgs e) { e.Graphics.FillRectangle(Brushes.DarkGray, rect); } 

Une fois que cela fonctionne, créez un formulaire List , ajoutez le rectangle actuel à l’événement MouseUp et dessinez tous les rectangles dans l’événement Paint . Vous pouvez également effectuer certaines optimisations dans MouseMoved afin d’invalider uniquement la région d’écran modifiée, mais pas à la fois l’ancien et le nouveau rectangle.