Форум программистов, компьютерный форум, киберфорум
Visual Basic .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.96/26: Рейтинг темы: голосов - 26, средняя оценка - 4.96
9 / 9 / 5
Регистрация: 29.04.2014
Сообщений: 70

Нарисовать на форме сетку, а при нажатии заменить на картинку

14.11.2014, 23:19. Показов 5214. Ответов 19
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем доброго времени суток. Делаю программу для рисования различных схем. Нужно нарисовать сетку на форме (см. вложение) это я реализовал:
VB.NET
1
2
3
4
5
6
7
8
Dim draw As Graphics = PictureBox1.CreateGraphics
        draw.Clear(PictureBox1.BackColor)
        For i = 0 To PictureBox1.Width Step 35  
            draw.DrawLine(Pens.Black, i, 0, i, PictureBox1.Height)
        Next
        For i = 0 To PictureBox1.Height Step 35  
            draw.DrawLine(Pens.Black, 0, i, PictureBox1.Width, i)
        Next
Но тут проблема, сетка рисуется на всю картинку. А мне нужно, чтобы при нажатии по конкретным участкам сетки - этот участок заполнялся заранее подготовленной картинкой. Т.е как в паинте, взяли кисть ---> рисуем на форме ---> взяли карандаш ---> рисуем по другому. В моем случае нужно примерно так: сверху формы жмем на картинку (выбираем чем рисовать) ---> рисуем на форме (нужно рисовать по сетке) ---> нарисовали ---> берем другой элемент --- рисуем и т.д.
...нужно рисовать по сетке. Т.е жмем на квадратик на сетке, заполняется только он. Нужно примерное так: ЛКМ-рисуем, ПКМ-вытираем.
У меня нет идей, как это реализовать... Только 100-200 PictureBox'ов с процедурой на каждый (или общей, на все, если возможно) Но если так, то будет еще проблема, т.к размер поля для рисования должен выбрать пользователь, то количество PictureBox'ов будет меняться.
Вообще не знаю, как реализовать. Помогите, пожалуйста.
Заранее спасибо!
Миниатюры
Нарисовать на форме сетку, а при нажатии заменить на картинку  
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
14.11.2014, 23:19
Ответы с готовыми решениями:

Как при нажатии одного радиобаттона показать одну картинку, а при нажатии другого другую
Как сделать так, чтобы при нажатие одного радиобаттона появлялась одна картинка, а при нажатие другого другая, подскажите.

