【问题标题】:C# Dynamic Form HelpC# 动态表单帮助
【发布时间】:2011-06-22 19:26:20
【问题描述】:

我正在尝试使用图片框在 C# 中制作一个 Tile-Map 编辑器(我能想到的将图块放入表单的最简单方法)

生成图片框的代码是:

public void Generate_Tiles(int width, int height)
        {
            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    System.Windows.Forms.PictureBox picturebox = new PictureBox();
                    picturebox.BackColor = SystemColors.ActiveCaption;
                    picturebox.Cursor = Cursors.Cross;
                    picturebox.Location = new System.Drawing.Point((x*32) + 4, (y*32) + 4);
                    picturebox.Name = x+y+"tile";
                    picturebox.Size = new System.Drawing.Size(32, 32);
                    picturebox.TabIndex = 0;
                    picturebox.TabStop = false;
                    picturebox.Click += new System.EventHandler(TileBox_Clicked));
                    map.Controls.Add(picturebox);
                }
            }
            MessageBox.Show("Done");
        }

只要我一次使用少量图片框(8 x 8 似乎是它想要在相当长的时间内显示的最大值),那部分就可以了

我想在用户单击指定的图片框时执行一些操作,这就是为什么我有一个 onclick 方法,这就是我遇到问题的地方,所有的图片框都被称为...图片框。据我所知,我无法判断用户点击了哪个图片框。

无论如何,我可能需要重新制作动态表单的工作方式,因为我无法获得很多图片框,但我认为主要问题仍然存在,只要我希望它是动态的(我这样做),并不是所有的瓦片地图的大小都是一样的。

我从来没有做过这样的事情,我一直在寻找覆盖 onclick 事件的方法......我找不到,而且我找不到一个可以使用最新的好磁贴引擎(除了 XNA,但我认为这对于一个简单的平铺编辑器来说有点过头了)

我可能会朝着相反的方向前进,然后我需要做的事情。

【问题讨论】:

    标签: c# forms dynamic onclick


    【解决方案1】:

    您的事件处理程序中的发送者将是被点击的PictureBox

        void TileBox_Clicked(object sender, EventArgs e)
        {
            PictureBox pictureBox = sender as PictureBox;
            if(pictureBox != null)
            {
                //do stuff with your pictureBox
            }
        }
    

    【讨论】:

    • ...为了完整起见,您可能希望通过在该步骤之后检查 mull 来确保您的转换工作 - 您可能不小心将另一个对象的 Click 事件连接到该方法(虽然可能只是我做这样的事情;))...
    • @ZombieSheep 是的;预计会检查 null ...为“完整性”进行编辑;)
    • >_> 我想我忘记了作为 PictureBox 的对象的名称是否无关紧要,如果作为发送者的对象专门指的是我需要的对象,我想,是试图改变 1通过发件人的图片框会改变它们,但现在我想起来,它们都有唯一的指针......
    【解决方案2】:

    你不能在事件处理程序中将 sender 对象转换为 PictureBox 并使用它吗?

    【讨论】:

      【解决方案3】:

      事件处理程序中的第一个参数是被点击的控件(它将是 PictureBox。

      private void pictureBox1_Click(object sender, System.EventArgs e)
      {
         PictureBox pb = (PictureBox)sender;
      
         // ...
      }
      

      【讨论】:

        【解决方案4】:

        我也在地图图块编辑器中采用了这种方法。正如其他人所说,您可以使用 sender 参数并将其转换为 PictureBox 以获取被单击的 PictureBox 对象。但我想你会发现(你可能已经有)一个合适的地图大小真的会减慢速度。

        您可能会重新考虑 XNA。它看起来很复杂,而且要让某些东西正常工作并不像生成一堆 PictureBox 对象那么容易。但它很快,而且您可以相当快地显示 2D 地图。您还可以更轻松地扩展它,例如,如果您希望地图具有不同的可编辑图层(地形等)。

        【讨论】:

        • 我们实际上是将每个图块编译成一个大图像,256/256 加载速度足够快,而且它在每次图块编辑时重绘并不会过多阻碍编辑过程,我们计划制作它是 3d 而不是通过 XNA 自顶向下,但现在我们希望我们的游戏开发人员使用基本系统,然后我们会担心让它看起来对最终用户来说很好:D
        【解决方案5】:

        实际上有很多方法可以做到这一点。我认为最简单的方法是使用您的事件处理程序的sender,它会将您指向点击的按钮:

        private void PictureBox_Click(object sender, EventArgs e)
        {
             var box = sender as PictureBox;
             if (box != null)
             {
                 //...
        

        您还可以动态创建和添加事件处理程序,这是一个有趣的选择:

                //...
                for (int x = 0; x < width; x++)
                {
                    for (int y = 0; y < height; y++)
                    {
                        System.Windows.Forms.PictureBox picturebox = new PictureBox();
        
                        pictureBox.Click += new Action<object, EventArgs>(
                             (sender, e) => { doStuff(pictureBox); }
                        );
        

        在上面的代码中,doStuff 获取pictureBox 作为参数,因此它知道它应该处理哪个对象。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-09-04
          • 1970-01-01
          相关资源
          最近更新 更多