Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#Windows窗体控件到图像?_C#_Winforms_Graphics - Fatal编程技术网

C#Windows窗体控件到图像?

C#Windows窗体控件到图像?,c#,winforms,graphics,C#,Winforms,Graphics,我正在尝试创建面板的图像并将其保存到文件夹中。问题是面板有滚动条,生成的图像仅用于面板的可见部分 我使用的代码类似于Panel.DrawToImage。这里有什么帮助可以将整个面板保存为图片,而不仅仅是可见部分吗?Hmmm。。。这听起来像(正如您在原始问题中没有这样说),但您是否有一个picturebox作为面板容器内的容器,即嵌套容器 您是否考虑过这样做: // Assume pic is the type of PictureBox and the image property is ass

我正在尝试创建面板的图像并将其保存到文件夹中。问题是面板有滚动条,生成的图像仅用于面板的可见部分

我使用的代码类似于Panel.DrawToImage。这里有什么帮助可以将整个面板保存为图片,而不仅仅是可见部分吗?

Hmmm。。。这听起来像(正如您在原始问题中没有这样说),但您是否有一个picturebox作为面板容器内的容器,即嵌套容器

您是否考虑过这样做:

// Assume pic is the type of PictureBox and the image property is assigned PictureBox pic; // And that the picturebox is embedded in the Panel variable p. p.Controls.Add(pic); // ... // So why not do this? pic.Image.Save(...); //假设pic是PictureBox的类型,并且已指定image属性 图片盒; //并且picturebox嵌入在面板变量p中。 p、 控件。添加(pic); // ... //那么为什么不这样做呢? pic.Image.Save(…); Image类的
Save
方法有5个重载,请在方便的时候选择一个

希望这有帮助, 顺致敬意,
Tom.

考虑暂时增大面板的大小,调用p.Layout(),然后调用p.DrawToImage()

也许您可以将控件克隆到另一个(隐藏的)表单上,使其达到所需的大小(这样滚动条就不会显示),然后调用
DrawToImage()
那样工作?

我认为WM\u打印消息会很有帮助。这是一个几乎有效的示例。(它仍然会打印滚动条本身,并且“滚动”部分的背景会丢失。)也许您可以使用它并使其工作,或者有更多WinForms经验的人可以将其提升到下一个级别

在类中声明以下内容:

[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);

private const int WM_PRINT = 791;

/// <summary>
/// The WM_PRINT drawing options
/// </summary>
[Flags]
private enum DrawingOptions
{
    /// <summary>
    /// Draws the window only if it is visible.
    /// </summary>
    PRF_CHECKVISIBLE = 1,

    /// <summary>
    /// Draws the nonclient area of the window.
    /// </summary>
    PRF_NONCLIENT = 2,
    /// <summary>

    /// Draws the client area of the window.
    /// </summary>
    PRF_CLIENT = 4,

    /// <summary>
    /// Erases the background before drawing the window.
    /// </summary>
    PRF_ERASEBKGND = 8,

    /// <summary>
    /// Draws all visible children windows.
    /// </summary>
    PRF_CHILDREN = 16,

    /// <summary>
    /// Draws all owned windows.
    /// </summary>
    PRF_OWNED = 32
}
编辑:这里有一个替代的绘画策略,可以让你找到你想要的。我在做一些假设,但也许会奏效。它首先在位图上绘制虚拟背景,并删除滚动条:

using (Bitmap screenshot = new Bitmap(this.panel1.DisplayRectangle.Width, this.panel1.DisplayRectangle.Height))
using (Graphics g = Graphics.FromImage(screenshot))
{
    g.FillRectangle(SystemBrushes.Control, 0, 0, screenshot.Width, screenshot.Height);
    try
    {
        SendMessage(this.panel1.Handle, WM_PRINT, g.GetHdc().ToInt32(), (int)(DrawingOptions.PRF_CHILDREN | DrawingOptions.PRF_CLIENT | DrawingOptions.PRF_OWNED));
    }
    finally
    {
        g.ReleaseHdc();
    }
    screenshot.Save("temp.bmp");
}

我会创建一个大小正确的位图(并用正确的颜色清除它,或者为它绘制面板的背景图像),然后在所有子控件上循环。DrawToImages将每个控件都映射到正确的位置。

这里没有令人满意的答案,DrawToBitmap只能绘制用户可以看到的内容。由于父级对控件大小施加的限制,诸如事先更改面板的位置和大小之类的技巧通常会很快耗尽气体。表单本身永远不会比屏幕大,现在还取决于目标机器上视频适配器的分辨率

一个丑陋的方法是多次运行DrawToBitmap,在每次调用之间更改面板的AutoScrollPosition属性。您必须将生成的图像缝合在一起。当然要特别注意最后一个,因为它不会像其他的那么大


一旦您开始考虑这样的代码,您真的应该考虑打印文档或报表生成器。这样做的一个好处是打印输出看起来更干净。由于视频和打印机分辨率的巨大差异,打印的屏幕截图总是很难看。

你需要使你的面板
AutoZize=True
AutoScroll=False
,而不是把它放进另一个容器,使容器
AutoScroll=True

我想他想要“屏幕截图”在他的窗体上有一个容器控件。@hometoast:哦……现在我明白了……嗯……Alt+PrtScrn如何,然后将它粘贴到mspaint中?或者其他屏幕抓取工具?简言之,答案是否定的,因为屏幕截图显示的是什么,而不管图像是否被剪裁!控件无论如何都大于屏幕的显示大小。所以滚动条是不可能摆脱的!!谢谢这似乎是目前唯一的办法!!不过要做点工作!!再次感谢!!嘿,伙计们,这只是一个更新。。。。解决方法是在内存中创建相同的控件,定义自定义高度和宽度,然后调用DrawToBitmap函数!!这是一个甜蜜的成功!!希望这能帮助别人!!
using (Bitmap screenshot = new Bitmap(this.panel1.DisplayRectangle.Width, this.panel1.DisplayRectangle.Height))
using (Graphics g = Graphics.FromImage(screenshot))
{
    g.FillRectangle(SystemBrushes.Control, 0, 0, screenshot.Width, screenshot.Height);
    try
    {
        SendMessage(this.panel1.Handle, WM_PRINT, g.GetHdc().ToInt32(), (int)(DrawingOptions.PRF_CHILDREN | DrawingOptions.PRF_CLIENT | DrawingOptions.PRF_OWNED));
    }
    finally
    {
        g.ReleaseHdc();
    }
    screenshot.Save("temp.bmp");
}