我正在尝试编写一个程序来创建一个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才能加载。
答案 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个当代,只是绘制矩形。你可以做一个 按钮的仿真。
绘制矩形,其中Left
和Top
行更暗然后正确和底部< / em>,将3D填充给用户,使其成为线条的反色,并且它将给用户填充按钮。您肯定需要处理所有鼠标互动,例如面板上的MouseMove
,MouseDown
,MouseUp
(因为该面板将仅为 < / em>控制此时出现),并找出发生了什么矩形事件并相应地绘制该矩形。