При рисовании на поверхности элемента управления вы всегда используете событие Paint
этого элемента управления.
Никогда не пытайтесь сохранить его Graphics
объект (он больше не действителен, так каккак только элемент управления становится недействительным (перекрашивается)).
Не пытайтесь использовать его PaintEventArgs
каким-либо экзотическим способом.Используйте объект Graphics
, на который он ссылается, только внутри события Paint
.
Когда требуется более сложная процедура для рисования большего количества различных фигур, вы можете передать объект e.Graphics
, предоставленныйсобытие Paint
для различных методов, которые будут использовать объект e.Graphics
для выполнения специализированных рисунков.
В этом примере я сохраняю координаты каждого нарисованного прямоугольника в специализированном классе(DrawingRectangle
, упрощенная структура здесь), и я использую List<DrawingRectangle>()
для доступа к этим ссылкам.
Когда событие MouseDown
сообщает, что левая кнопка нажата на поверхности элемента управления,e.Location
сохраняется как DrawingRectangle.Location
(это значение может изменяться в зависимости от направления указателя мыши) и DrawingRectangle.StartPoint
(контрольная мера, которая не изменяется).
КогдаПри перемещении мыши текущие значения e.Location
координат вычитаются из сохраненных координат начальной точки Rectangle (плюс некоторые вычисления, которые позволяют нарисовать Rectangle со всех сторон).Эта мера является размером прямоугольника.
Каждый раз, когда обнаруживается левый MouseDown
, в список добавляется новый элемент класса.
Чтобы удалить прямоугольник из чертежа, вам просто нужно удалить его ссылкуиз Списка и Invalidate()
Элемент управления, который предоставляет поверхность для рисования.
Чтобы очистить поверхность для рисования, очистите List<DrawingRectangle>()
(DrawingRects.Clear()
) и вызовите Invalidate()
.
Некоторые другие примеры здесь:
Прозрачные перекрывающиеся круговые индикаторы хода выполнения
Классы GraphicsPath и Matrix
Соединение различных фигур
Рисование прозрачного / полупрозрачногоПользовательские элементы управления
![Drawing Rectangles](https://i.stack.imgur.com/WS299.gif)
List<DrawingRectangle> DrawingRects = new List<DrawingRectangle>();
public class DrawingRectangle
{
public Point Location { get; set; }
public Size Size { get; set; }
public Point StartPosition { get; set; }
public Color DrawingcColor { get; set; } = Color.LightGreen;
public float PenSize { get; set; } = 3f;
}
private void form1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left) {
DrawingRects.Add(new DrawingRectangle() {
Location = e.Location, Size = Size.Empty, StartPosition = e.Location
});
}
}
private void form1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
DrawingRectangle rect = DrawingRects.Last();
if (e.Y < rect.StartPosition.Y) { rect.Location = new Point(rect.Location.Y, e.Y); }
if (e.X < rect.StartPosition.X) { rect.Location = new Point(e.X, rect.Location.Y); }
rect.Size = new Size(Math.Abs(rect.StartPosition.X - e.X), Math.Abs(rect.StartPosition.Y - e.Y));
DrawingRects[DrawingRects.Count - 1] = rect;
this.Invalidate();
}
}
private void form1_Paint(object sender, PaintEventArgs e)
{
if (DrawingRects.Count == 0) return;
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
foreach (var rect in DrawingRects) {
using (Pen pen = new Pen(rect.DrawingcColor, rect.PenSize)) {
e.Graphics.DrawRectangle(pen, new Rectangle(rect.Location, rect.Size));
};
}
}
private void btnClear_Click(object sender, EventArgs e)
{
DrawingRects.Clear();
this.Invalidate();
}