【问题标题】:printing png file with file system watcher vb.net使用文件系统观察程序 vb.net 打印 png 文件
【发布时间】:2021-01-19 12:04:08
【问题描述】:

我正在尝试打印一个新创建的 png 文件。 我正在使用文件系统观察器在创建文件并获取它的路径时做出反应。

    Private Sub FileSystemWatcher1_Created(sender As Object, e As FileSystemEventArgs) Handles FileSystemWatcher1.Created
    Dim MyFile As String = e.FullPath.ToString
    Try
        AddHandler PrintDocument1.PrintPage, AddressOf Me.PrintImage
        PrintDocument1.Print()
    Catch ex As Exception
        MsgBox(ex, MsgBoxStyle.Critical, "Error during Print")
    End Try
    End Sub

但是当我想打印它时,我不知道从 MSDN 到代码的路径如何直接与此代码 Me.PrintImage 和 Me.PrintImage(MyFile) 返回错误

WithEvents PrintDocument1 As New PrintDocument
Private Sub PrintImage(ByVal sender As Object, ByVal ppea As PrintPageEventArgs, MyFile As String)
    ppea.Graphics.DrawImage(Image.FromFile(MyFile), ppea.Graphics.VisibleClipBounds)
    ppea.HasMorePages = False
End Sub

我怎样才能将我的文件定向到此打印服务?我发现的代码基于文件的静态路径,不在文件系统观察程序中,我似乎找不到将它们联系在一起的方法。 请帮忙!

【问题讨论】:

  • 您需要将文件路径分配给一个事件处理程序中的成员变量,然后从另一个事件处理程序的同一字段中取回它。您不能更改处理事件的方法的签名。
  • 不要更改PrintPage事件的签名,去掉, MyFile As String参数。将MyFile 声明为类字段。在FileSystemWatcher.Created 事件中,只需分配e.FullPathMyFile = e.FullPath,不要调用.ToString 方法,因为它是一个字符串。将此AddHandler PrintDocument1.PrintPage, AddressOf Me.PrintImage 移至构造函数或Form.Load 事件。
  • @dr.null 'Declare MyFile as a class field' 是什么意思?抱歉,由于某种原因,我无法理解把手等。 Form.Load 事件是指在 Form 启动时加载的 sub,对吗?
  • 类字段或成员。 Private MyFile As String 类中的任何位置,但不在任何方法块内。这样,该变量在该类中的任何位置都是可见和可访问的。至于事件,您应该只订阅一次事件,而不是每次触发Create 事件。所以,在Load 事件中订阅PrintPage 事件。双击表单以创建 Load 事件(如果尚未存在)。
  • 谢谢@dr.null,Image.FromFile(MyFile) 怎么知道需要打印哪个文件?如果我声明 Private MyFile as String 我还需要在 FileSystemWatcher 中声明它还是将其设置为 MyFile = e.FullPath

标签: vb.net printing png filesystemwatcher


【解决方案1】:

请考虑以下几点:

  • 您不能更改委托/事件的签名,例如:
Private Sub PrintImage(ByVal sender As Object, ByVal ppea As PrintPageEventArgs, MyFile As String)
  • 您始终可以声明类成员以在类中的任何位置访问它们。您可以像这样声明MyFile
Public Class Form1
    Private MyFile As String
End Class

现在您可以在FileSystemWatcher1_Created 事件中分配它的值,并在PrintImage 事件中读取该值。阅读更多:How to: Control the Scope of a Variable (Visual Basic)

  • 您应该只订阅一次事件:
Public Class Form1

    Private MyFile As String
    Private PrintDocument1 As PrintDocument

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        PrintDocument1 = New PrintDocument
        AddHandler PrintDocument1.PrintPage, AddressOf PrintImage
    End Sub

    Private Sub PrintImage(sender As Object, e As PrintPageEventArgs)
        '...
    End Sub
End Class

或者像在FileSystemWatcher1_Created 事件中一样使用WithEvents and Handles 子句。

