2D RectangleShapes数组

时间:2012-07-03 14:22:55

标签: c# arrays winforms forms rectangles

我正在开发一个非常基本绘图程序:一个由多个RectangleShapes组成的2D网格,每个大约20x30像素,点击时根据用户RGB输入改变颜色,这很好用:

Color SelectedColor = new Color();
private void Pixel_1_1_Click(object sender, EventArgs e)    // on Rectangle click
{
    Pixel_1_1.FillColor = SelectedColor;    // change to currently desired color.
}

由于广场数量急剧增加,我正在寻找一种方法来安排像素"矩形成2D阵列。 (我真的不想为屏幕上的每个矩形制作一个Pixel_Click方法!)希望最终能够调用类似的东西:

private void Pixel_[x]_[y]_Click(object sender, EventArgs e)
{
    Pixel_[x]_[y].FillColor = SelectedColor;
}

我的朋友建议使用匿名代表,但我不明白如何充分利用一个来解决我的问题。

在C#Windows窗体中生成2D矩形的最佳方法是什么?一旦生成,如何使用单一方法为x和y的变量值访问它们?

3 个答案:

答案 0 :(得分:1)

如果要将矩形维护为屏幕上的组件,则可以为所有这些组件分配相同的单击事件,单击事件将有一个下拉列表以选择现有事件。要了解点击了哪个重新计算,请使用sender参数((Pixel)sender).FillColor = SelectedColor;

为了方便起见,我建议使用类似面板和绘制矩形的东西,这意味着你只需要一个单击事件来处理。所以现在你的问题变成“如何在面板上绘制矩形网格”和“我如何知道点击了哪个矩形”

因此,对于第一部分,您可以使用它而不是非常有效的方式。

创建一个存储像素信息的类

class MyPixel
{
    public Color PixelColour;
    public Rectangle Bounds;
}

在内存中保留一份列表

List<MyPixels> MyGrid = new List<MyPixels>();

然后在面板的onpaint事件中绘制面板上的像素

foreach(MyPixel Pixel in MyGrid)
{
    using(Brush B = new SolidBrush(Pixel.PixelColor))
    {
        e.Graphics.DrawRectangle(B, Pixel.Bounds);
    }
}

现在,在点击事件中,您需要知道点击了哪个像素

foreach(MyPixel Pixel in MyGrid)
{
    if (Pixel.Bounds.Contains(e.Location))
    {
        PixelClicked(Pixel);
    }
}

答案 1 :(得分:1)

虽然将每个矩形视为一个对象可能是正确的,但将每个矩形视为一个窗口控件可能是不正确的,特别是因为你有这么多矩形。

所以尝试创建自己的矩形对象:

public class MyRect {
  public Color FillColor { get; set; }
  public Rectangle Rectangle { get; set; }

  public MyRect(Rectangle r, Color c) {
    this.Rectangle = r;
    this.FillColor = c;
  }
}

现在你只需要保留一个对象列表并在一个Panel控件(或PictureBox)上绘制所有矩形:

private List<MyRect> myRectangles = new List<MyRect>();

public Form1() {
  InitializeComponent();

  myRectangles.Add(new MyRect(new Rectangle(10, 10, 64, 16), Color.Blue));
  myRectangles.Add(new MyRect(new Rectangle(20, 48, 16, 64), Color.Red));
}

private void panel1_Paint(object sender, PaintEventArgs e) {
  foreach (MyRect mr in myRectangles) {
    using (SolidBrush sb = new SolidBrush(mr.FillColor)) {
      e.Graphics.FillRectangle(sb, mr.Rectangle);
    }
  }
}

要处理矩形的“click”事件,您只需处理容器控件的MouseDownMouseClick事件,并确定自己点击了哪个矩形:

void panel1_MouseDown(object sender, MouseEventArgs e) {
  if (e.Button == MouseButtons.Left) {
    foreach (MyRect mr in myRectangles) {
      if (mr.Rectangle.Contains(e.Location)) {
        ChangeColor(mr, Color.Green);
      }
    }
    panel1.Invalidate();
  }
}

private void ChangeColor(MyRect mr, Color newColor) {
  mr.FillColor = newColor;
}

答案 2 :(得分:0)

我相信你会以错误的方式解决这个问题。你想要做的是直接绘制到位图。下面是一些使用PictureBox允许用户绘制的代码。

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

    namespace WindowsFormsApplication1
    {
        public partial class Form1 : Form
        {
            private Pen _pen;

            private bool _mouseDown;
            private int _startX;
            private int _startY;

            public Form1()
            {
                InitializeComponent();
            }

            private void Form1_Load(object sender, EventArgs e)
            {
                pictureBox1.Image = new Bitmap(pictureBox1.Width, pictureBox1.Height);
                _pen = new Pen(Color.Black);
            }

            private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
            {
                _mouseDown = true;

                _startX = e.X;
                _startY = e.Y;
            }

            private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
            {
                _mouseDown = false;
            }

            private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
            {
                if (_mouseDown)
                {
                    using (var graphics = Graphics.FromImage(pictureBox1.Image))
                    {
                        graphics.DrawLine(_pen, _startX, _startY, e.X, e.Y);
                        _startX = e.X;
                        _startY = e.Y;
                    }
                    pictureBox1.Invalidate();
                }
            }

        }
    }

这是编写绘画应用程序的常用方法,同时也非常高效。您还可以通过这种方式轻松保存,编写新工具或更好地操作图像。