Ordermate was created to simplify the process of building an invoice of materials
based on Movie 'product' requests.
The actors of this scenario are: Distribution Company Employee (i.e. User),
Theater Company Contact (i.e. Customer).
Ordermate covers the following workflow for movie order processing.
- Movie Theater 'Customer' requests to place an order for one or more movies.
- Distributor company Employee selects Customer from ComboBox dropdown menu.
- Requested products are selected from a CheckedListBox.
- Employee enters the Quantity of items ordered.
- Employee clicks the [Add] button to update form.
- Employee has option to View the invoice on screen and/or
Export the invoice to Microsoft Excel.
Ordermate is a demonstration of using xml as a flat file type data store.
XML can be converted, formatted, and imported to any type database you choose
(i.e. MS Access, SQL Server, Oracle, MYSQL, etc.)
The purpose of this article is to give you a sense of "what it is like" to build a .NET
application using XML Serialization. It demonstrates a variety of programing topics
for the entry to mid-level VB.NET programmer.
- XmlSerializer: Serializes and deserializes objects into and from XML documents.
- PrintDocument: Create custom invoice forms for Print and Print preview.
- DocumentFormat.OpenXml: Open XML Format to create/output Excel
SpreadsheetLight is an open
source Open XML spreadsheet library for .NET Framework.
binding is the process that establishes a connection between the application UI
and business objects.
- StringRandomGenerator: Helps to generate random invoice numbers.
Ordermate generally involves the following: Process movie inventory,
create invoices, create, edit, and update product supplies. It can be used
to Read/Write XML files. XML input/output and to export to a Microsoft Excel
worksheet. Invoices maybe viewed for Print and Print preview.
Read Write XML.
Ordermate is actually and update to a program that I created about 10 yrs ago.
It was recently revisited due to a client's need to reformat some Nessus Scanner
By Tenable report files.
The files themselves are just plain vanilla xml datasets that needed to be
extracted, formatted, and then dropped into a Microsoft Excel spreadsheet.
The following steps were taken to generate class files based on existing xml file(s):
- Create xml file(s) using standard text editor.
- Use xsd.exe to generate schema file(s) (*.xsd).
- - start Visual Studio Tools 'Developer Command Prompt'
- - Format / correct type schema properties
- Use xsd.exe to generate class file(s) from Step 2
- - xsd products.xsd /classes /language:VB
- - xsd customers.xsd /classes /language:VB
- Clean up the generated class file(s) (*.vb)
- Create Visual Studio Solution, include (*.vb) file(s)
DataCollection class represents the primary -top level element
of the Xml file. Only one top level element is allowed in an XML document.
It holds a reference to all Customer and Product objects found within a deserialized
xml file. Once all Products and Customers are loaded it triggers a
PropertyChangedEvent which a listener (i.e. Form control) can
Public Class DataCollection
Private _Products As List(Of Product)
Private _Customers As List(Of Customer)
Public Property Products() As List(Of Product)
Set(ByVal value As List(Of Product))
_Products = value
Public Property Customers() As List(Of Customer)
Set(ByVal value As List(Of Customer))
_Customers = value
Public Event PropertyChanged As _
Protected Sub RaisePropertyChanged(ByVal propertyName As String)
Dim propertyChanged As _
If (propertyChanged IsNot Nothing) Then
In order to deserialize data from an xml file into class objects.
We need to utilize the
This procedure is taken care of in the
method of the
FrmMain class. As Deserialization
occurs connect an EventHandler to receive and handle events.
Private Sub Initialize()
_Data = New DataCollection
AddHandler _Data.PropertyChanged, AddressOf OnDataChanged
Dim XmlDataCollection As DataCollection = Nothing
Dim format As New XmlSerializer(GetType(DataCollection))
Using CustomerStream As Stream = _
File.OpenRead(DataDirectory & CustomersXml)
XmlDataCollection = DirectCast(format.Deserialize(CustomerStream), _
If Not XmlDataCollection Is Nothing Then
_Data.Customers = XmlDataCollection.Customers
The opposite of
Serialization involves saving data back to an xml file.
You can do this by again using the
Each time an edit is made to a Customer's data it can be written
back to the hard disk. For the
FrmCustomer class this is done in
Private Sub SaveCustomers()
Dim serializer As New XmlSerializer(GetType(DataCollection))
Dim Data As New DataCollection
Data.Customers = _Customers
Using CustomerStream As Stream = _
New FileStream(DataDirectory & "Customers.xml", FileMode.Create)
Dim writer As New XmlTextWriter(CustomerStream, Encoding.Unicode)
PrintDocument class defines a reusable object that sends
output to a printer, when printing from a Windows Forms application.
The following method creates the invoice on screen for print out.
Private Sub CreateInvoiceDocument(ByVal g As Graphics)
Dim srcRect As RectangleF = New Rectangle(0, 0, InvoiceSize.Width, _
Dim nWidth As Integer = _
Dim nHeight As Integer = _
Dim destRect As RectangleF = New Rectangle(0, 0, nWidth, nHeight)
Dim scalex As Single = CSng(destRect.Width / InvoiceSize.Width)
Dim scaley As Single = CSng(destRect.Height / InvoiceSize.Height)
Dim aPen As New Pen(Brushes.Black, 1)
If picGroupLogo.BackgroundImage IsNot Nothing Then
Dim gu As GraphicsUnit = GraphicsUnit.Pixel
Dim scaledRectangle As RectangleF = GetScaledRectangle(scalex, _
Dim myImage As Image = CType(picGroupLogo.BackgroundImage.Clone(), _
g.DrawImage(myImage, scaledRectangle, _
WriteInvoiceHeader(g, scalex, scaley)
WriteInvoiceLineItems(g, scalex, scaley)
Probably the most exciting portion of this program for me was finding the
library. Although the source is written in C# I am still a fan of this nifty little utility.
Maybe someday later I will translate it over to a more sensible language like
Visual Basic (i.e. VB.NET).
All jokes aside SpreadsheetLight is a great utility.
Below is an example of how toExport invoice data into a
Microsoft Excel spreadsheet. A preformatted template spreadsheet is used and
invoice data is dropped onto it. Creating a Helper class makes is simple to format
and manipulate the eventual output.
Public Class Helper
Private Sub Create(ByVal inInvoice As Invoice, info As FileInfo)
Dim sl As New SLDocument(TemplateDirectory & "Invoice.xlsx", "Invoice")
For Each item As LineItem In SortedHost
Databinding makes it easier and much simpler to bind class properties to
In the Databind method of the FrmProduct form we bind all the neccessary controls
to a specific Product object.
Private Sub Databind(ByVal item As Product)
cboCategory.DataBindings.Add("Text", item, "Category")
nbrPrice.DataBindings.Add("Value", item, "UnitPrice")
txtYear.DataBindings.Add("Text", item, "Year")
txtTitle.DataBindings.Add("Text", item, "Name")
nbrRating.DataBindings.Add("Text", item, "Rating")
txtNumber.DataBindings.Add("Text", item, "Number")
txtDescription.DataBindings.Add("Text", item, "Description")
txtActor.DataBindings.Add("Text", item, "Actor")
nbrQuantity.DataBindings.Add("Value", item, "Quantity")
StringRandomGenerator is actually a custom designed class
derived from an article found here on CodeProject.
Appended in the
GetRandom method is code to put a dash after
Public Function GetRandom() As String
If i > 0 AndAlso (i Mod 4) = 0 Then sb.Append("-")
Ordermate can be used as a basic example of utilizing the XMLSerializer class
to automate the creation of invoice forms.
The purpose of this article was to give you a sense of the experience of
building an WindowsForm application based upon XMLSerialization techniques.
I hope that you discovered that building an XML flat file application is not difficult.
In this article, we examined only the most basic features of the .NET framework
and using component libraries.