我可以画的网格 [英] Grid I can paint on

查看:33
本文介绍了我可以画的网格的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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 CanvasColoredGrid.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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