2

私は非常に初歩的な描画プログラムを開発しています:複数の 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 配列に配置する方法を探しています。(画面上のすべての Rectangle に対して Pixel_Click メソッドを作成する必要はありません!) 最終的に次のようなものを呼び出せるようになることを望んでいます。

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

私の友人は、匿名デリゲートの使用を提案していますが、問題を解決するために匿名デリゲートを完全に使用する方法がわかりません。

C# Windows フォームで四角形の 2D 配列を生成する最良の方法は何でしょうか? 一度生成されたら、x と y のバリアント値に対して 1 つのメソッドでそれらにアクセスするにはどうすればよいでしょうか?

4

3 に答える 3

1

画面上のコンポーネントとして長方形を維持したい場合は、それらすべてに同じクリックイベントを割り当てることができます。クリックイベントには、既存のイベントを選択するための小さなドロップダウンがあります。クリックされたリカンタングルを知るには、senderパラメータを使用します((Pixel)sender).FillColor = SelectedColor;

簡単にするために、パネルのようなものを使用してその上に長方形を描画することをお勧めします。つまり、処理するクリックイベントは1つだけです。したがって、質問は「パネルに長方形のグリッドを描画するにはどうすればよいですか」と「どの長方形がクリックされたかを知るにはどうすればよいですか」になります。

したがって、最初の部分では、これはあまり効率的な方法ではありません。

ピクセルに関する情報を格納するクラスを作成します

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);
    }
}
于 2012-07-03T15:26:08.987 に答える
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);
    }
  }
}

長方形の「クリック」イベントを処理するには、コンテナコントロールの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;
}
于 2012-07-03T15:26:38.270 に答える
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();
                }
            }

        }
    }

これは、ペイント アプリを作成する通常の方法であり、パフォーマンスも非常に優れています。この方法で、簡単に保存したり、新しいツールを作成したり、画像をより適切に操作したりすることもできます。

于 2012-07-03T15:30:37.163 に答える