网格我可以画上

时间:2018-05-23 21:04:33

标签: vb.net

所以我正在尝试创建一个应用程序来简化像素艺术(学校项目)的创建,我到目前为止所做的是在面板中绘制网格,下一步是允许用户点击一个单元格,并绘制,但我无法使其工作,这里是我的代码:

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

这会绘制一个网格,其中包含用户想要的列数和行数,但我一直在努力允许绘画

我一直在想的是:处理此代码,并创建一个像素'上课,创造像素的数量'基于用户行和列的对象,并逐个绘制每个对象,然后只需更改每个像素的对象即可。颜色

1 个答案:

答案 0 :(得分:0)

这是一个Grid类,允许设置其单元格的颜色。

使用Grid引用List(Of List(Of Class))单元格。

Cell类包含的是一个简单的Rectagle属性,用于测量单元格的大小; Color属性,用于设置单个单元格的颜色:< BR />

Friend Class GridCell
    Public Property Cell() As Rectangle
    Public Property CellColor() As Color
End Class

您可以定义:

  
      
  • 网格的大小→ColoredGrid.GridSize = new Size(...)
  •   
  • 列数和行数→ColoredGrid.GridColumnsRows = new Size(...)
  •   
  • 网格在画布ColoredGrid.GridPosition = New Point(...)中的位置
  •   
  • 网格的颜色→ColoredGrid.GridColor = Color.Gray
  •   
  • 单元格的BackGround颜色→ColoredGrid.CellColor = Color.FromArgb(32, 32, 32)
  •   
  • 所选单元格的颜色→ColoredGrid.SelectedCellColor = Color.OrangeRed
  •   


Grid类包含对控件的引用,该控件将用作网格绘制的 Canvas 。此引用在类构造函数中设置 Grid注册 Canvas 控件Paint()MouseClick()事件以自动响应相关操作。
当在 Canvas 表面上检测到鼠标单击时,MouseEventArgs e.Location属性会报告Click发生的坐标。

要确定执行此操作的Grid CellGetUpdateCell()方法会使用简单的List(Of List(Of GridCell)) SelectMany()检查LINQ,识别出包含鼠标点击坐标的Cell矩形(表示为Point()值) 仅通过检查单元格Rectangle.Contains(Point())来执行该识别 识别单元格后,将调用 Canvas Invalidate()方法,指定要重绘的区域。
此区域对应Cell Rectangle,因此只有在Cell着色时才会重新绘制此部分,以节省资源和时间。

要对其进行测试,请在Panel中创建ButtonForm

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

这是一个可视化示例,展示了它的工作原理:

enter image description here

这是主要的Grid类 ColorGrid类支持IDisposable,因为它注册了所描述的事件。当不再使用Class时,必须取消注册。 奇怪的如果你不这样做,就会发生。

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