I'm trying to print a newly created png file. I'm using File system watcher to react when file is being created and getting path of it.
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
but when I want to print it I don't know how direct that path to the code from MSDN as with this code Me.PrintImage and Me.PrintImage(MyFile) returns an error
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
How can i just direct my file to this printing service? code i found was based on static path to the file and was not in the file system watcher and i can't seem to find a way to tie them together. Please help!
Please consider the following:
Private Sub PrintImage(ByVal sender As Object, ByVal ppea As PrintPageEventArgs, MyFile As String)
MyFile
like so:Public Class Form1
Private MyFile As String
End Class
Now you can assign its value in the FileSystemWatcher1_Created
event and read that value in the PrintImage
event. To read more: 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
Or just use the WithEvents and Handles clause the same way you have in the FileSystemWatcher1_Created
event.
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
Or use the designer to add an instance of the PrintDocument
component and subscribe to its events. just like the FileSystemWatcher
component.
Put it all together and you should get something like:
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
A better approach IMHO is to collect the created files in a list and send them to the printer as one print-job. Useful when - for example - you paste multiple files into the FileSystemWatcher.Path
. The FileSystemWatcher.Created
event is raised for each file and the PrintDocument.Print
method in the preceding code is called for each one as well. We can reduce the print calls to just one to do the same task.
The code below is a quick Lambda-Expression-Way example.
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,
.SynchronizingObject = Me
}
AddHandler watcher.Created,
Sub(s, e)
If Not MyFiles.Contains(e.FullPath) Then
MyFiles.Enqueue(e.FullPath)
timer.Start()
End If
End Sub
timer = New Timer With {.Interval = 200}
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