При нажатии на форме на кнопку нужно нарисовать квадратики
Будущий начинающий студент:) Прошу Вашей помощи в понимание основ паттерна MVC для WinForm (я уже прочитал, что это не лучший выбор, но...

Иерархия объектов. Нарисовать фигуры в форме при нажатии соответствующей кнопки
Всем привет! Задача несложная, но увы, я с ней не справляюсь. Необходимо создать иерархии классов...

19
4708 / 3661 / 857
Регистрация: 02.02.2013
Сообщений: 3,518
Записей в блоге: 2
15.11.2014, 14:54
Лучший ответ Сообщение было отмечено Памирыч как решение

Решение

Пример реализации. Думаю, что будет полезен только для небольшого размера сетки в противном случае, нужно переходить непосредственно к растру.
Здесь клетки заливаются цветом (черный/белый) но никаких проблем нет и для вставки выбранной картинки. Кнопки для выбора текущей картинки можно разместить справа на форме.
Идея взята из программы игры Крестики/Нолики.
VB.NET
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
Private nH As Integer = 20  'число ячеек по горизонтали
Private nV As Integer = 20  'число ячеек по вертикали
Private ln As Integer = 20  'размер ячейки
Private cll(nH, nV) As Label
Private Sub Form6_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
    Panel1.Height = ln * (nH + 1)
    Panel1.Width = ln * (nV + 1)
    Panel1.Location = New Point(5, 5)
    Me.ClientSize = New Size(Panel1.Width + 10, Panel1.Height + 10)
    For i = 1 To nH
        For j = 1 To nV
            cll(i, j) = New Label
            Panel1.Controls.Add(cll(i, j))
            With cll(i, j)
                .BorderStyle = BorderStyle.FixedSingle
                .Width = ln
                .Height = ln
                .Left = (ln * i) - ln
                .Top = (ln * j) - ln
                .Text = ""
                .BackColor = Color.FromArgb(&HFCF9C5)
                AddHandler cll(i, j).Click, AddressOf CellClick
            End With
        Next
    Next
End Sub
Sub CellClick(ByVal Cell As Object, ByVal e As EventArgs)
    Dim lb As Label = CType(Cell, Label)
    If lb.BackColor = Color.Black Then
        lb.BackColor = Color.White
    Else
        lb.BackColor = Color.Black
    End If
End Sub
Миниатюры
Нарисовать на форме сетку, а при нажатии заменить на картинку  
2
4708 / 3661 / 857
Регистрация: 02.02.2013
Сообщений: 3,518
Записей в блоге: 2
22.11.2014, 14:02
Лучший ответ Сообщение было отмечено Памирыч как решение

Решение

Вариант с растром. Размер сетки, число ячеек задаются в коде.
При клике левой кнопкой мыши вставляется выбранная картинка, при клике правой кнопкой - ячейка очищается.
Миниатюры
Нарисовать на форме сетку, а при нажатии заменить на картинку  
Вложения
Тип файла: zip gridBmp.zip (94.4 Кб, 72 просмотров)
4
9 / 9 / 5
Регистрация: 29.04.2014
Сообщений: 70
22.11.2014, 21:57  [ТС]
ovva, спасибо! Ваш вариант почти идеален, не хватает только возможности заполнения/очищения зажатием ЛКМ/ПКМ
0
4708 / 3661 / 857
Регистрация: 02.02.2013
Сообщений: 3,518
Записей в блоге: 2
22.11.2014, 23:36
Цитата Сообщение от n1lsik Посмотреть сообщение
не хватает только возможности заполнения/очищения зажатием ЛКМ/ПКМ
непонятно что имеется ввиду?
0
9 / 9 / 5
Регистрация: 29.04.2014
Сообщений: 70
23.11.2014, 13:09  [ТС]
ovva, в Вашем варианте нужно кликать на каждую клетку отдельно, если удалить, то ПКМ, если заполнить, то ЛКМ. Но для моей программы - это не удобно (нужно рисовать много прямых, длинных линий и т.д). Поэтому нужно, чтобы была возможность заполнять/очищать клетки зажатием кнопок мышки, т.е зажали ЛКМ ---> Тянем мышку ---> Клетки заполняются. Так же и с ПКМ.
Каждый раз кликать не удобно. Нужно реализовать заполнение/очищение зажатием ЛКМ/ПКМ... Заранее спасибо.
0
4708 / 3661 / 857
Регистрация: 02.02.2013
Сообщений: 3,518
Записей в блоге: 2
23.11.2014, 14:16
Лучший ответ Сообщение было отмечено Памирыч как решение

Решение

Внесите в код следующие изменения.
VB.NET
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
Public Class FormMain
….
Private isDo As Boolean = False.
Private Sub PictureBox1_MouseDown(sender As System.Object, e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
    isDo = True
    setAction(e.Location, e.Button)
End Sub
Private Sub PictureBox1_MouseUp(sender As System.Object, e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseUp
    isDo = False
    PictureBox1.Refresh()
End Sub
Private Sub PictureBox1_MouseMove(sender As System.Object, e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
    setAction(e.Location, e.Button)
End Sub
Private Sub setAction(pp As Point, btn As MouseButtons)
    Try
        Dim j As Integer = pp.Y \ aa
        Dim i As Integer = pp.X \ aa
        If btn = Windows.Forms.MouseButtons.Left Then
            grid(i, j) = A.Clone
        ElseIf btn = Windows.Forms.MouseButtons.Right Then
            grid(i, j) = B.Clone
        End If
    Catch ex As Exception
 
    End Try
End Sub
End Class
1
9 / 9 / 5
Регистрация: 29.04.2014
Сообщений: 70
23.11.2014, 14:52  [ТС]
ovva, огромное спасибо! + пропала ошибка, если не выбрать картинку. Почти идеально, не хватает только одного - возможности просмотра заполняемого/очищаемого. Т.е чтобы посмотреть результат заполнения/очищения нужно отпустить ЛКМ/ПКМ, а это не совсем удобно. В идеале должно быть так: зажимаем ЛКМ --> тянем мышку на 10 клеток, когда тянем, сразу видим результат, что "натянули", так сказать
0
4708 / 3661 / 857
Регистрация: 02.02.2013
Сообщений: 3,518
Записей в блоге: 2
23.11.2014, 18:23
Лучший ответ Сообщение было отмечено n1lsik как решение

Решение

Полагаю это то что вы хотели получить
Вложения
Тип файла: zip gridBmp.zip (95.5 Кб, 69 просмотров)
1
9 / 9 / 5
Регистрация: 29.04.2014
Сообщений: 70
23.11.2014, 21:22  [ТС]
ovva, супер! Спасибо!
П.С. Вспомнил про еще одну штуку, которой не хватает. Некоторые картинки должны накладываться поверх других, т.е поверх непрозрачной картинки наложить полупрозрачную. Чтобы, например, в программе можно было поверх желтого цвета (самая последняя кнопка) наложить тире (самая первая), а не заменить.
Возможно?
Заранее спасибо.
0
4708 / 3661 / 857
Регистрация: 02.02.2013
Сообщений: 3,518
Записей в блоге: 2
23.11.2014, 23:35
Цитата Сообщение от n1lsik Посмотреть сообщение
Делаю программу для рисования различных схем.
Думаю, что ваш проект сдвинулся с места и далее вы уже можете развивать его самостоятельно. Удачи.
1
 Аватар для MACHOMAN
54 / 30 / 4
Регистрация: 15.01.2014
Сообщений: 354
24.11.2014, 13:01
у меня вот такая ошибка как ее можно исправить?
Миниатюры
Нарисовать на форме сетку, а при нажатии заменить на картинку  
0
4708 / 3661 / 857
Регистрация: 02.02.2013
Сообщений: 3,518
Записей в блоге: 2
24.11.2014, 14:45
Возможно, выбранная кнопка не содержит картинки (вместо картинки текст).
0
9 / 9 / 5
Регистрация: 29.04.2014
Сообщений: 70
24.11.2014, 21:34  [ТС]
MACHOMAN, в последнем вложении этой проблемы нет, вроде.
Цитата Сообщение от ovva Посмотреть сообщение
Думаю, что ваш проект сдвинулся с места и далее вы уже можете развивать его самостоятельно. Удачи.
Я посидел, подумал... И что-то никак
Помогите, пожалуйста.
0
4708 / 3661 / 857
Регистрация: 02.02.2013
Сообщений: 3,518
Записей в блоге: 2
24.11.2014, 22:23
Для начала определитесь, какое действие пользователя будет определять процедуру НАЛОЖЕНИЕ. Например ЛКМ+Ctrl. В процедуре setAction можно отслеживать эту ситуацию. Здесь вы имеете: grid(i, j) – картинка на сетке и А – выбранная картинка. Осталось объединить эти картинки, наложить А на grid(i, j) и результат сохранить в grid(i, j). Вот как то так.
1
9 / 9 / 5
Регистрация: 29.04.2014
Сообщений: 70
29.11.2014, 12:49  [ТС]
Я еще подумал... И так и не понял,
Цитата Сообщение от ovva Посмотреть сообщение
Осталось объединить эти картинки
как это сделать? Вариантов реализации совсем нет... Помогите, пожалуйста.
0
4708 / 3661 / 857
Регистрация: 02.02.2013
Сообщений: 3,518
Записей в блоге: 2
29.11.2014, 13:41
Лучший ответ Сообщение было отмечено Памирыч как решение

Решение

Попробуйте проанализировать код. Здесь все как я описывал ранее.
Вложения
Тип файла: zip gridBmp.zip (97.5 Кб, 67 просмотров)
2
9 / 9 / 5
Регистрация: 29.04.2014
Сообщений: 70
30.11.2014, 14:29  [ТС]
ovva, спасибо! Извините, если я Вам уже надоел.
У меня еще 2 проблемы:
1. Наложение может сработать несколько раз, и картинка получится совсем не такой, как хотелось.
2. Не могу сохранить то, что нарисовал. Делал примерное так:
VB.NET
1
2
3
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        PictureBox1.Image.Save("E:\45564.png")
    End Sub
не работает "Ссылка на объект не указывает на экземпляр объекта." Как я понял, этот вариант не подходит, т.к если задать PictureBox'у свойство Image, то все нормально. Но сохранит он только картинку, которая была задана, а не то, что было нарисовано.
0
4708 / 3661 / 857
Регистрация: 02.02.2013
Сообщений: 3,518
Записей в блоге: 2
30.11.2014, 19:29
1. Не понял. В процессе рисовки с наложением, как и при простой рисовке, выбранная картинка вставляется во все пересекаемые при движении мыши клетки. Возможно какой то эффект возникает при дрожании мыши и неполном нажатии клавиши Ctrl.
2. Вставьте в используемый код.
VB.NET
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Imports System.Drawing.Drawing2D
Public Class FormMain
…
Private isSaveImg As Boolean = FalsePrivate Sub PictureBox1_Paint(sender As System.Object, e As System.Windows.Forms.PaintEventArgs) Handles PictureBox1.Paint
…
    If isSaveImg Then
        Dim im As New Bitmap(PictureBox1.Width, PictureBox1.Height)
        Dim gg As Graphics = Graphics.FromImage(im)
        For i = 0 To nn - 1
            For j = 0 To nn - 1
                gg.DrawImage(grid(i, j), New Rectangle(i * aa, j * aa, aa, aa))
            Next
        Next
        im.Save("c:\00\img.png", Imaging.ImageFormat.Png)
        isSaveImg = False
    End If
End SubPrivate Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
    isSaveImg = True
    PictureBox1.Refresh()
End Sub
End Class
1
9 / 9 / 5
Регистрация: 29.04.2014
Сообщений: 70
30.11.2014, 20:01  [ТС]
Цитата Сообщение от ovva Посмотреть сообщение
Не понял. В процессе рисовки с наложением, как и при простой рисовке, выбранная картинка вставляется во все пересекаемые при движении мыши клетки. Возможно какой то эффект возникает при дрожании мыши и неполном нажатии клавиши Ctrl.
Извиняюсь, я немного не так сформулировал.
Нужно запретить наложении больше 1 раза.
Код на сохранение работает, спасибо!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
30.11.2014, 20:01
Помогаю со студенческими работами здесь

Нарисовать сетку из клеток на форме, отслеживая клики по каждой из них
Ребят,всем добрый вечер. Подскажите как лучше нарисовать сетку из клеток на форме,чтобы потом обработать клик мышки и закрашивать клетки,в...

Заменить картинку у кнопки на 1-ой форме по клику на кнопку на 2-ой форме
Есть две формы . На первой форме есть одна кнопка с картинкой "А" , когда нажимаешь на неё открывается форма2 с тремя кнопками у 1-ой...

Как нарисовать картинку на форме
Доброго времени суток =) Подскажите, как нарисовать картинку на форме? Image b = new Image(@"images\red_car.png");

При нажатии на кнопку поменять картинку из элемента ImageList и поставить туда стандартную картинку
Всем привет! Как сделать кнопку и поставить пару картинок в ImageList я знаю. Осталось только запрограмировать кнопку так, чтобы те...

Как при нажатии на картинку открыть текст и картинку?
Здравствуйте. У меня есть маленькие треугольники (см вложение), при нажатии на который, должен появляться текст, а треугольник изменится...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Символьное дифференцирование
igorrr37 13.02.2026
/ * Логарифм записывается как: (x-2)log(x^2+2) - означает логарифм (x^2+2) по основанию (x-2). Унарный минус обозначается как ! */ #include <iostream> #include <stack> #include <cctype>. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru