C# Winforms绘画是同步完成的还是非同步完成的?

C# Winforms绘画是同步完成的还是非同步完成的?,c#,.net,screenshot,C#,.net,Screenshot,我有一张有三个面板的表格。顶部面板包含列表框,中间面板包含网格,底部面板包含网格。我需要截图的底部网格,但有时有更多的行在网格中,你需要滚动查看每一行。在截图之前,我想将底部网格设置为表单的大小,可以通过设置.Visible to false来实现这一点。我的问题是,截图是在表单重新绘制以显示网格作为表单大小之前拍摄的。在我执行代码截图之前,如何保证表单已重新绘制/重新绘制 我用ArsenMkrt的答案来截图 编辑:网格是Infragistics UltraGrid。使用Applicaton.D

我有一张有三个面板的表格。顶部面板包含列表框,中间面板包含网格,底部面板包含网格。我需要截图的底部网格,但有时有更多的行在网格中,你需要滚动查看每一行。在截图之前,我想将底部网格设置为表单的大小,可以通过设置.Visible to false来实现这一点。我的问题是,截图是在表单重新绘制以显示网格作为表单大小之前拍摄的。在我执行代码截图之前,如何保证表单已重新绘制/重新绘制

我用ArsenMkrt的答案来截图


编辑:网格是Infragistics UltraGrid。

使用
Applicaton.DoEvents()
允许处理所有windows消息,因此从调用返回时将完成调整大小和绘制。然后,您可以立即拍摄表单的屏幕截图。

使用
Applicaton.DoEvents()
允许处理所有windows消息,以便在呼叫返回时完成调整大小和绘制。然后,您可以立即拍摄表单的屏幕截图。

如果您使用的是Winforms DataGrid,您不需要经历所有这些麻烦。只用


如果您使用的是Winforms数据网格,那么您不需要经历所有这些麻烦。只用

调用表单的Update()方法。如果有任何悬而未决的油漆,那么您可以确保它们将被执行,并且表单已完全绘制。这里的情况肯定是这样的,隐藏面板需要表单重新绘制其背景

这只适用于您自己的窗体,不适用于另一个进程拥有的窗口。使用表单的DrawToBitmap()方法通常也可以(不需要同步),但并非所有子控件都支持它。值得注意的是,RichTextBox和WebBrowser以及许多其他ActiveX控件无法正确实现底层Windows消息。

调用表单的Update()方法。如果有任何悬而未决的油漆,那么您可以确保它们将被执行,并且表单已完全绘制。这里的情况肯定是这样的,隐藏面板需要表单重新绘制其背景


这只适用于您自己的窗体,不适用于另一个进程拥有的窗口。使用表单的DrawToBitmap()方法通常也可以(不需要同步),但并非所有子控件都支持它。值得注意的是,ReXTrimeBox和WebBub以及许多其他ActiveX控件都没有正确地实现底层Windows消息。

<代码> doStase绝对是您最不想考虑的事情。首先,因为它是
VB.NET
而不是
C
,所以它不可用。第二,因为在VB/VB.NET中,由于可重入性,它会导致问题。第三,有一种更好的方法99.99999999999999%的时间使用它,而不得不使用它意味着你做错了什么。Application.DoEvents()与语言无关。它可从所有.NET语言获得。确定。谢谢-我不知道C#也有这个缺陷。删除第一个反对意见,删除第二个反对意见中的VB/VB.NET引用中的
。其余的仍然有效不过,我会取消否决票,因为基于这一修正,这可能是仓促的。但是,我不能投票赞成,因为另外两个原因。你的权利,它确实有它的风险,重新入侵者,并没有意识到在DATGRIDVIEW上有一个可用的位图。<代码> doStase绝对是你考虑的最后一件事。首先,因为它是
VB.NET
而不是
C
,所以它不可用。第二,因为在VB/VB.NET中,由于可重入性,它会导致问题。第三,有一种更好的方法99.99999999999999%的时间使用它,而不得不使用它意味着你做错了什么。Application.DoEvents()与语言无关。它可从所有.NET语言获得。确定。谢谢-我不知道C#也有这个缺陷。删除第一个反对意见,删除第二个反对意见中的VB/VB.NET
引用中的
。其余的仍然有效不过,我会取消否决票,因为基于这一修正,这可能是仓促的。但是,由于另外两个原因,我无法对其进行投票。您是对的,它肯定存在重新进入的风险,并且没有意识到DataGridView上有DrawToBitmap可用。您也可以尝试Control.Refresh()。。。dataGridView1.Refresh(),强制立即重新绘制控件及其所有子项。我不确定这是否是线程安全的。您也可以尝试Control.Refresh()。。。dataGridView1.Refresh(),强制立即重新绘制控件及其所有子项。我不确定这是否是线程安全的。@Hans回答您的评论,我会接受的。Update()工作得很好。@Hans请回答您的评论,我会接受的。Update()工作得很好。
var width = dataGridView1.Width;
var height = dataGridView1.Height;
var x = dataGridView1.Left;
var y = dataGridView1.Top;

var bitmap = new Bitmap(width, height);
var targetBounds = new Rectangle(x, y, width, height);
dataGridView1.DrawToBitmap(bitmap, targetBounds);

bitmap.Save("C:\\DataGridView.bmp");