Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.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
Vb.net 我的代码仅在插入随机MsgBox时有效_Vb.net_Screenshot_Tablelayoutpanel - Fatal编程技术网

Vb.net 我的代码仅在插入随机MsgBox时有效

Vb.net 我的代码仅在插入随机MsgBox时有效,vb.net,screenshot,tablelayoutpanel,Vb.net,Screenshot,Tablelayoutpanel,我在尝试获取表格中TableLayoutPanel的屏幕截图时遇到了一个非常奇怪的问题 我有这个代码(取自另一个问题();代码由用户“Chase Rocker”提供): 现在,我的问题来了。这个代码给了我一张空白图片。这显然是截图,但我只能看到白色。现在,我想看看大小是否正确,所以我搞乱了MsgBox。我将这一行添加到代码中: MsgBox("Random Message") 得到 Dim s As Size = TableLayoutPanel1.Size MsgBo

我在尝试获取表格中TableLayoutPanel的屏幕截图时遇到了一个非常奇怪的问题

我有这个代码(取自另一个问题();代码由用户“Chase Rocker”提供):

现在,我的问题来了。这个代码给了我一张空白图片。这显然是截图,但我只能看到白色。现在,我想看看大小是否正确,所以我搞乱了MsgBox。我将这一行添加到代码中:

    MsgBox("Random Message")
得到

    Dim s As Size = TableLayoutPanel1.Size
    MsgBox("Random Message")
    Dim memoryImage = New Bitmap(s.Width, s.Height)
    Dim memoryGraphics As Graphics = Graphics.FromImage(memoryImage)
    Dim ScreenPos As Point = Me.TableLayoutPanel1.PointToScreen(New Point(0, 0))
    memoryGraphics.CopyFromScreen(ScreenPos.X, ScreenPos.Y, 0, 0, s)
    Form3.PictureBox1.SizeMode = PictureBoxSizeMode.AutoSize
    Form3.PictureBox1.BringToFront()
    Form3.PictureBox1.Image = memoryImage

由于某种原因,我不知道,截图现在起作用了。我再也看不到白色了,但是TableLayoutPanel的实际屏幕截图。对我来说,这段代码只适用于MsgBox是非常奇怪的。也许我错过了什么。有人知道为什么会这样吗?谢谢大家!

如果您尝试将
表格布局面板
自身绘制为位图,会怎么样?这可以使用以下方法完成


如果您尝试将
表格布局面板
自身绘制为位图,效果如何?这可以使用以下方法完成


如果TableLayoutPanel填充发生在抓取图像的同一事件处理程序中,则Windows尚未为添加到TableLayoutPanel的元素绘制UI。只有当您退出事件处理程序时,winforms引擎才有机会绘制所有内容

添加MessageBox会改变一切,因为调用Show(一个中断代码并将控制权传递回窗口的模式调用)允许Winform引擎绘制挂起的更新,并且代码可以正常工作

您可以添加一个计时器控件,并将执行屏幕截图的代码放入计时器事件中

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 
   ......
   ' code that fills the TableLayoutPanel
   ......

   Dim tim1 = new System.Windows.Forms.Timer()
   tim1.Interval = 1
   AddHandler tim1.Tick, AddressOf tim1Ticked
   tim1.Start()
End Sub
Private Sub tim1Ticked(sender As Object, e As EventArgs)

    ......
    ' Code that execute the screenshoot.
    ......

    Dim t = DirectCast(sender, System.Windows.Forms.Timer)
    t.Stop()
End Sub

如果TableLayoutPanel填充发生在抓取图像的同一事件处理程序中,则Windows尚未为添加到TableLayoutPanel的元素绘制UI。只有当您退出事件处理程序时,winforms引擎才有机会绘制所有内容

添加MessageBox会改变一切,因为调用Show(一个中断代码并将控制权传递回窗口的模式调用)允许Winform引擎绘制挂起的更新,并且代码可以正常工作

您可以添加一个计时器控件,并将执行屏幕截图的代码放入计时器事件中

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 
   ......
   ' code that fills the TableLayoutPanel
   ......

   Dim tim1 = new System.Windows.Forms.Timer()
   tim1.Interval = 1
   AddHandler tim1.Tick, AddressOf tim1Ticked
   tim1.Start()
