比创建900控件c#.net更简单的创建网格的方法

时间:2011-10-26 19:38:03

标签: c#

我正在尝试编写一个程序来创建一个30x30网格的20px x 20px盒子。单击网格中的框时,它会更改框的颜色并存储其RGB值以及x,y坐标(隐藏在框中)。所以基本上我正在做一个简单的绘画程序。它的目的是帮助我为30x30像素网格编程LED RGB动画。所以,一旦我绘制了一些东西,我就会导出图像中每个像素的X,Y,R,G,B。

所以我的问题是,有一种简单的方法可以做到这一点。没有创建900个按钮并将它们组合在一起?我有点工作:

Panel BU = new Panel();

BU.AutoSize = false;
BU.Location = new System.Drawing.Point(xpos, ypos);
BU.BackColor = System.Drawing.Color.Transparent;
BU.Font = new System.Drawing.Font("Microsoft Sans Serif", 5, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
BU.Name = row_num + " x " + col_num;
BU.Size = new System.Drawing.Size(20, 20);
BU.MouseDown +=new MouseEventHandler(BU_MouseDown);
BU.MouseEnter +=new EventHandler(BU_MouseEnter);

this.Controls.Add(BU);

xpos = xpos + 20;

px_num++;
col_num++;

if (col_num == 30) 
{ 
   col_num = 0; 
   ypos = ypos + 20;
   row_num++; 
   xpos = 0;
};

但需要WAAAAAY才能加载。

4 个答案:

答案 0 :(得分:4)

创建一个面板,并在其中处理网格绘制和鼠标事件。

超级简单的例子,无需优化,闪烁快乐:

private Color[,] _Colors = new Color[30, 30];

private void panel1_Paint(object sender, PaintEventArgs e) {
  int left = 0;
  int top = 0;

  for (int y = 0; y < 30; y++) {
    left = 0;
    for (int x = 0; x < 30; x++) {
      Rectangle r = new Rectangle(left, top, 20, 20);

      using (SolidBrush sb = new SolidBrush(_Colors[x, y]))
        e.Graphics.FillRectangle(sb, r);
      ControlPaint.DrawBorder3D(e.Graphics, r, Border3DStyle.Raised, Border3DSide.Left | Border3DSide.Top | Border3DSide.Right | Border3DSide.Bottom);

      left += 20;
    }
    top += 20;
  }
}

private void panel1_MouseDown(object sender, MouseEventArgs e) {
  if (e.Button == MouseButtons.Left) {
    int left = 0;
    int top = 0;

    for (int y = 0; y < 30; y++) {
      left = 0;
      for (int x = 0; x < 30; x++) {
        Rectangle r = new Rectangle(left, top, 20, 20);

        if (r.Contains(e.Location)) {
          _Colors[x, y] = Color.Red;
          panel1.Invalidate();
        }
        left += 20;
      }
      top += 20;
    }
  }
}

答案 1 :(得分:1)

呈现20x20盒子的自定义用户控件可以解决问题。要获取鼠标单击的位置,请取x和y值除以20。

这里非常相似:https://github.com/i-e-b/DBSS/blob/master/DBSS/BigGrid/SheetView.cs

答案 2 :(得分:1)

我通常使用Bitmap对象并使用Graphics.DrawImage中的一个覆盖来绘制它放大。然后我在缩放图像的顶部绘制网格线。

我现在正在为你挖掘一些源代码。

修改 对不起,暂时没有源代码。但基本上你想要做的是创建一个30x30像素的新system.drawing.bitmap。在绘制甚至是想要绘制它的控件中,使用传入的Graphics对象(通常是e.graphics)并调用.DrawImage。使用其中一个重载,允许您指定输出大小,以便您可以通过所需的任何缩放系数将其缩小。您还需要将图形对象上的.PixelOffsetMode设置为.none,否则事物将被缩放1/2偏移。将.InterpolationMode设置为.NearestNeighbor,以使输出不模糊。这应该会给你一个完美对齐的“像素化”缩放图像。然后循环并绘制水平和垂直网格线。

要处理鼠标点击,只需在控件鼠标按下事件中添加处理程序,然后将输入位置除以缩放系数即可获得真实的x和y坐标。然后更新源图像的像素,并在您要绘制的控件上调用.invalidate。这将使其重新绘制更新的图像。

答案 3 :(得分:1)

好吧,不是创建900个控件,如果它是在WindowsForms中制作的,或者在带有HD加速的WPF中没有区别,它将会很慢。 可以做什么,如果你真的需要总是在屏幕上显示所有控件,那么在某些点上也可能有900个当代,只是绘制矩形。你可以做一个 按钮的仿真

绘制矩形,其中LeftTop更暗然后正确底部< / em>,将3D填充给用户,使其成为线条的反色,并且它将给用户填充按钮。您肯定需要处理所有鼠标互动,例如面板上的MouseMoveMouseDownMouseUp (因为该面板将仅为 < / em>控制此时出现),并找出发生了什么矩形事件并相应地绘制该矩形。