我可以画的网格 [英] Grid I can paint on
问题描述
所以我正在尝试创建一个应用程序来简化像素艺术的创建(学校项目),到目前为止我所做的是在面板中绘制一个网格,下一步是允许用户点击一个单元格并对其进行了绘制,但我无法使其正常工作,这是我拥有的代码:
Private Sub drawGrid(g As Graphics, rows As Integer, columns As Integer)Dim originPoint As Point = New Point(10, 2)Dim size As Size = 新尺寸(64, 64)Dim left As Integer = originPoint.X变暗为整数 = originPoint.YDim right As Integer = originPoint.X + (columns * size.Width)Dim down As Integer = originPoint.Y + (rows * size.Height)For y As Integer = up to down + 1 Step size.HeightDim pt1 As New Point(left, y)Dim pt2 As New Point(right, y)g.DrawLine(Pens.Black, pt1, pt2)下一个对于 x As Integer = left to right + 1 Step size.WidthDim pt1 As New Point(x, up)Dim pt2 As New Point(x, down)g.DrawLine(Pens.Black, pt1, pt2)下一个结束子
这会绘制一个包含用户想要的列数和行数的网格,但我一直在努力允许绘制
我一直在想的是:处理这段代码,并创建一个像素"类,根据用户的行和列创建像素"对象的数量,并单独绘制每个对象,然后只需更改每个像素"'颜色
这是一个 Grid
类,允许设置其单元格的颜色.
Grid
单元格使用 List(Of List(Of Class))
引用.
Cell
类对象包含一个简单的 Rectagle
属性,用于测量单元格的大小,以及一个 Color
属性,它允许设置单个单元格的颜色:
Friend 类 GridCell公共属性 Cell() 作为矩形公共属性 CellColor() 作为颜色结束类
您可以定义:
- 网格的大小→
ColoredGrid.GridSize = new Size(...)
- 列数和行数→
ColoredGrid.GridColumnsRows = new Size(...)
- 网格在 Canvas 中的位置 →
ColoredGrid.GridPosition = New Point(...)
- 网格的颜色→
ColoredGrid.GridColor = Color.Gray
- 单元格的背景颜色 →
ColoredGrid.CellColor = Color.FromArgb(32, 32, 32)
- 选定单元格的颜色 →
ColoredGrid.SelectedCellColor = Color.OrangeRed
Grid
类包含对控件的引用,该控件将用作网格绘制的 Canvas.此引用是在类构造函数中设置的.Grid
注册 Canvas 控件
这是主要的 Grid 类.ColorGrid
类支持 IDisposable,因为它注册了描述的事件.当不再使用该类时,必须取消注册这些.如果你不这样做,就会发生奇怪的事情.
公共类 ColorGrid实现 IDisposable私有网格作为列表(Of List(Of GridCell))私有 CurrentGridSize 作为新大小(100, 100)私有 GridColRows 作为新大小(10, 10)Private CellSize As New Size(10, 10)Private MouseCell As Point = Point.Empty私人画布作为控制 = 没有Private UpdateCell As Boolean = False私有 NewGrid 作为布尔值 = FalsePublic Sub New(DrawingControl As Control)如果 DrawingControl IsNot Nothing 那么Me.Canvas = DrawingControlAddHandler Me.Canvas.Paint, New PaintEventHandler(AddressOf Me.ControlPaint)AddHandler Me.Canvas.MouseClick, New MouseEventHandler(AddressOf Me.MouseHandler)Me.GridPosition = 新点(10, 10)Me.CellColor = Color.FromArgb(32, 32, 32)万一结束子公共属性 GridPosition() 作为点公共属性 CellColor() 作为颜色公共属性 SelectedCellColor() 作为颜色公共属性 GridColor() 作为颜色公共属性 GridSize() 作为大小得到返回我.CurrentGridSize结束获取设置(值作为大小)Me.CurrentGridSize = 值SetCellSize()结束集最终财产公共属性 GridColumnsRows() 作为大小得到返回我.GridColRows结束获取设置(值作为大小)Me.GridColRows = 值SetCellSize()结束集最终财产私有属性 RefreshCell() 作为 GridCell朋友类 GridCell公共属性 Cell() 作为矩形公共属性 CellColor() 作为颜色结束类私有子 SetCellSize()Me.CellSize = 新尺寸((Me.CurrentGridSize.Width \ Me.GridColRows.Width),(Me.CurrentGridSize.Height \ Me.GridColRows.Height))如果 Me.CellSize.Width <4 然后 Me.CellSize.Width = 4如果 Me.CellSize.Height <4 然后 Me.CellSize.Height = 4结束子公共子 BuildGrid()如果 Me.Canvas 什么都没有,那么返回Me.Grid = 新列表(Of List(Of GridCell))()对于 row As Integer = 0 To GridColumnsRows.Height - 1将 RowCells 调暗为新列表(属于 GridCell)()对于 col As Integer = 0 To GridColumnsRows.Width - 1RowCells.Add(New GridCell() with {.Cell = New Rectangle(New Point(Me.GridPosition.X + (col * Me.CellSize.Width),Me.GridPosition.Y + (row * Me.CellSize.Height)),Me.CellSize),.CellColor = Me.CellColor})下一个Me.Grid.Add(RowCells)下一个Me.NewGrid = 真Me.Canvas.Invalidate()结束子Private Sub ControlPaint(o As Object, e As PaintEventArgs)如果我.NewGrid 那么e.Graphics.Clear(Me.Canvas.BackColor)Me.NewGrid = False万一我.网格.SelectMany(Function(rowcells) rowcells).选择(功能(colcell)如果我.UpdateCell 那么使用画笔作为新的 SolidBrush(Me.RefreshCell.CellColor)e.Graphics.FillRectangle(画笔,Me.RefreshCell.Cell.X + 1,Me.RefreshCell.Cell.Y + 1,Me.RefreshCell.Cell.Width - 1, Me.RefreshCell.Cell.Height - 1)结束使用Me.UpdateCell = False什么都不返回别的使用钢笔作为新钢笔(Me.GridColor)e.Graphics.DrawRectangle(pen, colcell.Cell)结束使用使用画笔作为新的 SolidBrush(colcell.CellColor)e.Graphics.FillRectangle(brush, colcell.Cell.X + 1, colcell.Cell.Y + 1,colcell.Cell.Width - 1, colcell.Cell.Height - 1)结束使用万一返回科尔赛尔End Function).TakeWhile(Function(colcell) colcell IsNot Nothing).ToList()结束子Private Sub MouseHandler(o As Object, e As MouseEventArgs)Me.RefreshCell = GetUpdateCell(e.Location)Me.RefreshCell.CellColor = Me.SelectedCellColor将 CellColorArea 调暗为矩形 = Me.RefreshCell.CellCellColorArea.Inflate(-1, -1)Me.UpdateCell = TrueMe.Canvas.Invalidate(CellColorArea)结束子私有函数 GetUpdateCell(CellPosition As Point) As GridCell还我.Grid.SelectMany(Function(rowcells) rowcells).选择(函数(网格单元)网格单元).其中(Function(gridcell)gridcell.Cell.Contains(CellPosition)).第一的()结束函数Public Sub Dispose() 实现 IDisposable.Dispose如果我.Canvas 不是什么,那么RemoveHandler Me.Canvas.Paint, AddressOf Me.ControlPaintRemoveHandler Me.Canvas.MouseClick, AddressOf Me.MouseHandlerMe.Grid = 没有万一结束子结束类
So I am trying to create an application to ease creation of pixel arts (school project), what I've done so far is draw a grid in a panel, next step would be to allow the user to click on a cell and have it painted, but I can't manage to make it work, here's the code I have:
Private Sub drawGrid(g As Graphics, rows As Integer, columns As Integer)
Dim originPoint As Point = New Point(10, 2)
Dim size As Size = New Size(64, 64)
Dim left As Integer = originPoint.X
Dim up As Integer = originPoint.Y
Dim right As Integer = originPoint.X + (columns * size.Width)
Dim down As Integer = originPoint.Y + (rows * size.Height)
For y As Integer = up To down + 1 Step size.Height
Dim pt1 As New Point(left, y)
Dim pt2 As New Point(right, y)
g.DrawLine(Pens.Black, pt1, pt2)
Next
For x As Integer = left To right + 1 Step size.Width
Dim pt1 As New Point(x, up)
Dim pt2 As New Point(x, down)
g.DrawLine(Pens.Black, pt1, pt2)
Next
End Sub
This draws a grid with the amount of columns and rows the user wants, but I've been struggling to allow painting
What I've been thinking is: dispose this code, and create a 'pixel' class, create the amount of 'pixel' objects based on user rows and columns, and draw each one individually, then just change each 'pixel's' color
This is a Grid
class that allows setting the color of its cells.
The Grid
cell are referenced using a List(Of List(Of Class))
.
The Cell
class Object contains is a simple Rectagle
property that measures the size of the cell, and a Color
property, which allows to set the color of the single cell:
Friend Class GridCell
Public Property Cell() As Rectangle
Public Property CellColor() As Color
End Class
You can define:
- The size of the Grid →
ColoredGrid.GridSize = new Size(...)
- The number of Columns and Rows →
ColoredGrid.GridColumnsRows = new Size(...)
- The position of the Grid inside the Canvas →
ColoredGrid.GridPosition = New Point(...)
- The color of the Grid →
ColoredGrid.GridColor = Color.Gray
- The BackGround color of the cells →
ColoredGrid.CellColor = Color.FromArgb(32, 32, 32)
- The color of a selected cell →
ColoredGrid.SelectedCellColor = Color.OrangeRed
The Grid
class holds a reference to the control which will be used as the Canvas for the grid painting. This reference is set in the class contructor.
The Grid
registers the Canvas control Paint()
and MouseClick()
events to respond to the related actions automatically.
When a Mouse Click is detected on the Canvas surface, the MouseEventArgs
e.Location
property reports the coordinates where the Click occurred.
To identify the Grid
Cell
where this action is performed, the GetUpdateCell()
method inspects the List(Of List(Of GridCell))
using a simple LINQ
SelectMany()
and identified the Cell
rectangle that contains the Mouse Click coordinates (expressed as a Point()
value).
This identification is performed simply checking whether the Cell Rectangle.Contains(Point()).
When the cell is identified, the Canvas Invalidate()
method is called, specifing the area to repaint.
This area corresponds to the Cell
Rectangle
, so only this section is repainted when a Cell
is colored, to save resources and time.
To test it, create a Panel
and a Button
in a Form
:
Imports System.Drawing
'This Grid object in defined at Form Class scope
Public ColoredGrid As ColorGrid
'Button used to trigger the Grid painting
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If ColoredGrid IsNot Nothing Then
ColoredGrid.Dispose()
End If
ColoredGrid = New ColorGrid(Panel1)
ColoredGrid.GridSize = New Size(300, 300)
ColoredGrid.GridColumnsRows = New Size(10, 10)
ColoredGrid.GridPosition = New Point(10, 10)
ColoredGrid.GridColor = Color.White
ColoredGrid.CellColor = Color.FromArgb(32, 32, 32)
ColoredGrid.SelectedCellColor = Color.OrangeRed
ColoredGrid.BuildGrid()
End Sub
This is a visual sample that shows how it works:
This is the main Grid class.
The ColorGrid
Class supports IDisposable, because it registers the described events. These must be unregistered when the Class is not used anymore. Weird things can happen if you don't.
Public Class ColorGrid
Implements IDisposable
Private Grid As List(Of List(Of GridCell))
Private CurrentGridSize As New Size(100, 100)
Private GridColRows As New Size(10, 10)
Private CellSize As New Size(10, 10)
Private MouseCell As Point = Point.Empty
Private Canvas As Control = Nothing
Private UpdateCell As Boolean = False
Private NewGrid As Boolean = False
Public Sub New(DrawingControl As Control)
If DrawingControl IsNot Nothing Then
Me.Canvas = DrawingControl
AddHandler Me.Canvas.Paint, New PaintEventHandler(AddressOf Me.ControlPaint)
AddHandler Me.Canvas.MouseClick, New MouseEventHandler(AddressOf Me.MouseHandler)
Me.GridPosition = New Point(10, 10)
Me.CellColor = Color.FromArgb(32, 32, 32)
End If
End Sub
Public Property GridPosition() As Point
Public Property CellColor() As Color
Public Property SelectedCellColor() As Color
Public Property GridColor() As Color
Public Property GridSize() As Size
Get
Return Me.CurrentGridSize
End Get
Set(value As Size)
Me.CurrentGridSize = value
SetCellSize()
End Set
End Property
Public Property GridColumnsRows() As Size
Get
Return Me.GridColRows
End Get
Set(value As Size)
Me.GridColRows = value
SetCellSize()
End Set
End Property
Private Property RefreshCell() As GridCell
Friend Class GridCell
Public Property Cell() As Rectangle
Public Property CellColor() As Color
End Class
Private Sub SetCellSize()
Me.CellSize = New Size((Me.CurrentGridSize.Width \ Me.GridColRows.Width),
(Me.CurrentGridSize.Height \ Me.GridColRows.Height))
If Me.CellSize.Width < 4 Then Me.CellSize.Width = 4
If Me.CellSize.Height < 4 Then Me.CellSize.Height = 4
End Sub
Public Sub BuildGrid()
If Me.Canvas Is Nothing Then Return
Me.Grid = New List(Of List(Of GridCell))()
For row As Integer = 0 To GridColumnsRows.Height - 1
Dim RowCells As New List(Of GridCell)()
For col As Integer = 0 To GridColumnsRows.Width - 1
RowCells.Add(New GridCell() With {
.Cell = New Rectangle(New Point(Me.GridPosition.X + (col * Me.CellSize.Width),
Me.GridPosition.Y + (row * Me.CellSize.Height)),
Me.CellSize),
.CellColor = Me.CellColor})
Next
Me.Grid.Add(RowCells)
Next
Me.NewGrid = True
Me.Canvas.Invalidate()
End Sub
Private Sub ControlPaint(o As Object, e As PaintEventArgs)
If Me.NewGrid Then
e.Graphics.Clear(Me.Canvas.BackColor)
Me.NewGrid = False
End If
Me.Grid.
SelectMany(Function(rowcells) rowcells).
Select(Function(colcell)
If Me.UpdateCell Then
Using brush As New SolidBrush(Me.RefreshCell.CellColor)
e.Graphics.FillRectangle(brush, Me.RefreshCell.Cell.X + 1, Me.RefreshCell.Cell.Y + 1,
Me.RefreshCell.Cell.Width - 1, Me.RefreshCell.Cell.Height - 1)
End Using
Me.UpdateCell = False
Return Nothing
Else
Using pen As New Pen(Me.GridColor)
e.Graphics.DrawRectangle(pen, colcell.Cell)
End Using
Using brush As New SolidBrush(colcell.CellColor)
e.Graphics.FillRectangle(brush, colcell.Cell.X + 1, colcell.Cell.Y + 1,
colcell.Cell.Width - 1, colcell.Cell.Height - 1)
End Using
End If
Return colcell
End Function).TakeWhile(Function(colcell) colcell IsNot Nothing).ToList()
End Sub
Private Sub MouseHandler(o As Object, e As MouseEventArgs)
Me.RefreshCell = GetUpdateCell(e.Location)
Me.RefreshCell.CellColor = Me.SelectedCellColor
Dim CellColorArea As Rectangle = Me.RefreshCell.Cell
CellColorArea.Inflate(-1, -1)
Me.UpdateCell = True
Me.Canvas.Invalidate(CellColorArea)
End Sub
Private Function GetUpdateCell(CellPosition As Point) As GridCell
Return Me.Grid.
SelectMany(Function(rowcells) rowcells).
Select(Function(gridcell) gridcell).
Where(Function(gridcell) gridcell.Cell.Contains(CellPosition)).
First()
End Function
Public Sub Dispose() Implements IDisposable.Dispose
If Me.Canvas IsNot Nothing Then
RemoveHandler Me.Canvas.Paint, AddressOf Me.ControlPaint
RemoveHandler Me.Canvas.MouseClick, AddressOf Me.MouseHandler
Me.Grid = Nothing
End If
End Sub
End Class
这篇关于我可以画的网格的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!