我希望能够在图片框内创建X x Y数量的框/圆圈/按钮。就像Windows Defrag工具一样。

我试图创建一个布局并继续向其中添加按钮或图片框,但是它的速度非常慢,在崩溃了200个左右的图片框后,它耗尽了窗口句柄或内存。

有什么选择?您能给我看一段简单的代码来添加框吗,就像Defrag工具一样,在这里我可以像
box[x,y].Color = Green随着我的应用取得进展?

目前我有这个:

        private void ResetTableStyles()
        {
            boardPanel.Controls.Clear();
            boardPanel.RowStyles.Clear();
            boardPanel.ColumnStyles.Clear();

            boardPanel.RowCount = Rows;
            boardPanel.ColumnCount = Columns;

            for (int i = 0; i < Rows; i++)
            {
                boardPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 100f));
            }
            for (int j = 0; j < Columns; j++)
            {
                boardPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100f));
            }
        }

        private void CreateButtons()
        {
            for (int i = 0; i < Rows; i++)
            {
                for (int j = 0; j < Columns; j++)
                {
                    var button = new PictureBox
                    {
                        BackColor = Color.White,
                        Dock = DockStyle.Fill,
                        Margin = Padding.Empty,
                        Tag = new Point(i, j),
                        BackgroundImageLayout = ImageLayout.Stretch
                    };
                    //button.MouseDown += button_MouseDown;
                    boardPanel.Controls.Add(button, j, i);
                }
            }
        }


正如我说的那样,它不起作用,但是一段时间后它会崩溃,并且需要很长时间。

最佳答案

也许有人有更好的答案,但是您可以使用Panel作为画布并处理Paint事件,以在Panel上绘制彩色矩形。然后,您可以使用鼠标事件(例如MouseMove)来确定您所在的单元格。

这是概念的超简单证明。

// Data.cs
namespace WindowsFormsApplication
{
   public class Data
   {
      public int State { get; set; }
      public string Tip { get; set; }
   }
}

// Form1.cs
using System;
using System.Drawing;
using System.Windows.Forms;

namespace WindowsFormsApplication
{
   public partial class Form1 : Form
   {
      public Form1()
      {
         InitializeComponent();

         var rng = new Random();
         _data = new Data[30 * 30];
         for (int i = 0; i < _data.Length; i++)
         {
            _data[i] = new Data
            {
               State = rng.Next(0, 3),
               Tip = $"Data at index: {i}"
            };
         }
      }

      private Data[] _data;

      private void panel1_Paint(object sender, PaintEventArgs e)
      {
         using (var brush = new SolidBrush(Color.Gray))
         using (var buffer = BufferedGraphicsManager.Current.Allocate(e.Graphics,
            new Rectangle(0, 0, 450, 450)))
         {
            for (int x = 0; x < 30; x++)
            {
               for (int y = 0; y < 30; y++)
               {
                  int dataIdx = (y * 30) + x;
                  Data data = _data[dataIdx];
                  if (data.State == 1)
                  {
                     brush.Color = Color.Blue;
                  }
                  else if (data.State == 2)
                  {
                     brush.Color = Color.Red;
                  }
                  else
                  {
                     brush.Color = Color.Gray;
                  }
                  buffer.Graphics.FillRectangle(brush, x * 15, y * 15, 15, 15);
                  buffer.Graphics.DrawLine(Pens.Black, 0, y * 15, 450, y * 15); //Gridline
               }
               buffer.Graphics.DrawLine(Pens.Black, x * 15, 0, x * 15, 450); //Gridline
            }
            buffer.Render(e.Graphics);
         }
      }

      private void panel1_MouseMove(object sender, MouseEventArgs e)
      {
         var point = e.Location;
         int x = point.X / 15;
         int y = point.Y / 15;
         int dataIdx = (y * 30) + x;
         System.Diagnostics.Debug.WriteLine(_data[dataIdx].Tip);
      }
   }
}


Data类表示面板上每个段后面的模型,非常简单。

Form1上放置了一个控件:大小为Panel的名为panel1450 x 450。面板上的每个单元格均为15 x 15,因此我们有30列30行。在Form1的构造函数中,我们初始化将用于绘制面板的Data

Form1.panel1_Paint内部,我们遍历单元格并查找给定单元格的Data实例。然后,基于State,设置单元格的颜色并绘制该颜色的矩形。这是在缓冲区上完成的,因此在绘画时面板不会闪烁。

Form1.panel1_MouseMove内部,我们使用鼠标指针相对于panel1的位置来确定鼠标悬停在哪个单元格上,获取该单元格的Data实例,并在调试窗口中显示Tip

您也许可以采用自定义的UserControl并以此为基础,以便您可以轻松地通过列和行访问每个单元格...您的上述box[x, y].Color = Colors.Green示例。

关于c# - 在图片框内动态创建点/正方形,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57910861/

10-09 14:01