2

我正在开发一个 ASP.NET 网站,其中有一些数据表。我想生成这些数据的图像,以便我可以在论坛上显示这些图像(例如)。我过去使用的方法很简单:我在内存中创建一个 System.Windows.Forms.DataGridView 控件(是的,winforms 控件!),设置样式,加载一些列和行,然后使用它的 DrawToBitmap 方法生成图像(基本上是控件的“屏幕截图”)。

例子:

    private static Image WriteGrid(List<object[]> data)
    {
        var grid = new DataGridView();
        grid.Columns.Add("Column 1", "Column 1");  
        grid.Columns.Add("Column 2", "Column 2"); 
        grid.Columns.Add("Column 3", "Column 3");        

        // Ensure columns are large enough to display all data
        grid.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;

        foreach (var row in data)
            grid.Rows.Add(row);         

        var width = GetWidth(grid);
        var height = GetHeight(grid);

        grid.Width = width;
        grid.Height = height;

        var bmp = new Bitmap(width, height);
        grid.DrawToBitmap(bmp, grid.Bounds);
        bmp.Save(Util.Server.MapPath("~/Images/grid.png"), ImageFormat.Png);
        return bmp;
    }

这非常有效,但是我无法计算我应该生成的图像的大小,以及 DataGridView 控件本身的大小。默认情况下,它是 100x100(我认为),因此会删除大部分数据,这对于图像生成毫无用处,因为您显然无法滚动图像......

所以我想计算 DataGridView 应该的宽度和高度,以便它可以在没有滚动条的情况下显示所有数据。

我认为这很简单:遍历列并添加它们的 Width 属性以获得总宽度,然后遍历行并添加它们的 Height 属性以获得总高度:

    private static int GetWidth(DataGridView grid)
    {
        int width = 0;
        foreach (DataGridViewColumn col in grid.Columns)
        {
            width += col.Width;
        }
        return width;
    }

    private static int GetHeight(DataGridView grid)
    {
        int height = grid.ColumnHeadersHeight;
        foreach (DataGridViewRow row in grid.Rows)
        {
            height += row.Height;
        }
        return height;
    }

不过,这就是问题所在……每列的 Width 属性始终返回 100,我假设这是列的(默认)MinimumWidth,而不是列的实际宽度。因此,对于三列,我的网格始终为 300 像素宽,即使这些列实际上每列都比 100 像素宽得多。

我猜这是由于我在内存中创建网格而不是实际将其绘制到某个表格这一事实引起的?我相信这应该可行,但出于某种原因,无论我做什么,列宽总是 100 ......这使我的整个想法毫无用处,因为我无法计算网格和图像的必要宽度。我想我可以测量每列中的所有数据字符串并基本上手动调整它们的大小,但我真的不想......一定有更好的方法吗?

我究竟做错了什么?谢谢!

4

1 回答 1

1

使用 col.GetPreferredWidth(DataGridViewAutoSizeColumnMode.AllCells, true) 这似乎返回您期望的宽度(至少对我而言)。

于 2014-04-01T19:30:02.503 回答