创建网格比创建900个控件更容易

本文关键字:创建 更容易 控件 网格 900个 | 更新日期: 2023-09-27 18:12:41

我正在尝试编写一个程序,创建一个20px x 20px盒子的30x30网格。当您单击网格中的一个框时,它会改变框的颜色,并存储它的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;
};

但是加载时间太长了

创建网格比创建900个控件更容易

可以。

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

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

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;
    }
  }
}

呈现20x20框的自定义用户控件就可以达到这个效果。要获得鼠标点击的位置,取x和y值,除以20。

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

好吧,而不是创建900个控件,没有区别,如果它是在WindowsForms,或WPF高清加速,它会很慢。如果你真的需要所有的控件都在屏幕上可见,所以可能在某些时候也有900个,只是画矩形。你可以做一个仿真按钮。

绘制矩形,其中LeftTop线,将给用户三维填充,使其与线的颜色相反,并将给用户一个按钮填充。当然,您需要处理所有鼠标交互,如面板上的MouseMove, MouseDown, MouseUp(因为面板将是此时仅存在的控件),并找出发生什么矩形事件并相应地绘制该矩形。

我通常使用位图对象,并使用图形中的覆盖之一。DrawImage绘制它的放大。然后在缩放后的图像上方绘制网格线。

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

编辑对不起,目前没有现成的源代码。但基本上你要做的是创建一个新的system。drawing。bitmap它是30x30像素。在你想要绘制它的控件的paint even中,使用传入的Graphics Object(通常是. Graphics)并调用。drawimage。使用允许您指定输出大小的重载之一,以便您可以根据所需的缩放系数将其缩放。你还需要将图形对象上的。pixeloffsetmode设置为。none,否则物体将被缩放的1/2偏移。将. interpolationmode设置为。nearestneighbor,这样输出就不会模糊。这应该会给你一个完美对齐的"像素化"缩放图像。然后循环并绘制水平和垂直的网格线。

要处理鼠标单击,只需向控件的mouse down事件添加一个处理程序,并将输入位置除以缩放因子以获得实际的x和y坐标。然后更新源图像的像素,并在您要绘制的控件上调用.invalidate。这将导致它重新绘制更新后的图像。