首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >VB.net PrintForm在新线程中不工作

VB.net PrintForm在新线程中不工作
EN

Stack Overflow用户
提问于 2017-08-20 06:07:15
回答 3查看 857关注 0票数 0

我正在开发一个电子归档应用程序,我需要打印一个胶粘剂标签与一些信息附加到物理文件夹。

我已经设计了一个形式的标签,把标志和所有我需要的东西放在那里。然后,在Form.Shown事件中,我将命令放入打印:

Me.PrintLabelForm.Print() (这是VisualStudio PowerPack控件)

这就是我遇到问题的地方。打印输出完全是空的(我已经更改了页边距设置打印机等)。问题是表单实际上没有完全加载,我将方法切换到打印预览,控件在那里,但它们是空的。

我尝试了几种方法,但我无法自动完成此操作。我发现的一种解决方案是使用一个按钮来执行Me.PrintLabelForm.Print(),然后它就可以工作了,因为表单已经完全加载并显示了,但这不是一个选项。我需要的表单自动打开,打印和关闭。

我认为它应该可以工作的一个选项是创建一个带有计时器的新线程,然后打印,所以我这样做了:

代码语言:javascript
复制
Private Sub LabelPrint_Load(sender As Object, e As EventArgs) Handles MyBase.Load

End Sub

Private Sub LabelPrint_Shown(sender As Object, e As EventArgs) Handles Me.Shown
    PrintLabelForm.PrinterSettings.DefaultPageSettings.Margins.Left = 0.1
    PrintLabelForm.PrinterSettings.DefaultPageSettings.Margins.Right = 0.1
    PrintLabelForm.PrinterSettings.DefaultPageSettings.Margins.Top = 0.1
    PrintLabelForm.PrinterSettings.DefaultPageSettings.Margins.Bottom = 0.1
    PrintLabelForm.PrinterSettings.DefaultPageSettings.Landscape = True

    Dim PrintThread As New System.Threading.Thread(AddressOf PrintSub)
    PrintThread.Start()
End Sub

Private Sub PrintSub()
    Threading.Thread.Sleep(1000)
    Me.PrintLabelForm.Print()
    Me.Close()
End Sub

我们的想法是让PrintSub让应用程序有足够的时间完成渲染,然后打印出来,但我得到了这个错误:

** Microsoft.VisualBasic.PowerPacks.dll中发生'System.Exception‘类型的未处理异常

附加信息:打印的窗口必须可见并包含焦点。**

所以我想知道如何让这个线程拥有窗口窗体的焦点,以便能够打印。

这就是全部。谢谢你的帮助。

EN

回答 3

Stack Overflow用户

发布于 2017-08-20 06:43:24

始终只在主线程中使用窗体。

您发现它是正确的-表单打印将不会从新线程运行。

在窗体上执行任何操作时,必须从Dispatcher线程执行所有工作。它是运行所有事件方法的线程。如果你这样做失败了,你会遇到很多副作用。(不仅仅是打印的问题。我一直在那里,这个来自Windows高级程序员的建议帮助我让事情恢复正常。)因此不会从任何其他线程使用表单打印。

如果你想解决这个问题,可以将表单打印到图像(在主线程中),然后可以使用新线程打印图像。

这与.NET无关,这与Windows Forms技术的内部结构有关。欢迎使用Windows编程。

票数 0
EN

Stack Overflow用户

发布于 2017-08-20 09:52:59

我设法解决了这个问题,把这一行放在Form.Shown中

代码语言:javascript
复制
PrintLabelForm.Print(Me, PrintForm.PrintOption.ClientAreaOnly)

我不知道为什么,也不知道它是如何工作的。

感谢你们所有人的帮助。让我们希望,当表单完全显示时,我不会发现自己在尝试做一些事情。

这是我的完整代码,让我们希望它适用于其他人:

代码语言:javascript
复制
Imports Microsoft.VisualBasic.PowerPacks.Printing

Public Class PrintAdhesiveLabel

    Private Sub LabelPrint_Load(sender As Object, e As EventArgs) Handles MyBase.Load

    End Sub

    Private Sub LabelPrint_Shown(sender As Object, e As EventArgs) Handles Me.Shown
        PrintLabelForm.PrinterSettings.DefaultPageSettings.Margins.Left = 0.1
        PrintLabelForm.PrinterSettings.DefaultPageSettings.Margins.Right = 0.1
        PrintLabelForm.PrinterSettings.DefaultPageSettings.Margins.Top = 0.1
        PrintLabelForm.PrinterSettings.DefaultPageSettings.Margins.Bottom = 0.1
        PrintLabelForm.PrinterSettings.DefaultPageSettings.Landscape = True
        PrintLabelForm.Print(Me, PrintForm.PrintOption.ClientAreaOnly)
        Me.Close()
    End Sub

End Class
票数 0
EN

Stack Overflow用户

发布于 2017-08-20 06:17:00

也许this是相关的:

使用此方法只能打印当前具有焦点的表单。如果在调用此方法之前已将Form属性设置为另一个窗体,则该窗体的图像可能无法按预期呈现。若要避免这种情况,请在调用Print之前调用窗体的Focus方法。

因此在调用Me.PrintLabelForm.Print()之前先调用Me.PrintLabelForm.Focus()

代码语言:javascript
复制
Private Sub PrintSub()
    Threading.Thread.Sleep(1000)
    Me.PrintLabelForm.Focus()
    Me.PrintLabelForm.Print()
    Me.Close()
End Sub
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45776688

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档