Practical Learning: Starting a Custom Collection Class |
|
- Start Microsoft Visual Basic and create a new Windows Forms Application named MusicalInstrumentStore1
- To create a dialog box, on the main menu, click Project -> Add Windows
Form...
- Set the name to CategoryEditor and click Add
- Design the form as follows:
|
Control |
Text |
Name |
Other Properties |
Label |
&Category: |
|
|
TextBox |
|
txtCategory |
Modifiers: Public |
Button |
OK |
btnOK |
DialogResult: OK |
Button |
Cancel |
btnCancel |
DialogResult: Cancel |
|
Form Property |
Value |
FormBorderStyle |
FixedDialog |
Text |
Category Editor |
StartPosition |
CenterScreen |
AcceptButton |
btnOK |
CancelButton |
btnCancel |
MaximizeBox |
False |
MinimizeBox |
False |
ShowInTaskbar |
False |
- To create a dialog box, on the main menu, click Project -> Add Windows
Form...
- Set the name to TypeEditor and click Add
- Design the form as follows:
|
Control |
Text |
Name |
Other Properties |
Label |
&Item Type: |
|
|
TextBox |
|
txtItemType |
Modifiers: Public |
Button |
OK |
btnOK |
DialogResult: OK |
Button |
Cancel |
btnCancel |
DialogResult: Cancel |
|
Form Property |
Value |
FormBorderStyle |
FixedDialog |
Text |
Type Editor |
StartPosition |
CenterScreen |
AcceptButton |
btnOK |
CancelButton |
btnCancel |
MaximizeBox |
False |
MinimizeBox |
False |
ShowInTaskbar |
False |
- To create a dialog box, in the Solution Explorer, right-click
MusicalInstrumentStore2 -> Add -> Windows
Form...
- Set the name to ItemEditor and click Add
- Design the form as follows:
|
Control |
Text |
Name |
Other Properties |
Label |
&Item #: |
|
|
TextBox |
|
txtItemNumber |
|
Label |
&Category: |
|
|
ComboBox |
|
cbxCategories |
|
Button |
New C&ategory... |
btnNewCategory |
|
Label |
&Item Type: |
|
|
ComboBox |
|
cbxItemTypes |
|
Button |
New &Item Type... |
btnNewItemType |
|
Label |
Item &Name: |
|
|
TextBox |
|
txtItemName |
|
Label |
&Unit Price: |
|
|
TextBox |
0.00 |
txtUnitPrice |
TextAlign: Right |
Button |
Picture... |
btnPicture |
|
TextBox |
|
txtPicturePath |
|
PictureBox |
|
pbxPicturePath |
SizeMode: Zoom |
Button |
Create |
btnCreate |
|
Button |
Close |
btnClose |
DialogResult: Cancel |
OpenFileDialog |
(Name): dlgOpen
Title: Select Item Picture
DefaultExt: jpg
Filter: JPEG Files (*.jpg,*.jpeg)|*.jpg|GIF Files (*.gif)|*.gif|Bitmap Files
(*.bmp)|*.bmp|PNG Files (*.png)|*.png |
|
Form Property |
Value |
FormBorderStyle |
FixedDialog |
Text |
Musical Instrument Store - Item Editor |
StartPosition |
CenterScreen |
MaximizeBox |
False |
MinimizeBox |
False |
ShowInTaskbar |
False |
- Double-click the New Category button and implement it as follows:
Private Sub btnNewCategoryClick(ByVal sender As System.Object,
ByVal e As System.EventArgs)
Handles btnNewCategory.Click
Dim Editor As CategoryEditor = New CategoryEditor
If Editor.ShowDialog() = DialogResult.OK Then
If Editor.txtCategory.Text.Length > 0 Then
Dim NewCategory As String = Editor.txtCategory.Text
' Make sure the category is not yet in the list
If cbxCategories.Items.Contains(NewCategory) Then
MsgBox(NewCategory + " is already in the list")
Else
' Since this is a new category, add it to the combo box
cbxCategories.Items.Add(NewCategory)
' Just in case the user wanted to use this new category
' select it
cbxCategories.Text = NewCategory
End If
End If
End If
End Sub
|
- In the Class name combo box, select btnNewItemType
- In the Method Name combo box, select Click and implement the event as follows:
Private Sub btnNewItemTypeClick(ByVal sender As Object,
ByVal e As System.EventArgs)
Handles btnNewItemType.Click
Dim Editor As TypeEditor = New TypeEditor
If Editor.ShowDialog() = DialogResult.OK Then
If Editor.txtItemType.Text.Length > 0 Then
Dim NewType As String = Editor.txtItemType.Text
' Make sure the type is not yet in the list
If cbxTypes.Items.Contains(NewType) Then
MsgBox("The list already contains " & NewType)
Else
cbxTypes.Items.Add(NewType)
cbxTypes.Text = NewType
End If
End If
End If
End Sub
|
- In the Class name combo box, select btnPicture
- In the Method Name combo box, select Click and implement the event as follows:
Private Sub btnPictureClick(ByVal sender As Object,
ByVal e As System.EventArgs)
Handles btnPicture.Click
If dlgPicture.ShowDialog() = DialogResult.OK Then
txtPicturePath.Text = dlgPicture.FileName
pbxStoreItem.Image = Image.FromFile(txtPicturePath.Text)
End If
End Sub
|
- In the Solution Explorer, right-click Form1.cs and click Rename
- Type MusicStore.vb and press Enter twice (to display the form)
- Design the form as follows:
|
Control |
Text |
Name |
Other Properties |
Label |
|
Item Category: |
|
|
ComboBox |
|
|
cbxCategories |
|
Label |
|
Items Type: |
|
|
ComboBox |
|
|
cbxTypes |
|
Label |
|
Available Items |
|
|
Button |
|
New Store Item... |
btnNewStoreItem |
|
ListView |
|
|
lvwStoreItems |
View: Details
FullRowSelect: True
GridLines: True |
Columns |
(Name) |
Text |
TextAlign |
Width |
colItemNumber |
Item # |
|
|
colItemName |
Item Name/Description |
|
320 |
colUnitPrice |
Unit Price |
Right |
|
|
PictureBox |
|
|
pbxStoreItem |
SizeMode: Zoom |
GroupBox |
|
Selected Items |
|
|
Label |
|
Item # |
|
|
Label |
|
Description |
|
|
Label |
|
Unit Price |
|
|
Label |
|
Qty |
|
|
Label |
|
Sub Total |
|
|
TextBox |
|
|
txtItemNumber1 |
|
TextBox |
|
|
txtDescription1 |
|
TextBox |
|
0.00 |
txtUnitPrice1 |
TextAlign: Right |
TextBox |
|
0 |
txtQuantity1 |
TextAlign: Right |
TextBox |
|
0.00 |
txtSubTotal1 |
TextAlign: Right |
Button |
|
Remove |
btnRemove1 |
|
TextBox |
|
|
txtItemNumber2 |
|
TextBox |
|
|
txtDescription2 |
|
TextBox |
|
0.00 |
txtUnitPrice2 |
TextAlign: Right |
TextBox |
|
0 |
txtQuantity2 |
TextAlign: Right |
TextBox |
|
0.00 |
txtSubTotal2 |
TextAlign: Right |
Button |
|
Remove |
btnRemove2 |
|
TextBox |
|
|
txtItemNumber3 |
|
TextBox |
|
|
txtDescription3 |
|
TextBox |
|
0.00 |
txtUnitPrice3 |
TextAlign: Right |
TextBox |
|
0 |
txtQuantity3 |
TextAlign: Right |
TextBox |
|
0.00 |
txtSubTotal3 |
TextAlign: Right |
Button |
|
Remove |
btnRemove3 |
|
TextBox |
|
|
txtItemNumber4 |
|
TextBox |
|
|
txtDescription4 |
|
TextBox |
|
0.00 |
txtUnitPrice4 |
TextAlign: Right |
TextBox |
|
0 |
txtQuantity4 |
TextAlign: Right |
TextBox |
|
0.00 |
txtSubTotal4 |
TextAlign: Right |
Button |
|
Remove |
btnRemove4 |
|
TextBox |
|
|
txtItemNumber5 |
|
TextBox |
|
|
txtDescription5 |
|
TextBox |
|
0.00 |
txtUnitPrice5 |
TextAlign: Right |
TextBox |
|
0 |
txtQuantity5 |
TextAlign: Right |
TextBox |
|
0.00 |
txtSubTotal5 |
TextAlign: Right |
Button |
|
Remove |
btnRemove5 |
|
TextBox |
|
|
txtItemNumber6 |
|
TextBox |
|
|
txtDescription6 |
|
TextBox |
|
0.00 |
txtUnitPrice6 |
TextAlign: Right |
TextBox |
|
0 |
txtQuantity6 |
TextAlign: Right |
TextBox |
|
0.00 |
txtSubTotal6 |
TextAlign: Right |
Button |
|
Remove |
btnRemove6 |
|
GroupBox |
|
Order Summary |
|
|
Label |
|
Items Total: |
|
|
TextBox |
|
0.00 |
txtItemsTotal |
TextAlign: Right |
Label |
|
Tax Rate: |
|
|
TextBox |
|
7.75 |
|
TextAlign: Right |
Label |
|
% |
|
|
Label |
|
Tax Amount: |
|
|
TextBox |
|
0.00 |
txtTaxAmount |
TextAlign: Right |
Label |
|
Order Total: |
|
|
TextBox |
|
0.00 |
txtOrderTotal |
TextAlign: Right |
Button |
|
Save |
btnSave |
|
Label |
|
Receipt #: |
|
|
TextBox |
|
0.00 |
txtReceiptNumber |
|
Button |
|
&Open |
btnOpen |
|
Button |
|
New Order |
btnNewOrder |
|
Button |
|
Close |
btnClose |
|
|
- To create a new class, in the Solution Explorer, right-click
MusicalInstrumentStore2 -> Add -> Class...
- Set the Name to StoreItem and press Enter
- Change the file as follows:
<Serializable()> Public Class StoreItem
Private nbr As String
Private cat As String
Private tp As String
Private nm As String
Private prc As Double
Public Property ItemNumber() As String
Get
Return nbr
End Get
Set(ByVal value As String)
nbr = value
End Set
End Property
Public Property Category() As String
Get
Return cat
End Get
Set(ByVal value As String)
cat = value
End Set
End Property
Public Property Type() As String
Get
Return tp
End Get
Set(ByVal value As String)
tp = value
End Set
End Property
Public Property ItemName() As String
Get
Return nm
End Get
Set(ByVal value As String)
nm = value
End Set
End Property
Public Property UnitPrice() As Double
Get
Return prc
End Get
Set(ByVal value As Double)
prc = value
End Set
End Property
Public Overrides Function Equals(ByVal Same As Object) As Boolean
If (nbr = Same.nbr) And
(cat = Same.cat) And
(tp = Same.tp) And
(nm = Same.nm) And
(prc = Same.prc) Then
Return True
Else
Return False
End If
End Function
Public Sub New()
nbr = "000000"
cat = "Accessories"
tp = "Accessories"
nm = "Unknown"
prc = 0.0
End Sub
Public Sub StoreItem(ByVal itmNumber As String)
nbr = itmNumber
cat = "Accessories"
tp = "Accessories"
nm = "Unknown"
prc = 0.0
End Sub
Public Sub New(ByVal itmNumber As String, ByVal strCategory As String,
ByVal strType As String, ByVal strName As String,
ByVal dPrice As Double)
nbr = itmNumber
cat = strCategory
tp = strType
nm = strName
prc = dPrice
End Sub
End Class
|
- Save the file
- To create a new class, in the Class View, right-click
MusicalInstrumentStore2 -> Add -> Class...
- Set the Name to StoreItems and press Enter
- Click the right side of the Public Class StoreItems line and press Enter
- Type Implements IList and press Enter.
Notice that a complete skeleton code has been generated
- Change the file as follows:
<Serializable()> Public Class StoreItems
Implements IList
Private Counter As Integer
Private Items() As Object = New Object
Public Sub New()
Counter = 0
End Sub
Public Sub CopyTo(ByVal array As System.Array,
ByVal index As Integer)
Implements System.Collections.ICollection.CopyTo
End Sub
Public ReadOnly Property Count() As Integer
Implements System.Collections.ICollection.Count
Get
Return Counter
End Get
End Property
Public ReadOnly Property IsSynchronized() As Boolean
Implements System.Collections.ICollection.IsSynchronized
Get
Return False
End Get
End Property
Public ReadOnly Property SyncRoot() As Object
Implements System.Collections.ICollection.SyncRoot
Get
Return Me
End Get
End Property
Public Function GetEnumerator() As System.Collections.IEnumerator
Implements System.Collections.IEnumerable.GetEnumerator
Return Nothing
End Function
' This method is used to add a new item to the collection
Public Function Add(ByVal value As Object) As Integer
Implements System.Collections.IList.Add
End Function
' This methods deletes all items from the collection
Public Sub Clear() Implements System.Collections.IList.Clear
End Sub
' This method is used to find out whether the item
' passed as argument exists in the collection
Public Function Contains(ByVal value As Object) As Boolean
Implements System.Collections.IList.Contains
End Function
' This method is used to check whether the item passed as
' argument exists in the collection. If so, it returns its index
Public Function IndexOf(ByVal value As Object) As Integer
Implements System.Collections.IList.IndexOf
End Function
' This method can be used to insert an item at
' a certain position inside the collection
Public Sub Insert(ByVal index As Integer, ByVal value As Object)
Implements System.Collections.IList.Insert
End Sub
Public ReadOnly Property IsFixedSize() As Boolean Implements
System.Collections.IList.IsFixedSize
Get
End Get
End Property
Public ReadOnly Property IsReadOnly() As Boolean
Implements System.Collections.IList.IsReadOnly
Get
End Get
End Property
Default Public Property Item(ByVal index As Integer) As Object
Implements System.Collections.IList.Item
Get
Return Nothing
End Get
Set(ByVal value As Object)
End Set
End Property
' This method first checks the existence of the item passed
' as argument. If the item exists, the method deletes it
Public Sub Remove(ByVal value As Object)
Implements System.Collections.IList.Remove
End Sub
' This method is used to delete the item positioned
' at the index passed as argument
Public Sub RemoveAt(ByVal index As Integer)
Implements System.Collections.IList.RemoveAt
End Sub
End Class
|
- Save the file
- Change the IsFixedSize() method as follows:
Public ReadOnly Property IsFixedSize() As Boolean Implements
System.Collections.IList.IsFixedSize
Get
Return False
End Get
End Property
|
- Save the file
- Change the IsReadOnly method as follows:
Public ReadOnly Property IsReadOnly() As Boolean
Implements System.Collections.IList.IsReadOnly
Get
Return False
End Get
End Property
|
- Save the file
- Change the code of the StoreItems.Add() method as follows:
' This method is used to add a new item to the collection
Public Function Add(ByVal value As Object) As Integer
Implements System.Collections.IList.Add
' Find out if the array is getting too small for the next item(s)
' If it is, increase its size by 5
If Count = Items.Length Then
Array.Resize(Items, Items.Length + 5)
End If
If Counter < Items.Length Then
Items(Counter) = value
Counter = Counter + 1
Return Counter - 1
Else
Return -1
End If
End Function
|
- In the Class View, double-click ItemEditor
- In the top section of the file, add the following:
Imports System.IO
Imports System.Runtime.Serialization.Formatters.Binary
Public Class ItemEditor
|
- In the Solution Explorer, right-click ItemEditor.vb and click View
Code
- In the Class name combo box, select btnCreate
- In the Method Name combo box, select Click and implement the event
as follows:
Private Sub btnCreateClick(ByVal sender As Object,
ByVal e As System.EventArgs)
Handles btnCreate.Click
Dim StreamStoreItem As FileStream
Dim Item As StoreItem = New StoreItem
Dim items As StoreItems = New StoreItems
Dim FormatterStoreItem As BinaryFormatter = New BinaryFormatter
' If this directory doesn't exist, create it
Directory.CreateDirectory("C:\Musical Instrument Store")
' This is the file that holds the list of items
Dim Filename As String = "C:\Musical Instrument Store\StoreItems.mis"
' Create a random number that will be used to identify the item
Dim RndNumber As Random = New Random
txtItemNumber.Text = RndNumber.Next(100000, 999999)
' Make sure the user had selected a category
If cbxCategories.Text.Length = 0 Then
MsgBox("You must specify the item's category")
cbxCategories.Focus()
Exit Sub
End If
' Make sure the user had selected a type
If cbxTypes.Text.Length = 0 Then
MsgBox("You must specify the item's type")
cbxTypes.Focus()
Exit Sub
End If
' Make sure the user had entered a name/description
If txtItemName.Text.Length = 0 Then
MsgBox("You must enter the name (or a " &
"short description) for the item")
txtItemName.Focus()
Exit Sub
End If
' Make sure the user had typed a price for the item
If txtUnitPrice.Text.Length = 0 Then
MsgBox("You must enter the price of the item")
txtUnitPrice.Focus()
Exit Sub
End If
' Before saving the new item, find out if there was
' already a file that holds the list of items
' If that file exists, open it and store its items
' in our StoreItems list
If File.Exists(Filename) Then
StreamStoreItem = New FileStream(Filename,
FileMode.Open,
FileAccess.Read,
FileShare.Read)
Try
' Retrieve the list of items from file
items = CType(FormatterStoreItem.Deserialize(StreamStoreItem),
StoreItems)
Finally
StreamStoreItem.Close()
End Try
End If
' Create the music item
item.ItemNumber = txtItemNumber.Text
item.Category = cbxCategories.Text
item.Type = cbxTypes.Text
item.ItemName = txtItemName.Text
item.UnitPrice = cdbl(txtUnitPrice.Text)
' Call the Add method of our collection class to add the item
items.Add(item)
' Save the list
StreamStoreItem = New FileStream(Filename,
FileMode.Create,
FileAccess.Write,
FileShare.Write)
Try
FormatterStoreItem.Serialize(StreamStoreItem, items)
If txtPicturePath.Text.Length <> 0 Then
Dim flePicture As FileInfo = New FileInfo(txtPicturePath.Text)
flePicture.CopyTo("C:\Musical Instrument Store\" &
txtItemNumber.Text & flePicture.Extension)
End If
' After saving the item, reset the form
txtItemNumber.Text = RndNumber.Next(100000, 999999).ToString()
cbxCategories.Text = ""
cbxTypes.Text = ""
txtItemName.Text = ""
txtUnitPrice.Text = "0.00"
txtPicturePath.Text = ""
pbxStoreItem.Image = Nothing
Finally
StreamStoreItem.Close()
End Try
End Sub
|
- Save the file
- In the Class View, click StoreItems
- In the lower part of the Class View, double-click Item(Integer) As Object
- Change the code of the property as
follows:
Default Public Property Item(ByVal index As Integer) As Object
Implements System.Collections.IList.Item
Get
Return Items(index)
End Get
Set(ByVal value As Object)
Items(index) = value
End Set
End Property
|
- In the Solution Explorer, right-click ItemEditor.vb and click View
Code
- In the Class name combo box, select (ItemEditor Events)
- In the Method Name combo box, select Load and implement the event
as follows:
Private Sub ItemEditorLoad(ByVal sender As Object,
ByVal e As System.EventArgs) Handles Me.Load
Dim i As Integer
Dim RndNumber As Random = New Random
' Since all values seem ready, prepare to process the item
Dim Item As StoreItem = New StoreItem
Dim Items As StoreItems = New StoreItems
Dim FormatterStoreItem As BinaryFormatter = New BinaryFormatter
' This is the file that holds the list of items
Dim Filename As String = "C:\Musical Instrument Store\StoreItems.mis"
If File.Exists(Filename) Then
Dim StreamStoreItem As FileStream = New FileStream(Filename,
FileMode.Open,
FileAccess.Read,
FileShare.Read)
Try
' Retrieve the list of items from file
Items = CType(FormatterStoreItem.Deserialize(StreamStoreItem),
StoreItems)
' Display the categories in the combo box
For i = 0 To Items.Count - 1
Item = CType(Items(i), StoreItem)
If Not cbxCategories.Items.Contains(Item.Category) Then
cbxCategories.Items.Add(Item.Category)
End If
Next
' Display the items types in the combo box
For i = 0 To Items.Count - 1
Item = CType(Items(i), StoreItem)
If Not cbxTypes.Items.Contains(Item.Type) Then
cbxTypes.Items.Add(Item.Type)
End If
Next
Finally
StreamStoreItem.Close()
End Try
Else
' Create a random number that will be used
' to identify the item
txtItemNumber.Text = RndNumber.Next(100000, 999999).ToString()
' Make sure the user had selected a category
cbxCategories.Text = ""
cbxTypes.Text = ""
End If
End Sub
|
- In the Solution Explorer, right-click MusicStore.vb and click View Code
- Make the following changes:
Imports System.IO
Imports System.Runtime.Serialization.Formatters.Binary
Public Class MusicStore
Private Items As StoreItems
Private iFilename As Integer
Private IsNewCustomerOrder As Boolean
Private Sub LoadMusicStore()
' Since all values seem ready, prepare to process the item
Dim i As Integer
items = New StoreItems
Dim FormatterStoreItem As BinaryFormatter = New BinaryFormatter
' This is the file that holds the list of items
Dim Filename As String = "C:\Musical Instrument Store\StoreItems.mis"
If File.Exists(Filename) Then
Dim StreamStoreItem As FileStream = New FileStream(Filename,
FileMode.Open,
FileAccess.Read,
FileShare.Read)
Try
' Retrieve the list of items from file
Items = CType(FormatterStoreItem.Deserialize(StreamStoreItem),
StoreItems)
' Display the categories in the combo box
For i = 0 To items.Count - 1
Dim item As StoreItem = CType(items(i), StoreItem)
If Not cbxCategories.Items.Contains(item.Category) Then
cbxCategories.Items.Add(item.Category)
End If
Next
Finally
StreamStoreItem.Close()
End Try
End If
End Sub
End Class
|
- In the Class Name combo box, select btnNewStoreItem
- In the Method Name combo box, select Click and implement the event as follows:
Private Sub btnNewStoreItemClick(ByVal sender As Object,
ByVal e As System.EventArgs)
Handles btnNewStoreItem.Click
Dim Editor As ItemEditor = New ItemEditor
' Create a random number to get it ready for
' the user creating a new store item
Dim RndNumber As Random = New Random
Editor.txtItemNumber.Text = RndNumber.Next(100000, 999999)
If Editor.ShowDialog() = DialogResult.Cancel Then
LoadMusicStore()
End If
End Sub
|
- In the Class Name combo box, select cbxCategories
- In the Method Name combo box, select SelectedIndexChanged and implement the event as
follows:
Private Sub cbxCategoriesSelectedIndexChanged(ByVal sender As Object,
ByVal e As System.EventArgs)
Handles cbxCategories.SelectedIndexChanged
Dim i As Integer
cbxTypes.Items.Clear()
cbxTypes.Text = ""
lvwStoreItems.Items.Clear()
pbxStoreItem.Image = Nothing
' If the current store inventory is empty, don't do anything
If Items.Count = 0 Then Exit Sub
' Get the item selected in the combo box
Dim strCategory = CStr(cbxCategories.SelectedItem)
' Before doing anything, remove everything from the Types combo box
' This eliminates the possibility of adding the same item(s) that
' would exist already in the combo box
cbxTypes.Items.Clear()
' Check each item from the store inventory
For i = 0 To Items.Count - 1
' Get the current item from the store inventory
Dim Item = CType(Items(i), StoreItem)
' If that item is the same as the one selected in the combo box...
If Item.Category = strCategory Then
' ... get ready to add its corresponding type
' But check first that the type is not
' already in the Types combo box
' If it's not yet there, then add it
If Not cbxTypes.Items.Contains(Item.Type) Then
cbxTypes.Items.Add(Item.Type)
End If
End If
Next
End Sub
|
- In the Class Name combo box, select cbxTypes
- In the Method Name combo box, select SelectedIndexChanged and implement the event as
follows:
Private Sub cbxTypesSelectedIndexChanged(ByVal sender As Object,
ByVal e As System.EventArgs)
Handles cbxTypes.SelectedIndexChanged
Dim i As Integer
cbxTypes.Text = ""
pbxStoreItem.Image = Nothing
Dim lviStoreItem As ListViewItem
' If the current store inventory is empty, don't do anything
If Items.Count = 0 Then Exit Sub
' Get the item selected in the Categories combo box
Dim strCategory As String = CStr(cbxCategories.SelectedItem)
' Get the item selected in theTypes combo box
Dim strType As String = CStr(cbxTypes.SelectedItem)
' Empty the Available Items list view because
' we are about to (re)populate it
lvwStoreItems.Items.Clear()
' Check each item from the store inventory
For i = 0 To Items.Count - 1
' Get the current item from the inventory
Dim Item As StoreItem = CType(Items(i), StoreItem)
' If the category of that item is the same as the one
' selected in the combo box and the type of that item is
' the same as the one selected in the Types combo box...
If (Item.Category = strCategory) And
(Item.Type = strType) Then
' ... then display it in the Available Items list view
lviStoreItem = lvwStoreItems.Items.Add(Item.ItemNumber)
lviStoreItem.SubItems.Add(Item.ItemName)
lviStoreItem.SubItems.Add(FormatNumber(Item.UnitPrice))
End If
Next
End Sub
|
- In the Class Name combo box, select lvwStoreItems
- In the Method Name combo box, select
SelectedIndexChanged and implement the event as follows:
Private Sub lvwStoreItemsSelectedIndexChanged(ByVal sender As Object,
ByVal e As System.EventArgs)
Handles lvwStoreItems.SelectedIndexChanged
Dim i As Integer
Dim strItemNumber As String
Dim Item As StoreItem = New StoreItem
If (lvwStoreItems.SelectedItems.Count = 0) Or
(lvwStoreItems.SelectedItems.Count > 1) Then
Exit Sub
End If
strItemNumber = lvwStoreItems.SelectedItems(0).SubItems(0).Text
For i = 0 To Items.Count - 1
Dim itm As StoreItem = CType(Items(i), StoreItem)
If itm.ItemNumber = strItemNumber Then
Item = itm
End If
Next
' Make a list of the picture files
Dim strDirectory As String = "C:\Musical Instrument Store"
Dim dirStoreItems As DirectoryInfo = New DirectoryInfo(strDirectory)
Dim PictureFiles() As FileInfo = dirStoreItems.GetFiles("*.jpg")
' Look for a file that holds the same name as the item number
For Each fle As FileInfo In PictureFiles
' Get the name of the file without its extension
Dim fwe As String = Path.GetFileNameWithoutExtension(fle.FullName)
If fwe = strItemNumber Then
pbxStoreItem.Image = Image.FromFile(strDirectory &
"\" + Item.ItemNumber + ".jpg")
End If
Next
End Sub
|
- Under the above End Sub line, create a new procedure as follows;
' This function calculates the current total order
' and updates the order
Private Sub CalculateOrder()
Dim SubTotal1 As Double
Dim SubTotal2 As Double
Dim SubTotal3 As Double
Dim SubTotal4 As Double
Dim SubTotal5 As Double
Dim SubTotal6 As Double
Dim ItemsTotal As Double
Dim TaxRate As Double
Dim TaxAmount As Double
Dim OrderTotal As Double
' Retrieve the value of each sub total
Try
SubTotal1 = CDbl(txtSubTotal1.Text)
Catch
MsgBox("Invalid Value")
End Try
Try
SubTotal2 = CDbl(txtSubTotal2.Text)
Catch
MsgBox("Invalid Value")
End Try
Try
SubTotal3 = CDbl(txtSubTotal3.Text)
Catch
MsgBox("Invalid Value")
End Try
Try
SubTotal4 = CDbl(txtSubTotal4.Text)
Catch
MsgBox("Invalid Value")
End Try
Try
SubTotal5 = CDbl(txtSubTotal5.Text)
Catch
MsgBox("Invalid Value")
End Try
Try
SubTotal6 = CDbl(txtSubTotal6.Text)
Catch
MsgBox("Invalid Value")
End Try
' Calculate the total value of the sub totals
ItemsTotal = SubTotal1 + SubTotal2 + SubTotal3 +
SubTotal4 + SubTotal5 + SubTotal6
' Display the total order in the appropriate text box
txtItemsTotal.Text = FormatNumber(ItemsTotal)
Try
TaxRate = CDbl(txtTaxRate.Text)
Catch
MsgBox("Invalid Tax Rate")
txtTaxRate.Text = "7.75"
txtTaxRate.Focus()
End Try
TaxAmount = ItemsTotal * TaxRate / 100
OrderTotal = ItemsTotal + TaxAmount
txtTaxAmount.Text = FormatNumber(TaxAmount)
txtOrderTotal.Text = FormatNumber(OrderTotal)
End Sub
|
- In the Class Name combo box, select txtItemNumber1
- In the Method Name combo box, select Leave and implement the event as follows:
Private Sub txtItemNumber1Leave(ByVal sender As Object,
ByVal e As System.EventArgs)
Handles txtItemNumber1.Leave
Dim ItemFound As Boolean = False
Dim Item As StoreItem = New StoreItem
Dim strItemNumber As String = txtItemNumber1.Text
For Each Itm As StoreItem In Items
If Itm.ItemNumber = strItemNumber Then
ItemFound = True
txtDescription1.Text = Itm.ItemName
txtUnitPrice1.Text = Itm.UnitPrice.ToString("F")
txtQuantity1.Text = "1"
txtSubTotal1.Text = Itm.UnitPrice.ToString("F")
CalculateOrder()
End If
Next
If ItemFound = False Then
MsgBox("There is no store item with that number")
txtDescription1.Text = ""
txtUnitPrice1.Text = "0.00"
txtQuantity1.Text = "0"
txtSubTotal1.Text = "0.00"
End If
End Sub
|
- Under the above End Sub line, define the following event
Public Sub Item1Leave(ByVal sender As Object,
ByVal e As EventArgs)
Handles txtUnitPrice1.Leave, txtQuantity1.Leave
Dim Quantity As Integer
Dim UnitPrice As Double
Dim SubTotal As Double
' Get the quantity of the current item
Try
Quantity = CInt(txtQuantity1.Text)
Catch
MsgBox("Invalid quantity value for item 1")
End Try
' Get the unit price of the current item
Try
UnitPrice = CDbl(txtUnitPrice1.Text)
Catch
MsgBox("Invalid unit price for item 1")
End Try
' Calculate the current sub total
SubTotal = Quantity * UnitPrice
' Display the new sub total in the corresponding text box
txtSubTotal1.Text = FormatNumber(SubTotal)
btnRemove1.Enabled = True
' Update the order
CalculateOrder()
End Sub
|
- In the Class Name combo box, select btnRemove1
- On the form, double-click the top Remove button and implement the event as
follows:
Private Sub btnRemove1Click(ByVal sender As Object,
ByVal e As System.EventArgs)
Handles btnRemove1.Click
txtItemNumber1.Text = ""
txtDescription1.Text = ""
txtUnitPrice1.Text = "0.00"
txtQuantity1.Text = "0"
txtSubTotal1.Text = "0.00"
btnRemove1.Enabled = False
CalculateOrder()
End Sub
|
- Complete the file as follows:
Public Sub Item2Leave(ByVal sender As Object,
ByVal e As EventArgs)
Handles txtUnitPrice2.Leave, txtQuantity2.Leave
Dim Quantity As Integer
Dim UnitPrice As Double
Dim SubTotal As Double
' Get the quantity of the current item
Try
Quantity = CInt(txtQuantity2.Text)
Catch
MsgBox("Invalid quantity value for item 2")
End Try
' Get the unit price of the current item
Try
UnitPrice = CDbl(txtUnitPrice2.Text)
Catch
MsgBox("Invalid unit price for item 2")
End Try
' Calculate the current sub total
SubTotal = Quantity * UnitPrice
' Display the new sub total in the corresponding text box
txtSubTotal2.Text = SubTotal.ToString()
btnRemove2.Enabled = True
' Update the order
CalculateOrder()
End Sub
Private Sub btnRemove2Click(ByVal sender As Object,
ByVal e As System.EventArgs)
Handles btnRemove2.Click
txtItemNumber2.Text = ""
txtDescription2.Text = ""
txtUnitPrice2.Text = "0.00"
txtQuantity2.Text = "0"
txtSubTotal2.Text = "0.00"
btnRemove2.Enabled = False
CalculateOrder()
End Sub
Public Sub Item3Leave(ByVal sender As Object,
ByVal e As EventArgs)
Handles txtUnitPrice3.Leave, txtQuantity3.Leave
Dim Quantity As Integer
Dim UnitPrice As Double
Dim SubTotal As Double
' Get the quantity of the current item
Try
Quantity = CInt(txtQuantity3.Text)
Catch
MsgBox("Invalid quantity value for item 3")
End Try
' Get the unit price of the current item
Try
UnitPrice = CDbl(txtUnitPrice3.Text)
Catch
MsgBox("Invalid unit price for item 3")
End Try
' Calculate the current sub total
SubTotal = Quantity * UnitPrice
' Display the new sub total in the corresponding text box
txtSubTotal3.Text = SubTotal.ToString()
btnRemove3.Enabled = True
' Update the order
CalculateOrder()
End Sub
Private Sub btnRemove3Click(ByVal sender As Object,
ByVal e As System.EventArgs)
Handles btnRemove3.Click
txtItemNumber3.Text = ""
txtDescription3.Text = ""
txtUnitPrice3.Text = "0.00"
txtQuantity3.Text = "0"
txtSubTotal3.Text = "0.00"
btnRemove3.Enabled = False
CalculateOrder()
End Sub
Public Sub Item4Leave(ByVal sender As Object,
ByVal e As EventArgs)
Handles txtUnitPrice4.Leave, txtQuantity4.Leave
Dim Quantity As Integer
Dim UnitPrice As Double
Dim SubTotal As Double
' Get the quantity of the current item
Try
Quantity = CInt(txtQuantity4.Text)
Catch
MsgBox("Invalid quantity value for item 4")
End Try
' Get the unit price of the current item
Try
UnitPrice = CDbl(txtUnitPrice4.Text)
Catch
MsgBox("Invalid unit price for item 4")
End Try
' Calculate the current sub total
SubTotal = Quantity * UnitPrice
' Display the new sub total in the corresponding text box
txtSubTotal4.Text = SubTotal.ToString()
btnRemove4.Enabled = True
' Update the order
CalculateOrder()
End Sub
Private Sub btnRemove4Click(ByVal sender As Object,
ByVal e As System.EventArgs)
Handles btnRemove4.Click
txtItemNumber4.Text = ""
txtDescription4.Text = ""
txtUnitPrice4.Text = "0.00"
txtQuantity4.Text = "0"
txtSubTotal4.Text = "0.00"
btnRemove4.Enabled = False
CalculateOrder()
End Sub
Public Sub Item5Leave(ByVal sender As Object,
ByVal e As EventArgs)
Handles txtUnitPrice5.Leave, txtQuantity5.Leave
Dim Quantity As Integer
Dim UnitPrice As Double
Dim SubTotal As Double
' Get the quantity of the current item
Try
Quantity = CInt(txtQuantity5.Text)
Catch
MsgBox("Invalid quantity value for item 5")
End Try
' Get the unit price of the current item
Try
UnitPrice = CDbl(txtUnitPrice5.Text)
Catch
MsgBox("Invalid unit price for item 5")
End Try
' Calculate the current sub total
SubTotal = Quantity * UnitPrice
' Display the new sub total in the corresponding text box
txtSubTotal5.Text = SubTotal.ToString()
btnRemove5.Enabled = True
' Update the order
CalculateOrder()
End Sub
Private Sub btnRemove5Click(ByVal sender As Object,
ByVal e As System.EventArgs)
Handles btnRemove5.Click
txtItemNumber5.Text = ""
txtDescription5.Text = ""
txtUnitPrice5.Text = "0.00"
txtQuantity5.Text = "0"
txtSubTotal5.Text = "0.00"
btnRemove5.Enabled = False
CalculateOrder()
End Sub
Public Sub Item6Leave(ByVal sender As Object,
ByVal e As EventArgs)
Handles txtUnitPrice6.Leave, txtQuantity6.Leave
Dim Quantity As Integer
Dim UnitPrice As Double
Dim SubTotal As Double
' Get the quantity of the current item
Try
Quantity = CInt(txtQuantity6.Text)
Catch
MsgBox("Invalid quantity value for item 6")
End Try
' Get the unit price of the current item
Try
UnitPrice = CDbl(txtUnitPrice6.Text)
Catch
MsgBox("Invalid unit price for item 6")
End Try
' Calculate the current sub total
SubTotal = Quantity * UnitPrice
' Display the new sub total in the corresponding text box
txtSubTotal6.Text = SubTotal.ToString()
btnRemove6.Enabled = True
' Update the order
CalculateOrder()
End Sub
Private Sub btnRemove6Click(ByVal sender As Object,
ByVal e As System.EventArgs)
Handles btnRemove6.Click
txtItemNumber6.Text = ""
txtDescription6.Text = ""
txtUnitPrice6.Text = "0.00"
txtQuantity6.Text = "0"
txtSubTotal6.Text = "0.00"
btnRemove6.Enabled = False
CalculateOrder()
End Sub
|
- In the Class Name combo box, select txtTaxRate
- In the Method Name combo box, select Leave and
implement the event as follows:
Private Sub txtTaxRateLeave(ByVal sender As Object,
ByVal e As System.EventArgs)
Handles txtTaxRate.Leave
CalculateOrder()
End Sub
|
- In the Class Name combo box, select btnNewCustomerOrder
- In the Method Name combo box, select Click and
implement the event as follows:
Private Sub btnNewCustomerOrderClick(ByVal sender As Object,
ByVal e As System.EventArgs)
Handles btnNewCustomerOrder.Click
' We will store our files in the following folder
Dim strDirectory As String = "C:\Musical Instrument Store\Receipts"
Dim dirInfo = Directory.CreateDirectory(strDirectory)
' Get the list of files, if any, from our directory
Dim ListOfFiles = dirInfo.GetFiles()
Dim Filename As String = ""
' If there is no file in the directory,
' then we will use 1000 as the first file name
If ListOfFiles.Length = 0 Then
iFilename = 1000
Else ' If there was at least one file in the directory
' Get a reference to the last file
Dim LastFile = ListOfFiles(ListOfFiles.Length - 1)
' Get the name of the last file without its extension
Dim fwe As String =
Path.GetFileNameWithoutExtension(LastFile.FullName)
' Increment the name of the file by 1
iFilename = CInt(fwe) + 1
End If
' Update our global name of the file
Filename = strDirectory + "\" + CStr(iFilename) + ".cos"
txtReceiptNumber.Text = CStr(iFilename)
cbxCategories.Text = ""
cbxTypes.Text = ""
lvwStoreItems.Items.Clear()
txtItemNumber1.Text = ""
txtDescription1.Text = ""
txtUnitPrice1.Text = "0.00"
txtQuantity1.Text = "0"
txtSubTotal1.Text = "0.00"
txtItemNumber2.Text = ""
txtDescription2.Text = ""
txtUnitPrice2.Text = "0.00"
txtQuantity2.Text = "0"
txtSubTotal2.Text = "0.00"
txtItemNumber3.Text = ""
txtDescription3.Text = ""
txtUnitPrice3.Text = "0.00"
txtQuantity3.Text = "0"
txtSubTotal3.Text = "0.00"
txtItemNumber4.Text = ""
txtDescription4.Text = ""
txtUnitPrice4.Text = "0.00"
txtQuantity4.Text = "0"
txtSubTotal4.Text = "0.00"
txtItemNumber5.Text = ""
txtDescription5.Text = ""
txtUnitPrice5.Text = "0.00"
txtQuantity5.Text = "0"
txtSubTotal5.Text = "0.00"
txtItemNumber6.Text = ""
txtDescription6.Text = ""
txtUnitPrice6.Text = "0.00"
txtQuantity6.Text = "0"
txtSubTotal6.Text = "0.00"
txtItemsTotal.Text = "0.00"
txtTaxRate.Text = "7.75"
txtTaxAmount.Text = "0.00"
txtOrderTotal.Text = "0.00"
End Sub
|
- In the Class Name combo box, select btnSave
- In the Method Name combo box, select Click and implement the event as follows:
Private Sub btnSaveClick(ByVal sender As Object,
ByVal e As System.EventArgs)
Handles btnSave.Click
Dim fwe As String
Dim Filename As String
Dim LastFile As FileInfo
' We will store our files in the following folder
Dim strDirectory As String = "C:\Musical Instrument Store\Receipts"
Dim dirInfo = Directory.CreateDirectory(strDirectory)
' Get the list of files, if any, from our directory
Dim ListOfFiles() As FileInfo = dirInfo.GetFiles()
' If this is a new customer order,
' get ready to create a name for the file
If IsNewCustomerOrder = True Then
' If there is no file in the directory,
' then we will use 1000 as the first file name
If ListOfFiles.Length = 0 Then
iFilename = 1000
Else ' If there was at least one file in the directory
' Get a reference to the last file
LastFile = ListOfFiles(ListOfFiles.Length - 1)
' Get the name of the last file without its extension
fwe = Path.GetFileNameWithoutExtension(LastFile.FullName)
' Increment the name of the file by 1
iFilename = CInt(fwe) + 1
End If
' Update our global name of the file
Filename = strDirectory + "\" + iFilename.ToString() + ".cos"
txtReceiptNumber.Text = iFilename.ToString()
IsNewCustomerOrder = False
' If a cleaning order was already opened,
' we will simply update it
Else
Filename = "C:\Musical Instrument Store\Receipts\" &
txtReceiptNumber.Text & ".cos"
End If
Dim wrtCustomerOrder As StreamWriter = New StreamWriter(Filename)
Try
wrtCustomerOrder.WriteLine(txtItemNumber1.Text)
wrtCustomerOrder.WriteLine(txtDescription1.Text)
wrtCustomerOrder.WriteLine(txtUnitPrice1.Text)
wrtCustomerOrder.WriteLine(txtQuantity1.Text)
wrtCustomerOrder.WriteLine(txtItemNumber2.Text)
wrtCustomerOrder.WriteLine(txtDescription2.Text)
wrtCustomerOrder.WriteLine(txtUnitPrice2.Text)
wrtCustomerOrder.WriteLine(txtQuantity2.Text)
wrtCustomerOrder.WriteLine(txtItemNumber3.Text)
wrtCustomerOrder.WriteLine(txtDescription3.Text)
wrtCustomerOrder.WriteLine(txtUnitPrice3.Text)
wrtCustomerOrder.WriteLine(txtQuantity3.Text)
wrtCustomerOrder.WriteLine(txtItemNumber4.Text)
wrtCustomerOrder.WriteLine(txtDescription4.Text)
wrtCustomerOrder.WriteLine(txtUnitPrice4.Text)
wrtCustomerOrder.WriteLine(txtQuantity4.Text)
wrtCustomerOrder.WriteLine(txtItemNumber5.Text)
wrtCustomerOrder.WriteLine(txtDescription5.Text)
wrtCustomerOrder.WriteLine(txtUnitPrice5.Text)
wrtCustomerOrder.WriteLine(txtQuantity5.Text)
wrtCustomerOrder.WriteLine(txtItemNumber6.Text)
wrtCustomerOrder.WriteLine(txtDescription6.Text)
wrtCustomerOrder.WriteLine(txtUnitPrice6.Text)
wrtCustomerOrder.WriteLine(txtQuantity6.Text)
wrtCustomerOrder.WriteLine(txtItemsTotal.Text)
wrtCustomerOrder.WriteLine(txtTaxRate.Text)
Finally
wrtCustomerOrder.Close()
End Try
End Sub
|
- In the Class Name combo box, select
- Double-click the Open button and implement its event as follows:
Private Sub btnOpenClick(ByVal sender As Object,
ByVal e As System.EventArgs)
Handles btnOpen.Click
Dim strDirectory = "C:\Musical Instrument Store\Receipts"
Dim strFilename As String =
"C:\Musical Instrument Store\Receipts\1000.cos"
If txtReceiptNumber.Text = "" Then
Exit Sub
Else
Try
strFilename = strDirectory & "\" &
txtReceiptNumber.Text + ".cos"
Dim rdrCustomerOrder As StreamReader =
New StreamReader(strFilename)
Try
txtItemNumber1.Text = rdrCustomerOrder.ReadLine()
txtDescription1.Text = rdrCustomerOrder.ReadLine()
txtUnitPrice1.Text = rdrCustomerOrder.ReadLine()
txtQuantity1.Text = rdrCustomerOrder.ReadLine()
Item1Leave(sender, e)
txtItemNumber2.Text = rdrCustomerOrder.ReadLine()
txtDescription2.Text = rdrCustomerOrder.ReadLine()
txtUnitPrice2.Text = rdrCustomerOrder.ReadLine()
txtQuantity2.Text = rdrCustomerOrder.ReadLine()
Item2Leave(sender, e)
txtItemNumber3.Text = rdrCustomerOrder.ReadLine()
txtDescription3.Text = rdrCustomerOrder.ReadLine()
txtUnitPrice3.Text = rdrCustomerOrder.ReadLine()
txtQuantity3.Text = rdrCustomerOrder.ReadLine()
Item3Leave(sender, e)
txtItemNumber4.Text = rdrCustomerOrder.ReadLine()
txtDescription4.Text = rdrCustomerOrder.ReadLine()
txtUnitPrice4.Text = rdrCustomerOrder.ReadLine()
txtQuantity4.Text = rdrCustomerOrder.ReadLine()
Item4Leave(sender, e)
txtItemNumber5.Text = rdrCustomerOrder.ReadLine()
txtDescription5.Text = rdrCustomerOrder.ReadLine()
txtUnitPrice5.Text = rdrCustomerOrder.ReadLine()
txtQuantity5.Text = rdrCustomerOrder.ReadLine()
Item5Leave(sender, e)
txtItemNumber6.Text = rdrCustomerOrder.ReadLine()
txtDescription6.Text = rdrCustomerOrder.ReadLine()
txtUnitPrice6.Text = rdrCustomerOrder.ReadLine()
txtQuantity6.Text = rdrCustomerOrder.ReadLine()
Item6Leave(sender, e)
txtItemsTotal.Text = rdrCustomerOrder.ReadLine()
txtTaxRate.Text = rdrCustomerOrder.ReadLine()
CalculateOrder()
IsNewCustomerOrder = False
Finally
rdrCustomerOrder.Close()
End Try
Catch Exc As FileNotFoundException
MsgBox("There is no customer order with that receipt number")
End Try
End If
End Sub
|
- In the Class Name combo box, select (MusicStore Events)
- In the Method Name combo box, select Load and implement the event as
follows:
Private Sub MusicStoreLoad(ByVal sender As Object,
ByVal e As System.EventArgs)
Handles Me.Load
btnNewCustomerOrderClick(sender, e)
LoadMusicStore()
IsNewCustomerOrder = True
End Sub
|
- In the Class Name combo box, select btnClose
- Double-click the Close and implement its Click event as follows:
Private Sub btnCloseClick(ByVal sender As Object,
ByVal e As System.EventArgs)
Handles btnClose.Click
End
End Sub
|
- Execute the application to test it
- Access the Item Editor dialog box and create a few items as follows
(let the computer create the item numbers):
Category |
Type |
Item Name |
Unit Price |
Picture |
Guitars |
Electric |
Gibson Les Paul Vintage Mahogany Electric Guitar |
745.95 |
Picture |
Bass |
Electric 4-String |
Epiphone Thunderbird IV Bass |
325.85 |
Picture |
Keyboards |
Synthesizers |
Alesis QS8.2 88 Key Synthesizer |
825.50 |
Picture |
Guitars |
Acoustic |
Gretsch Guitars G100 Synchromatic Archtop Acoustic Guitar |
595.95 |
Picture |
Drums |
Drum Set |
Pulse Pro 5-Piece Drum Set with Cymbals |
395.95 |
Picture |
Keyboards |
Pianos |
Roland RD-700SX Digital Piano |
2195.00 |
|
Accessories |
Cables |
Mogami Gold AES/EBU Interconnect Cable with Neutrik XLR |
45.85 |
|
Guitars |
Acoustic-Electric |
Ibanez V Series V70CE Dreadnought Cutaway Acoustic-Electric Guitar |
225.50 |
|
Guitars |
Electric |
Schecter C-1 Hellraiser Electric Guitar |
650.00 |
Picture |
Keyboards |
Synthesizers |
Roland V Synth GT Elastic Audio Synthesizer Keyboard |
2895.50 |
Picture |
Bass |
Electric 5-String |
Fender Jazz Bass 24 V 5-String Bass Guitar |
825.50 |
Picture |
Guitars |
Electric |
Fender Standard Stratocaster Left-Handed Electric Guitar |
425.85 |
Picture |
Recording |
Microphone |
MXL V63M Studio Condenser Microphone |
72.95 |
Picture |
Guitars |
Acoustic |
Yamaha FD01S Acoustic Folk Guitar |
185.95 |
|
Book/CD/DVD |
Instructional |
Hal Leonard Amazing Phrasing - Alto Sax (Book/CD) |
18.00 |
|
Guitars |
Classical & Nylon |
Alvarez Artist Series AC60S Classical Acoustic Guitar |
275.95 |
Picture |
Guitars |
Acoustic |
Washburn D100DL Acoustic Guitar |
150.50 |
Picture |
Drums |
Electronic Percussion |
Boss DR-670 Dr. Rhythm Drum Machine |
275.85 |
Picture |
Recording |
Microphone |
Shure SM58 Mic |
95.95 |
Picture |
Accessories |
Cables |
Live Wire HPE325 Headphone and Extension Cable |
10.95 |
Picture |
Bass |
Acoustic Fretted |
Ibanez AEB10E Acoustic-Electric Bass Guitar with Onboard Tuner |
350.00 |
Picture |
Drums |
World Percussion |
Latin Percussion Conga 3-Pack with Bongos |
595.95 |
Picture |
Keyboards |
Synthesizers |
Roland JUNO-D 61-Key Synthesizer |
595.95 |
Picture |
Drums |
World Percussion |
Latin Percussion Aspire Conga Set with Bongos and Stand |
425.50 |
Picture |
Recording |
Microphone |
AKG Perception 200 Condenser Microphone |
160.00 |
Picture |
|
|
|
|
|
- Create a few customers' orders and click Save then New Order each
time. Here are examples:
- Close the form and return to your programming environment
|
|