C#图形吸引了Panel

时间:2015-02-27 22:27:13

标签: c# winforms

我在winforms并且出于学校的原因试图在其中制作一个tileengine。我在Panel中绘制tileset时遇到了麻烦。而是在图表的左上角和面板后面绘图。

这是代码:

private void gfxPanel_Paint(object sender, PaintEventArgs e)
        {
            using (Bitmap sourceBmp = new Bitmap("../../assets/art/Tileset5.png"))
            {
                Size s = new Size(level.TileWidth, level.TileHeight);
                Rectangle destRect = new Rectangle(Point.Empty, s);

                for (int row = 0; row <= level.MapHeight; row++)
                    for (int col = 0; col < level.MapWidth; col++)
                    {
                        PictureBox p = new PictureBox();
                        p.Size = s;
                        Point loc = new Point(level.TileWidth * col, level.TileHeight * row);
                        Rectangle srcRect = new Rectangle(loc, s);
                        Bitmap tile = new Bitmap(level.TileWidth, level.TileHeight);
                        Graphics G = Graphics.FromImage(tile);
                        G.DrawImage(sourceBmp, destRect, srcRect, GraphicsUnit.Pixel);
                        p.Image = tile;
                        p.Location = loc;
                        this.Controls.Add(p);
                    }
            }
        }

这里发生了什么,我做错了什么?

2 个答案:

答案 0 :(得分:2)

您正在将图片框添加到表单(this)。而是将它们添加到面板中:

gfxPanel.Controls.Add(p);

注意:您正在paint事件中添加控件,这意味着您将添加多组相同的控件。只要需要在屏幕上重绘控件,就会调用paint。您应该只添加一次控件,可能在表单加载事件中。如果要使用paint事件,则应使用事件参数中发送的图形对象直接在屏幕上绘制,而不是添加包含要绘制内容的控件。

答案 1 :(得分:1)

如果您真的只想在没有互动的情况下绘制图块,可以像这样更改Paint事件:

private void  gfxPanel_Paint(object sender, PaintEventArgs e)
{
    using (Bitmap sourceBmp = new Bitmap("../../assets/art/Tileset5.png"))
    {
        Size s = new Size(levelTile.Width, levelTile.Height);

        for (int row = 0; row <= levelMap.Height; row++)
            for (int col = 0; col < levelMap.Width; col++)
            {
                Rectangle destRect =  new Rectangle(
                         col * levelTile.Width, row * levelTile.Height, 
                         levelTile.Width, levelTile.Height);
                Point loc = new Point(levelTile.Width * col, levelTile.Height * row);
                Rectangle srcRect = new Rectangle(loc, s);
                e.Graphics.DrawImage(sourceBmp, destRect, srcRect, GraphicsUnit.Pixel);
            }
    }

}

请注意,我没有完全重写代码。如果要以与TileSet中显示的相同的顺序和大小绘制切片,则可以直接绘制整个TileSet。