title: C# Create Grid For Painting Pixels and Rendering Text
body: <p>I'm trying to find the best path to go about creating a pixel "grid" that would allow basic paint functions such as coloring the pixels by clicking and moving the mouse, selecting an area for copying, pasting, or moving, or using other graphics functions in order to render text or shapes to the pixels. I've looked at a few samples, such as <a href="https://stackoverflow.com/questions/13194674/foreach-loop-to-create-100-buttons-painting-all-buttons-at-same-time-as-to-prev">this example</a> which overrides the panel control and has a similar look to what I'm trying to achieve, but the painting is slow and it seems like it wouldn't perform well for drawing with the mouse. Is there a control, or one that I could override, that would allow for the functionality that I'm looking for?</p>
  
  <p>Here's a sample of what the above example looks like:
  <a href="https://i.stack.imgur.com/zk2CA.png" rel="nofollow noreferrer">Sample pixel grid</a></p>
  
  <p>And the code I adapted from the above example:</p>
  
  <pre><code>public class Pixel
  {
      public Rectangle Bounds { get; set; }
      public bool IsOn { get; set; }
      public bool IsSelected { get; set; }
  }
  </code></pre>
  
  <p><br></p>
  
  <pre><code>public class PixelGridControl : Panel
  {
      public int Columns = 99;
      public int Rows = 63;
      private readonly Pixel[,] pixels;
  
      public PixelGridControl()
      {
          this.DoubleBuffered = true;
          this.ResizeRedraw = true;
  
          // initialize pixel grid:
          pixels = new Pixel[Columns, Rows];
          for (int y = 0; y &lt; Rows; ++y)
          {
              for (int x = 0; x &lt; Columns; ++x)
              {
                  pixels[x, y] = new Pixel();
              }
          }
      }
  
      // adjust each column and row to fit entire client area:
      protected override void OnResize(EventArgs e)
      {
          int top = 0;
          for (int y = 0; y &lt; Rows; ++y)
          {
              int left = 0;
              int height = (this.ClientSize.Height - top) / (Rows - y);
              for (int x = 0; x &lt; Columns; ++x)
              {
                  int width = (this.ClientSize.Width - left) / (Columns - x);
                  pixels[x, y].Bounds = new Rectangle(left, top, width, height);
                  left += width;
              }
              top += height;
          }
          base.OnResize(e);
      }
  
      protected override void OnPaint(PaintEventArgs e)
      {
          e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
          for (int y = 0; y &lt; Rows; ++y)
          {
              for (int x = 0; x &lt; Columns; ++x)
              {
                  if (pixels[x, y].IsOn)
                  {
                      e.Graphics.FillRectangle(Brushes.Gold, pixels[x, y].Bounds);
                  }
                  else
                  {
                      ControlPaint.DrawButton(e.Graphics, pixels[x, y].Bounds,
                                              ButtonState.Normal);
                  }
              }
          }
          base.OnPaint(e);
      }
  
      // determine which button the user pressed:
      protected override void OnMouseDown(MouseEventArgs e)
      {
          for (int y = 0; y &lt; Rows; ++y)
          {
              for (int x = 0; x &lt; Columns; ++x)
              {
                  if (pixels[x, y].Bounds.Contains(e.Location))
                  {
                      pixels[x, y].IsOn = true;
                      this.Invalidate();
                      MessageBox.Show(
                        string.Format("You pressed on button ({0}, {1})",
                        x.ToString(), y.ToString())
                      );
                  }
              }
          }
          base.OnMouseDown(e);
      }
  }
  </code></pre>