Download EnhancedBrowserControl.zip - 26.34 KB
Introduction
I've read and heard comments lamenting the fact that the MS .net Web Browser
control (System.Windows.Forms.WebBrowser) doesn't behave like Internet Explorer,
or lacks some of the feature support that IE has. Chief among these complaints
is the one that it doesn't support the displaying of XML the way IE does, all
pretty and ready for printing. You could take the view, as do I, that this is
the way it should be. The Web Browser control is a basic (although powerful)
managed wrapper for the Web Browser ActiveX control (in Shdocvw.dll). IE uses
Shdocvw.dll too, but when you use a .net Web Browser control in your
application, you're not using a component of IE, you're using a component that
IE uses. IE extends it's functionality, and if the need arises... so must you.
So Very Useful
Since the basic WB control can be so useful in many different applications
that you develop, I recommend you consider creating a wrapper of your own which
you reuse in each project where you need a WB control. As you progress from
project to project, you'll add more features as needed by each project. Each
time you do this, you potentially save yourself a lot of time with each new
project you use it in. You can either put it into its own class library project,
as I have in this article. Alternatively you could maintain one code file which
you keep importing into other projects. The latter approach requires you to be
using a version control or file repository system (such as SourceSafe) so that
you can have the same physical file in many projects. Besides that, you may have
other class files that you want to add later. So I would suggest building your
own library to contain it.
No Need - There's One Right Here
So that's the approach I've taken with the project files associated with this
article. I've created a Class Library that contains one class which, using my
extensive imagination and creative flare I have named... 'WebBrowser'. This is
of course a wrapper for... you guessed... the WebBrowser. For those new to the
subject of inheritance, the distinction between the two rests in the fact that
EnhancedControls.WebBrowser (my namespace) inherits from, and extends System.Windows.Forms.WebBrowser (an MS namespace). So the issue my WB control
will tackle is the one I mentioned at the start - support for displaying XML.
But you can add other features to it that are appropriate for your needs too.
Transforming XML
Some people are prone to turning this subject into rocket science. My view is
that if a transformation works with the XML files you're working with... it
works. Compile the code, make the coffee, and move on. You can always add
support for other transformations later on when you encounter some XML with
which it doesn't work, if that ever happens. So when I went out looking for a
good transformation I found one provided by
Steve Muench.
I embedded that xslt file into the resources of my library project because I
don't want my library to have any dependencies on files external to itself.
Once you have an appropriate transformation at hand, actually making the
transform happen is very easy. Here is the code for that:
Public Sub DisplayPrettyXML(ByVal oReader As XmlReader)
Try If IsNothing(moXsltTransformation) Then
moXsltTransformation = New XslCompiledTransform(False)
Using oTextReader As TextReader = New StringReader(My.Resources.PrettyPrint)
Using oXsltReader As XmlReader = XmlReader.Create(oTextReader)
moXsltTransformation.Load(oXsltReader)
End Using
End Using
End If
If IsNothing(moStringBuilder) Then
moStringBuilder = New StringBuilder
Else moStringBuilder.Remove(0, moStringBuilder.Length)
End If
Using oXmlWriter As XmlWriter = XmlWriter.Create(moStringBuilder)
moXsltTransformation.Transform(oReader, Nothing, oXmlWriter)
End Using
Me.DocumentText = moStringBuilder.ToString
Catch ex As Exception
Me.DocumentText = ERR_HTML
End Try
End Sub
One of my big problems is that I don't always practice what I preach. Only
two paragraphs and one sub-routine ago did I say (in not so many words), don't
bother to cross bridges you haven't come to yet. Some bridges I immediately
spotted in the foggy distance convinced me that I may not always have an
XmlReader object to pass to the DisplayPrettyXML() routine. Sometimes I'll have
a file, other times perhaps and XMLDocument object. So I immediately crossed all
the bridges not yet reached, and wrote four overloads for DisplayPrettyXML().
I'll list just one of them here:
Public Sub DisplayPrettyXML(ByVal strFilePath As String)
Try DisplayPrettyXML(XmlReader.Create(File.OpenRead(strFilePath)))
Catch ex As Exception
Throw
End Try
End Sub
The other overloads accept: A Stream, an XMLDocument instance, and an
XMLDataDocument instance, and they're all pretty small like the one above.

Using the code
To test my new WB component I created a Windows Forms Application, with one form,
dropped my WB control onto that form and added five buttons. Each button causes
the WB control to do the same thing, but with five different (although they
share the same structure) XML files.
Private Sub cmdFile_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles cmdFile.Click
WebBrowser.DisplayPrettyXML("XMLFiles\MusicLibrarySting.xml")
End Sub
Private Sub cmdStream_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles cmdStream.Click
Using oStream As FileStream = File.OpenRead( _
"XMLFiles\MusicLibraryMadonna.xml")
WebBrowser.DisplayPrettyXML(oStream)
End Using
End Sub
Private Sub cmdXMLReader_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles cmdXMLReader.Click
Using oXmlReader As XmlReader = XmlReader.Create( _
"XMLFiles\MusicLibraryREM.xml")
WebBrowser.DisplayPrettyXML(oXmlReader)
End Using
End Sub
Private Sub cmdXMLDoc_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles cmdXMLDoc.Click
Dim oXmlDocument As XmlDocument = New XmlDocument()
oXmlDocument.Load("XMLFiles\MusicLibrarySeanPaul.xml")
WebBrowser.DisplayPrettyXML(oXmlDocument)
End Sub
Private Sub cmdXMLDataDoc_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles cmdXMLDataDoc.Click
Dim oXmlDataDocument As XmlDataDocument = New XmlDataDocument()
oXmlDataDocument.Load("XMLFiles\MusicLibraryBeatles.xml")
WebBrowser.DisplayPrettyXML(oXmlDataDocument)
End Sub
Points of Interest
- The System.Windows.Forms.WebBrowser control is a good example of a
situation where you know of a component that comes close to what you need, but
just stops a little short. This can apply to any control and many other .net
classes too.
- If you can set aside some time within your project, it's always a good
idea to consider spending it on making library-based functionality that you
know you're going to use again. The .net framework lends itself, and supports
you in this approach because there are so many aspects of it that you can
customise and build upon.
History
None.