DrawToBitmap无法截取所有项的屏幕截图

11

我目前有一段很有用的代码,是在 StackOverflow 上找到的:

form.DrawToBitmap(bmp, new Rectangle(0, 0, bmp.Width, bmp.Height));

我有一个带有几个文本框/下拉框和一个大图片框的表单,然后在这个大图片框上放置了较小的图片框。

当我查看截图时,它会显示表单,但是由于某种原因,已经放置在大图片框上方的较小图片框不被显示?


你能否发布整个代码?因为仅凭一行代码我们无法确定问题所在。 - coder
2个回答

18

我在Control.DrawToBitmap()的文档中看到了这个局限:

容器内的控件按相反顺序呈现。

这意味着,如果两个控件重叠,通常被渲染“在下面”的控件(首先绘制,然后被覆盖)将会最后渲染(因此它将覆盖通常覆盖它的控件)。在您的情况下,一个较小的控件完全绘制在一个较大的控件内部并在其上方,这种反向渲染将隐藏该控件。

尝试通过在较大的PictureBox上使用BringToFront()和SendToBack()来解决这个问题。在绘制到位图之前调用BringToFront(),完成后再调用SendToBack()。如果不希望用户看到屏幕闪烁,请尝试在进行任何 Z-order 更改之前调用SuspendLayout(),然后在重新设置正确的Z-order之后调用ResumeLayout(true)。


1
非常感谢您的回复,Keith。这个方法完美地解决了我的问题。正如您所说,我只需在大图框上调用BringToFront(),然后截取屏幕截图,最后再调用SendToBack()即可。 - Mike91

1

感谢KeithS帮我解决问题!

对于那些需要代码实现反转和再次反转的人,这是代码:

    private void ReverseControlZIndex(Control parentControl)
    {
        var list = new List<Control>();
        foreach (Control i in parentControl.Controls)
        {
            list.Add(i);
        }
        var total = list.Count;
        for (int i = 0; i < total / 2; i++)
        {
            var left = parentControl.Controls.GetChildIndex( list[i]);
            var right = parentControl.Controls.GetChildIndex(list[total - 1 - i]);

            parentControl.Controls.SetChildIndex(list[i], right);
            parentControl.Controls.SetChildIndex(list[total - 1 - i], left);
        }                        
    }

    private void SaveImage()
    {
        SaveFileDialog sf = new SaveFileDialog();
        sf.Filter = "Bitmap Image (.bmp)|*.bmp|Gif Image (.gif)|*.gif|JPEG Image (.jpeg)|*.jpeg|Png Image (.png)|*.png|Tiff Image (.tiff)|*.tiff|Wmf Image (.wmf)|*.wmf";
        if (sf.ShowDialog() == DialogResult.OK)
        {
            int width = pnlCanvas.Size.Width;
            int height = pnlCanvas.Size.Height;

            Bitmap bm = new Bitmap(width, height);


            SuspendLayout();
            // reverse control z-index
            ReverseControlZIndex(pnlCanvas);

            pnlCanvas.DrawToBitmap(bm, new Rectangle(0, 0, width, height));

            // reverse control z-index back
            ReverseControlZIndex(pnlCanvas);
            ResumeLayout(true);

            bm.Save(sf.FileName, ImageFormat.Bmp);
        }

    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接