c# - 在图片框内动态创建点/正方形

标签 c# .net winforms

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

我试图创建一个布局并继续向其添加按钮或图片框,但它非常慢,并且在 200 个左右的图片框之后崩溃,窗口句柄或内存不足。

有什么选择?你能告诉我一段简单的代码来添加框,就像碎片整理工具一样,我可以像这样轻松地访问它们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作为 Canvas 并处理PaintPanel 上绘制彩色矩形的事件.然后您可以使用鼠标事件,例如 MouseMove ,以确定您在哪个单元格上。

这是一个 super 简单的概念证明。

// 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 class 代表面板上每个部分背后的模型,并且非常简单。
Form1上面放置了一个控件:Panel命名为 panel1大小为 450 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/

相关文章:

c# - 是否有必要在 finally block 中处理数据集

c# - 如何从命令 Visual Studio Extension 2017 获取 IWpfTextView

c# - C# 命名指南

asp.net - 升级到 WebAPI 2.1 时出错 XmlDocumentationProvider 未实现接口(interface)成员 GetDocumentation

c# - 应该禁用和隐藏控件还是只是隐藏控件?

c# - 如何处理 System.OverflowException

c# - 在 C# 中将整数列表转换为逗号分隔的数字字符串的最简单方法是什么?

c# - 使用 Entity Framework /LINQ,您可以一劳永逸地定义一个默认对象吗?

.Net SQL Server 数据库监控 - 插入、更新、删除

C# - 将 XML 节点值设置为来自 StreamReader 结果的 Stings