MDI PDF File Viewer with Tabbed Header
June 23rd, 2007
This code example attempts to answer two common questions. First, how can I load PDF files into my VB.NET application for viewing? And, second, how can I create a MDI application that has tabbed browsing like Visual Studio, MSDN, and IE7? While there are more complex, and perhaps more elegant, ways to accomplish these tasks, this example offers a simple, easy-to-use way to implement these features. Plus it shows how to deal with some quirks you might encounter.
First, let’s look at what we need to do to load PDF files. In our case, we’re going to assume that potential users have Internet Explorer and Adobe Acrobat Reader already installed on their systems and configured correctly. If you can’t safely make this assumption, then you’ll need to look into more complex methods to accomplish this task. But, in most organizations, this code should work fine.
Having these ready made components reduces our work to a few simple commands. First, we need to place the Web Browser component on a form. In the case of this example, this will be a MDI child form. We will dock it so that it fills the entire form. Next, what do we need to do to load the PDF? That’s simple too. All we need to do is use the Navigate method to load the PDF into the browser, like so:
wbDocument.Navigate(filename)
So, we can achieve this seemingly daunting task with a control and one command, pretty easy. However, unloading is where we have to use a little trick to avoid a potential problem.
The problem that can be encountered is that Acrobat, under some circumstances, will hang onto a reference to a PDF file, thus keeping it locked. This may not be a big deal in some cases since the lock will be released eventually or at least when the application ends. But in other cases, the locked file may prevent actions your program or users need to take. To insure that Acrobat releases the file, we have to clear it out of our web browser completely. We can use the following code to do this:
wbDocument.Hide()
wbDocument.Navigate("about:blank")
Do Until wbDocument.ReadyState = WebBrowserReadyState.Complete
Application.DoEvents()
System.Threading.Thread.Sleep(100)
Loop
wbDocument.Dispose()
System.Threading.Thread.Sleep(100)
Here we hide the browser control, navigate to the default blank page, wait for the browser to completely load this page, then dispose of the browser control and wait a brief moment before continuing. You may not need all this waiting/sleeping but I’ve found that having these short waits helped insure that the PDF file is completely freed. Try it with and without this code and see how it performs for you.
Now, let’s create a tabbed browser for our MDI app. This too is rather easy to do as well. First, we add a tab control to our MDI parent form and dock it to the top and size it appropriately. We don’t need to add any tabs to it at this point. Next, in our MDI parent’s code, we want to include loading to the tab with the loading of a child form, like so:
Private Sub LoadNewViewer(ByVal fileName As String)
If My.Computer.FileSystem.GetFileInfo(fileName).Extension.ToUpper = ".PDF" Then
For Each frm As Form In Me.MdiChildren
If frm.Text = fileName Then
frm.BringToFront()
tabWindows.SelectedTab = tabWindows.TabPages(fileName)
Exit Sub
End If
Next
Dim ChildForm As New frmViewer
ChildForm.MdiParent = Me
ChildForm.Text = fileName
ChildForm.wbDocument.Navigate(fileName)
tabWindows.TabPages.Insert(0, fileName, fileName)
tabWindows.SelectTab(0)
For Each frm As Form In Me.MdiChildren
frm.WindowState = FormWindowState.Normal
Next
ChildForm.Show()
ChildForm.WindowState = FormWindowState.Maximized
End If
End Sub
That may seem like a lot of code but it performs a number of functions that improve how the app performs and looks.
After making sure the file type is what we want to load, we first check to see if the document is already loaded into our application. If it is, we bring it to the front and select the corresponding tab. In our case, we’re making it simple by using the filename as the key and display text for the child form and the tab but you could add a more complex method if you needed to do so. If the form is already loaded, we’re done, but if it isn’t we need to create a new child form in the next steps of the application. Finally we load in the PDF document and show it and we’re done, or are we?
If you don’t mind showing the default MDI child icon, then yes, you’re done. But, if you want to show your own icon, there is a little trickery involved here. To get your icon to show you have to normalize each of the child forms before showing your new form. This does cause a bit of flicker so you have to decide if you want icons or a little flicker in your app. In addition to this step, you will also need to load the icons in the New method of the MDI parent and child forms. This is a little quirk in the MDI interface and this is the easiest way to work around it.
ยป Click here to download VB.NET source code for this article.
Entry Filed under: Code Examples
Rate This Article:










3 Comments Add your own
1. Geoff Dodd - pdf | January 11th, 2008 at 7:26 am
Thanks. A very elegant solution. I have a small app for creating even highly secure pdf files. Clean user interface. Geoff.
2. Rob Furley | June 3rd, 2008 at 7:44 pm
Brilliant! I have spent days searching for a free PDF viewer.
3. Andrei | September 11th, 2008 at 9:46 am
Releasing a pdf file is BRILLIANT! I had this particular problem.
Leave a Comment
Some HTML allowed:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>
Trackback this post | Subscribe to the comments via RSS Feed