PictureBox网格并在单击时选择单个单元格

时间:2012-10-03 15:33:33

标签: c# winforms

我目前正在使用pictureBox和网格。我已经能够在pictureBox上成功设置网格。现在我正在寻找帮助/指导编码选择每个单元格的方法。如何选择单个单元格并以蓝色显示其颜色?这是参考生命游戏。

网格代码:

 private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            int numOfCells = 200;
            int cellSize = 10;
            Pen p = new Pen(Color.Black);

            for (int i = 0; i < numOfCells; i++)
            {
                // Vertical
                g.DrawLine(p, i * cellSize, 0, i * cellSize, numOfCells * cellSize);
                // Horizontal
                g.DrawLine(p, 0, i * cellSize, numOfCells * cellSize, i * cellSize);
            }
        }

蓝色单元格是点击的:

enter image description here

1 个答案:

答案 0 :(得分:0)

您需要添加一些结构来处理单元格,而不是处理paint方法中的所有内容。这是一个快速而又脏的应用程序,我把它放在一起。它使用两个简单的类:Cell和Grid,它包含一个2D数组Cell。

这里要理解的主要是表格类中的Grid.SetDimentions方法和Form1_MouseDown事件,它将鼠标位置映射到世界坐标。

细胞分类:

using System.Drawing;

public sealed class Cell
{
    public bool Hover { get; set; }
    public enum CellState { Inactive, Intermediate, Active }
    public CellState State { get; private set; }
    public int Column { get; private set; }
    public int Row { get; private set; }
    public Rectangle Bounds { get; private set; }

    public Cell (int column, int row, CellState state = CellState.Inactive)
    {
        this.Column = column;
        this.Row = row;
    }

    public void SetDimensions (Rectangle bounds)
    {
        this.Bounds = bounds;
    }

    public void RotateState ()
    {
        switch (this.State)
        {
            case CellState.Active: { this.State = CellState.Inactive; break; }
            case CellState.Inactive: { this.State = CellState.Intermediate; break; }
            case CellState.Intermediate: { this.State = CellState.Active; break; }
        }
    }
}

网格类:

using System.Drawing;

public class Grid
{
    public Cell [,] Cells { get; private set; }
    public Size Size { get; private set; }
    public Rectangle Bounds { get; private set; }

    public Grid (Size gridSize)
    {
        this.Size = gridSize;
        this.Cells = new Cell [this.Size.Width, this.Size.Height];

        for (int r=0; r < this.Size.Height; r++)
        {
            for (int c=0; c < this.Size.Width; c++)
            {
                this.Cells [c, r] = new Cell(c, r);
            }
        }
    }

    public void SetDimensions (Rectangle bounds)
    {
        Size size;

        this.Bounds = bounds;
        size = new Size((int) (((float) bounds.Width) / ((float) this.Size.Width)), (int) (((float) bounds.Height) / ((float) this.Size.Height)));

        for (int r=0; r < this.Size.Height; r++)
        {
            for (int c=0; c < this.Size.Width; c++)
            {
                this.Cells [c, r].SetDimensions(new Rectangle(bounds.Left + (size.Width * c), bounds.Top + (size.Height * r), size.Width, size.Height));
            }
        }
    }
}

表格:

using System;
using System.Drawing;
using System.Windows.Forms;

public partial class Form1: Form
{
    private Grid World { get; set; }

    public Form1 ()
    {
        this.InitializeComponent();

        this.World = new Grid(new Size(50, 50));
        this.World.SetDimensions(new Rectangle(0, 0, this.pictureBox1.ClientSize.Width, this.pictureBox1.ClientSize.Height));
    }

    private void Form1_Shown (object sender, EventArgs e)
    {
        this.pictureBox1.Invalidate();
    }

    private void Form1_Resize (object sender, EventArgs e)
    {
        this.World.SetDimensions(new Rectangle(0, 0, this.pictureBox1.ClientSize.Width, this.pictureBox1.ClientSize.Height));

        this.pictureBox1.Invalidate();
    }

    private void pictureBox1_MouseMove (object sender, MouseEventArgs e)
    {
        for (int r=0; r < this.World.Size.Height; r++)
        {
            for (int c=0; c < this.World.Size.Width; c++)
            {
                this.World.Cells [c, r].Hover = this.World.Cells [c, r].Bounds.Contains(e.X, e.Y);
            }
        }

        this.pictureBox1.Invalidate();
    }

    private void pictureBox1_MouseClick (object sender, MouseEventArgs e)
    {
        for (int r=0; r < this.World.Size.Height; r++)
        {
            for (int c=0; c < this.World.Size.Width; c++)
            {
                if (this.World.Cells [c, r].Bounds.Contains(e.X, e.Y))
                {
                    this.World.Cells [c, r].RotateState();
                }
            }
        }
    }

    private void pictureBox1_Paint (object sender, PaintEventArgs e)
    {
        for (int r=0; r < this.World.Size.Height; r++)
        {
            for (int c=0; c < this.World.Size.Width; c++)
            {
                if (this.World.Cells [c, r].State == Cell.CellState.Active)
                {
                    e.Graphics.FillRectangle(System.Drawing.Brushes.Blue, this.World.Cells [c, r].Bounds);
                }
                else if (this.World.Cells [c, r].State == Cell.CellState.Inactive)
                {
                    e.Graphics.FillRectangle(System.Drawing.Brushes.White, this.World.Cells [c, r].Bounds);
                }
                else if (this.World.Cells [c, r].State == Cell.CellState.Intermediate)
                {
                    e.Graphics.FillRectangle(System.Drawing.Brushes.Gray, this.World.Cells [c, r].Bounds);
                }

                if (this.World.Cells [c, r].Hover)
                {
                    e.Graphics.DrawRectangle(System.Drawing.Pens.Red, this.World.Cells [c, r].Bounds);
                }
                else
                {
                    e.Graphics.DrawRectangle(System.Drawing.Pens.Black, this.World.Cells [c, r].Bounds);
                }
            }
        }
    }
}