Windows Forms - Не видно рисование на pictureBox
Есть panel "Grid", поверх которой чётко стоит pictureBox "Dots", а поверх него - panel Crosspanel. Изначально было только две панели, но я в конструкторе как бы подсунул пикчербокс между ними.
Возможно, проблема в том, что из-за Crosspanel не видно рисующихся квадратов. Но я не исключаю, что намудрил с координатами, и всё рисуется не там. Пробовал на отдельном (просто расположенном на форме) пикчербксе рисовать - там тоже не видно.
public partial class MainWindow : Form
{
//----------------------------------------------------------------------------------------------- ПАРАМЕТРЫ
// Текущее приближение
public bool sZoom = true;
// Координатная схема
public int KS = 10;
// Толщины
private Pen penKS = new Pen(Color.DarkGreen, 1);
private Pen penOs = new Pen(Color.DarkGreen, 2);
// Ширина сетки
public int sS = 0;
// Текущие искусственные координаты курсора
Point tek = new Point(0, 0);
//----------------------------------------------------------------------------------------------- ФУНКЦИИ КООРДИНАТ
// Вычисление координат внутри сетки
public Point GetCoords()
{
// Курсор относительно формы
Point vihod = PointToClient(Cursor.Position);
// Расположение сетки
vihod.X -= Grid.Location.X;
vihod.Y -= Grid.Location.Y;
// Ширина сетки
vihod.X -= sS/2+1;
vihod.Y -= sS/2+1;
vihod.Y *= -1;
return vihod;
}
// Вычисление искусственных координат
public Point FakeCoords(Point m)
{
m.X = m.X / 12;
m.Y = m.Y / 12;
if (m.X > 30 || m.X < -30)
m.X = 30;
if (m.Y > 30 || m.Y < -30)
m.Y = 30;
return m;
}
// Вычисление искусственных координат
public Point FakeCoords()
{
Point m = new Point();
m.X = GetCoords().X / 12;
m.Y = GetCoords().Y / 12;
if (m.X > 30 || m.X < -30)
m.X = 30;
if (m.Y > 30 || m.Y < -30)
m.Y = 30;
return m;
}
//----------------------------------------------------------------------------------------------- ФУНКЦИИ ИВЕНТОВ
// Отображение координат в окошке
public void ShowCoords(object sender, EventArgs e)
{
tek = FakeCoords();
CoordX.Text = "X: " + tek.X.ToString();
CoordY.Text = "Y: " + tek.Y.ToString();
DrawRedSquare(Dots, PointToClient(Cursor.Position));
}
//----------------------------------------------------------------------------------------------- ФУНКЦИИ РИСОВАНИЯ
// Всё рисование сетки
public void GenZanovo(object sender, PaintEventArgs e)
{
// Рисовалка
Graphics g = e.Graphics;
// Оси
g.DrawLine(penOs, 0, sS/2, sS, sS/2);
g.DrawLine(penOs, sS/2, 0, sS/2, sS);
if (sZoom)
{
for (int i = -3; i <= 3; i++)
{
// По горизонтали
g.DrawLine(penKS, sS / 2 + (i * 12 * KS), 0, sS / 2 + (i * 12 * KS), sS);
// По вертикали
g.DrawLine(penKS, 0, sS / 2 + (i * 12 * KS), sS, sS / 2 + (i * 12 * KS));
}
}
// Перенос центра сетки
e.Graphics.TranslateTransform(Grid.Width / 2f, Grid.Height / 2f);
}
// Рисование одной точки
public void DrawRedSquare(PictureBox picturebox, Point m)
{
// Создаем Graphics объект для рисования на PictureBox
Graphics g = picturebox.CreateGraphics();
// Устанавливаем цвет кисти
Pen pen = new Pen(Color.Red);
// Рисуем прямоугольник размером 4x4 пикселя с указанными координатами
g.DrawRectangle(pen, m.X, m.Y, 400, 400);
}
//----------------------------------------------------------------------------------------------- ЗАПУСК
public MainWindow()
{
InitializeComponent();
// Отключение курсора при входе в область сетки
// Отрисовывание сетки
sS = Grid.Width;
Grid.Paint += GenZanovo;
// Координаты в окошке
Crosspanel.MouseMove += ShowCoords;
}
}
Ответы (1 шт):
Создаём коллекцию для хранения координат точек (квадратов):
private readonly HashSet<Point> points = new HashSet<Point>();
HashSet
удобен тем, что автоматически не допустит сохранения дубликатов и обеспечит быстрый поиск при удалении.
Подписываем PictureBox
на события MouseClick
и Paint
.
В первом добавляем точку в коллекцию при нажатии левой кнопки мыши и удаляем точку при нажатии правой кнопки. При это достаточно попасть в квадрат. И вызываем перерисовку пикчабокса вызовом метода Invalidate()
.
private void PictureBox_MouseClick(object? sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
points.Add(e.Location);
}
else if (e.Button == MouseButtons.Right)
{
foreach (var point in points)
{
var rect = new Rectangle(point.X, point.Y, 10, 10);
if (rect.Contains(e.X, e.Y))
points.Remove(point);
}
}
pictureBox.Invalidate();
}
Во втором событии отрисовываем всё необходимое: и координатную сетку, и квадраты.
private void PictureBox_Paint(object? sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
for (int y = 0; y <= pictureBox.Height; y += 100)
g.DrawLine(Pens.Green, 0, y, pictureBox.Width, y);
for (int x = 0; x <= pictureBox.Width; x += 100)
g.DrawLine(Pens.Green, x, 0, x, pictureBox.Height);
foreach (var point in points)
g.DrawRectangle(Pens.Red, point.X, point.Y, 10, 10);
}