End Sub
Private Sub tim1Ticked(sender As Object, e As EventArgs)

    ......
    ' Code that execute the screenshoot.
    ......

    Dim t = DirectCast(sender, System.Windows.Forms.Timer)
    t.Stop()
End Sub


在哪种情况下运行此代码?我希望不是在构造函数或表单加载中。私有子按钮1\u单击(发送者作为对象,e作为事件参数)处理按钮1。单击一个简单的单击按钮事件。同一事件还使用所有信息填充TableLayOutPanel。如果填充发生在抓取图像的同一点上,则在退出事件处理程序之前,TableLayOutPanel中没有任何内容。换句话说,winforms引擎在退出事件句柄之前无法绘制任何内容。它发生在同一事件中,是的。这是否解释了为什么MsgBox会让屏幕截图正常工作?MsgBox弹出是否意味着程序使用所有数据完成TableLayOutPanel的创建,然后获取屏幕截图?您可以进行BeginInvoke调用获取屏幕截图的代码,以便稍后在操作序列中调用它。它应该产生与messagebox(不带messagebox)相同的效果,在哪种情况下运行此代码?我希望不是在构造函数或表单加载中。私有子按钮1\u单击(发送者作为对象,e作为事件参数)处理按钮1。单击一个简单的单击按钮事件。同一事件还使用所有信息填充TableLayOutPanel。如果填充发生在抓取图像的同一点上,则在退出事件处理程序之前,TableLayOutPanel中没有任何内容。换句话说,winforms引擎在退出事件句柄之前无法绘制任何内容。它发生在同一事件中,是的。这是否解释了为什么MsgBox会让屏幕截图正常工作?MsgBox弹出是否意味着程序使用所有数据完成TableLayOutPanel的创建,然后获取屏幕截图?您可以进行BeginInvoke调用获取屏幕截图的代码,以便稍后在操作序列中调用它。它应该产生与您的messagebox(没有messagebox)相同的效果。您的代码在没有MsgBox的情况下工作。非常感谢。尽管如此,我仍然对我上一段代码中的MsgBox感到疑惑。我会尝试其他建议,看看结果如何。很好-TLP不再需要绘制,因此也不需要刷新…也不再泄漏。泄漏是什么意思?@CarlosArmendia:您的代码有一个小内存泄漏,因为您从未处理
图形
对象。使用/
将其包装在一个
块中,然后使用
块结束。啊,我明白了。好的,非常感谢你的帮助!您的代码在没有MsgBox的情况下工作。非常感谢。尽管如此,我仍然对我上一段代码中的MsgBox感到疑惑。我会尝试其他建议,看看结果如何。很好-TLP不再需要绘制,因此也不需要刷新…也不再泄漏。泄漏是什么意思?@CarlosArmendia:您的代码有一个小内存泄漏,因为您从未处理
图形
对象。使用
/
将其包装在一个
块中,然后使用
块结束。啊,我明白了。好的,非常感谢你的帮助!然后我很好奇为什么
TabelLayoutPanel1.DrawToBitmap()
似乎对OP有效。现在我也很好奇!谢谢你史蒂夫的解释,这就是我要找的。你介意回答Visual Vincent和我的新问题吗?看一下,似乎有一个WM_PAINT消息被发送到底层控件,强制立即重新绘制控件,以便下面的API BitBlt函数具有填充位图所需的内容。我不是这个领域(图形)的专家,所以可能还有其他需要考虑的问题,无论如何,DrawToBitmap似乎比我的答案和用户ChaseRockerI要求的所有代码都要好,我希望我能标记两个答案,因为你们两个都以不同的方式帮助了我。试着看看r
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 
   ......
   ' code that fills the TableLayoutPanel
   ......

   Dim tim1 = new System.Windows.Forms.Timer()
   tim1.Interval = 1
   AddHandler tim1.Tick, AddressOf tim1Ticked
   tim1.Start()
End Sub
Private Sub tim1Ticked(sender As Object, e As EventArgs)

    ......
    ' Code that execute the screenshoot.
    ......

    Dim t = DirectCast(sender, System.Windows.Forms.Timer)
    t.Stop()
End Sub