Public Class Form1

    Private MyFile As String
    Private WithEvents PrintDocument1 As PrintDocument

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        PrintDocument1 = New PrintDocument
    End Sub

   Private Sub PrintImage(sender As Object, e As PrintPageEventArgs) Handles PrintDocument1.PrintPage
         '...
    End Sub
End Class

或者使用设计器添加PrintDocument 组件的实例并订阅它的事件。就像FileSystemWatcher 组件一样。

把它们放在一起,你应该会得到类似的东西:

Public Class Form1

    Private MyFile As String
    Private WithEvents PrintDocument1 As PrintDocument

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        PrintDocument1 = New PrintDocument
    End Sub

    Private Sub FileSystemWatcher1_Created(sender As Object, e As FileSystemEventArgs) Handles FileSystemWatcher1.Created
        MyFile = e.FullPath
        PrintDocument1.Print()
    End Sub

    Private Sub PrintImage(sender As Object, e As PrintPageEventArgs) Handles PrintDocument1.PrintPage
        If Not File.Exists(MyFile) Then
            Return
        End If

        Try
            Using bmp = New Bitmap(New MemoryStream(File.ReadAllBytes(MyFile)))
                e.Graphics.DrawImage(bmp, e.Graphics.VisibleClipBounds)
            End Using
        Catch ex As ArgumentException
            Console.WriteLine("Not Image!")
        Catch ex As Exception
            Console.WriteLine(ex.Message)
        End Try
    End Sub

    Protected Overrides Sub OnFormClosed(e As FormClosedEventArgs)
        MyBase.OnFormClosed(e)

        PrintDocument1.Dispose()
    End Sub
End Class

恕我直言,更好的方法是将创建的文件收集在一个列表中,并将它们作为一个打印作业发送到打印机。当您在FileSystemWatcher.Path 中粘贴多个文件时很有用。为每个文件引发FileSystemWatcher.Created 事件,并且为每个文件调用前面代码中的PrintDocument.Print 方法。我们可以将打印调用减少到一个来完成相同的任务。

下面的代码是一个快速的 Lambda-Expression-Way 示例。

Imports System.IO
Imports System.Windows.Forms
Imports System.Drawing.Printing
Imports System.Collections.Generic

Public Class Form1

    Private ReadOnly watcher As FileSystemWatcher
    Private ReadOnly timer As Timer 'System.Windows.Forms.Timer
    Private ReadOnly printDoc As PrintDocument
    Private MyFiles As Queue(Of String)

    Sub New()
        InitializeComponent()

        MyFiles = New Queue(Of String)

        watcher = New FileSystemWatcher With {
            .Path = "PathToWatch",
            .EnableRaisingEvents = True
        }
        AddHandler watcher.Created,
            Sub(s, e)
                If Not MyFiles.Contains(e.FullPath) Then
                    MyFiles.Enqueue(e.FullPath)
                    Invoke(Sub() timer.Start())
                End If
            End Sub

        timer = New Timer With {.Interval = 1000}
        AddHandler timer.Tick,
            Sub(s, e)
                timer.Stop()
                printDoc.Print()
            End Sub

        printDoc = New PrintDocument
        AddHandler printDoc.PrintPage,
            Sub(s, e)
                Dim imgFile = MyFiles.Dequeue
                If Not File.Exists(imgFile) Then
                    Return
                End If

                Try
                    Using bmp = New Bitmap(New MemoryStream(File.ReadAllBytes(imgFile)))
                        e.Graphics.DrawImage(bmp, e.Graphics.VisibleClipBounds)
                    End Using
                Catch ex As ArgumentException
                    Console.WriteLine("Not Image!")
                Catch ex As Exception
                    Console.WriteLine(ex.Message)
                End Try

                e.HasMorePages = MyFiles.Count > 0
            End Sub
    End Sub

    Protected Overrides Sub OnFormClosed(e As FormClosedEventArgs)
        MyBase.OnFormClosed(e)

        watcher.Dispose()
        timer.Dispose()
        printDoc.Dispose()
    End Sub
End Class

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-13
    • 1970-01-01
    相关资源
    最近更新 更多