尝试在表单中获取TableLayoutPanel的屏幕截图时遇到了一个非常奇怪的问题。
我有这个代码(取自另一个问题(How to get a screenshot, only for a picturebox);代码由用户提供“Chase Rocker”):
Dim s As Size = TableLayoutPanel1.Size
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
现在,我的问题来了。这段代码给了我一张空白的图片。它显然是截图,但我能看到的只是白色。现在,我试图看看大小是否正确,所以我在搞乱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。也许我错过了什么。有谁知道为什么会这样?谢谢!
答案 0 :(得分:4)
如果您试图让TableLayoutPanel
将自己绘制为位图,那该怎么办?这可以使用Control.DrawToBitmap()
方法完成。
Dim s As Size = TableLayoutPanel1.Size
Dim memoryImage As New Bitmap(s.Width, s.Height)
TableLayoutPanel1.DrawToBitmap(memoryImage, New Rectangle(New Point(0, 0), s))
Form3.PictureBox1.Image = memoryImage
答案 1 :(得分:2)
如果TableLayoutPanel填充发生在您抓取图像的同一事件处理程序中,则Windows不会为添加到TableLayoutPanel的元素绘制UI。只有当您退出事件处理程序时,winforms引擎才有机会绘制所有内容。
添加MessageBox会更改所有内容,因为调用Show(中断代码并将控制权传递回窗口的模式调用)允许Winform引擎绘制待处理的更新并且代码可以正常工作。
您可以添加Timer控件并将执行ScreenShoot的代码放入Timer事件中。
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