Во-первых, не используйте CreateGraphics()
, если только вам это не нужно. Привязать обработчик событий к OnPaint
и вызвать Invalidate()
, когда вы хотите обновить поверхность.
Если вы не хотите, чтобы он мерцал, вам нужно будет дважды буферизовать поверхность рисования. Самый простой способ сделать это - установить для свойства DoubleBuffered
вашей формы значение True.
Я очень рекомендую, если вы планируете расширить это, чтобы сделать ваш рисунок для элемента управления PictureBox. PictureBox по умолчанию имеет двойную буферизацию и позволяет намного проще управлять областью рисования.
В коде:
public partial class Form1 : Form
{
int xFirst, yFirst;
Bitmap bm = new Bitmap(1000, 1000);
Graphics bmG;
Pen pen = new Pen(Color.Black, 1);
bool draw = false;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
bmG = Graphics.FromImage(bm);
bmG.Clear(Color.White);
}
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
xFirst = e.X;
yFirst = e.Y;
draw = true;
}
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
bmG.DrawLine(pen, xFirst, yFirst, e.X, e.Y);
draw = false;
Invalidate();
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
if (draw)
{
Invalidate();
}
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
if (draw) {
e.Graphics.DrawImage(bm, 0, 0);
e.Graphics.DrawLine(pen, xFirst, yFirst, e.X, e.Y);
} else {
e.Graphics.DrawImage(bm, 0, 0);
}
}
}
Edit:
Еще одна проблема, вы создаете частного Pen
участника. Ручки (и кисти, а также многие объекты GDI +) представляют собой дескрипторы неуправляемых объектов, которые необходимо утилизировать, иначе ваша программа утечет. Либо заключите их в операторы using
(предпочтительный и безопасный для исключений способ), либо явным образом избавьтесь от них в методе Dispose
формы.
В качестве альтернативы в System.Drawing вы можете получить доступ к некоторым предварительно созданным ручкам и кистям, которые не нужно (и не следует) утилизировать. Используйте их как:
private void Form1_Paint(object sender, PaintEventArgs e)
{
if (draw) {
e.Graphics.DrawImage(bm, 0, 0);
e.Graphics.DrawLine(Pens.Black, xFirst, yFirst, e.X, e.Y);
} else {
e.Graphics.DrawImage(bm, 0, 0);
}
}