我正在开发一个非常基本绘图程序:一个由多个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的变量值访问它们?
答案 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”事件,您只需处理容器控件的MouseDown
或MouseClick
事件,并确定自己点击了哪个矩形:
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();
}
}
}
}
这是编写绘画应用程序的常用方法,同时也非常高效。您还可以通过这种方式轻松保存,编写新工具或更好地操作图像。