C# XML Application: Solo Music Store
C# XML Application: Solo Music Store
Introduction
There are many options to create a database. One of the most basic options is a text-based repository. Even then, you have many options, such as JSON. A good solution for a database application is to create it as XML. The .NET Framework supports XML through various classes. These classes allow you to create a fully functional database application.
Practical Learning: Starting the Project
A Store Item
A database is made of objects. For our application, a store item is an object that identifies the main object of the business. We will use a form in which the user can type or select the neessary parts of a store item.
Practical Learning: Creating a Store Item
Control | (Name) | Text | Other Properties | |
Label | &Item #: | |||
Text Box | txtItemNumber | |||
Label | C&tegory: | |||
Combo Box | cbxCategories | |||
Button | btnNewCategory | N&ew | ||
Label | S&ub-Ctegory: | |||
Combo Box | cbxSubCategories | |||
Button | btnNewSubCategory | Ne&w | ||
Label | Item &Name: | |||
Text Box | txtItemNumber | ScrollBars: Vertical Multiline: True |
||
Label | &Unit Price: | |||
Text Box | txtUnitPrice | |||
Label | ________________________________ | |||
Button | btnSaveStoreItem | Sa&ve Store Item | ||
Button | btnClose | &Close |
using System.Xml; namespace SoloMusicStore { public partial class StoreItemNew : Form { public StoreItemNew() { InitializeComponent(); } private void InitializeStoreItem() { // Initialize the XML DOM XmlDocument xdStoreItems = new XmlDocument(); // Identify the file that contains the records for this project string strFileName = @"C:\Solo Music Store\StoreItems.xml"; // If that file was already created, ... if (File.Exists(strFileName)) { // (before going any further, reset the controls on the form) cbxCategories.Items.Clear(); cbxSubCategories.Items.Clear(); txtItemName.Text = string.Empty; txtUnitPrice.Text = string.Empty; txtItemNumber.Text = string.Empty; // open the file and put its records in the XML DOM xdStoreItems.Load(strFileName); // Get a list of nodes that are named "category". XmlNodeList xnlCategories = xdStoreItems.DocumentElement!.GetElementsByTagName("category"); // Visit each node foreach (XmlNode xnCategory in xnlCategories) { /* If the value of that node is already in the Categories combo box, * don't add it. If that value is not yet in the combo box, add it. */ if (!cbxCategories.Items.Contains(xnCategory.FirstChild!.InnerText)) cbxCategories.Items.Add(xnCategory.FirstChild.InnerText); } // At this time, no real item has been selected. Therefore, display the default picture pbxSelectedItem.Image = Image.FromFile(@"C:\Solo Music Store\Generic.png"); /* Every time throughout this project, we will resize the form * to display the complete picture of a store item. */ Width = pbxSelectedItem.Right + 40; Height = pbxSelectedItem.Bottom + 75; } } private void StoreItemNew_Load(object sender, EventArgs e) { InitializeStoreItem(); } private void txtItemNumber_Leave(object sender, EventArgs e) { if(string.IsNullOrEmpty(txtItemNumber.Text)) return; if (File.Exists(@"C:\Solo Music Store\" + txtItemNumber.Text + ".png")) pbxSelectedItem.Image = Image.FromFile(@"C:\Solo Music Store\" + txtItemNumber.Text + ".png"); else pbxSelectedItem.Image = Image.FromFile(@"C:\Solo Music Store\Generic.png"); Width = pbxSelectedItem.Right + 40; Height = pbxSelectedItem.Bottom + 75; } private void cbxCategories_SelectedIndexChanged(object sender, EventArgs e) { XmlDocument xdStoreItems = new XmlDocument(); string strFileName = @"C:\Solo Music Store\StoreItems.xml"; if (File.Exists(strFileName)) { xdStoreItems.Load(strFileName); XmlElement xeStoreItem = xdStoreItems.DocumentElement!; XmlNodeList xnlCategories = xeStoreItem.GetElementsByTagName("category"); cbxSubCategories.Text = ""; cbxSubCategories.Items.Clear(); // Display the sub-categories in the combo box foreach (XmlNode xnCategory in xnlCategories) { // Get only the sub-categories of the selected category if (xnCategory.InnerText == cbxCategories.Text) { if (!cbxSubCategories.Items.Contains(xnCategory.NextSibling!.InnerText)) cbxSubCategories.Items.Add(xnCategory.NextSibling.InnerText); } } } } private void btnNewCategory_Click(object sender, EventArgs e) { Category editor = new Category(); if (editor.ShowDialog() == DialogResult.OK) { if (!string.IsNullOrEmpty(editor.txtCategory.Text)) { string strCategory = editor.txtCategory.Text; // Make sure the category is not yet in the list if (cbxCategories.Items.Contains(strCategory)) { MessageBox.Show(strCategory + " is already in the list.", "Solo Music Store", MessageBoxButtons.OK, MessageBoxIcon.Information); } else { // Since this is a new category, add it to the combox box cbxCategories.Items.Add(strCategory); // Just in case the user wanted to use this new category // select it cbxCategories.Text = strCategory; } } } } private void btnNewSubCategory_Click(object sender, EventArgs e) { SubCategory editor = new(); if (editor.ShowDialog() == DialogResult.OK) { if (!string.IsNullOrEmpty(editor.txtSubCategory.Text)) { string strSubCategory = editor.txtSubCategory.Text; if (cbxSubCategories.Items.Contains(strSubCategory)) { MessageBox.Show(strSubCategory + " exists already.", "Solo Music Store", MessageBoxButtons.OK, MessageBoxIcon.Information); } else { cbxSubCategories.Items.Add(strSubCategory); cbxSubCategories.Text = strSubCategory; } } } } private void btnSaveStoreItem_Click(object sender, EventArgs e) { XmlDocument xdStoreItems = new XmlDocument(); string strFileName = @"C:\Solo Music Store\StoreItems.xml"; /* Make sure the user provides the item number, the category, the sub-category, * the name (or short description), and the price of the item. */ if( string.IsNullOrEmpty(txtItemNumber.Text) || string.IsNullOrEmpty(cbxCategories.Text) || string.IsNullOrEmpty(cbxSubCategories.Text) || string.IsNullOrEmpty(txtItemName.Text) ) { MessageBox.Show("You must provide all the information about the new item. " + "This includes the item number, its category, its sub-category, " + "its name (or short description), and its price.", "Solo Music Store", MessageBoxButtons.OK, MessageBoxIcon.Information); return; } // Get the values that were provided for the new store item int itemNumber = int.Parse(txtItemNumber.Text); string category = cbxCategories.Text.Replace("&", "&"); string subCategory = cbxSubCategories.Text.Replace("&", "&"); string itemName = txtItemName.Text.Replace("&", "&"); double unitPrice = double.Parse(txtUnitPrice.Text); /* Find out if the file exists already. * If it doesn't, then create it. */ if (!File.Exists(strFileName)) { xdStoreItems.LoadXml("<?xml version=\"1.0\" encoding=\"utf-8\"?>" + "<store-items></store-items>"); xdStoreItems.Save(strFileName); } // Open the XML file of the store items xdStoreItems.Load(strFileName); /* We will use this variable to find out whether the category * being added exists already in the Store Items document. */ bool categoryFound = false; // Get all the store items that have a Category node XmlNodeList xnlCategories = xdStoreItems.DocumentElement!.GetElementsByTagName("category"); // Since we will create a new store item, let's initialize its new node XmlElement xeStoreItem = xdStoreItems.CreateElement("store-item"); xeStoreItem.InnerXml = "<item-number>" + itemNumber + "</item-number>" + "<category>" + category + "</category>" + "<sub-category>" + subCategory + "</sub-category>" + "<item-name>" + itemName + "</item-name>" + "<unit-price>" + unitPrice + "</unit-price>"; // Check each store item foreach (XmlNode xnCategory in xnlCategories) { // If you find the same category, ... if (xnCategory.InnerText == category) { /* Now that we found a category, check the categories. * If you find the same sub-category, ... */ if (xnCategory.NextSibling!.InnerText == subCategory) { /* Now that we have the same sub-category, compare it to the current sub-category. * If the current sub-category alphabetically comes before the sub-category * of the new store item, insert the new one before the existing one */ if (string.Compare(xnCategory.InnerText, category) < 0) xdStoreItems.DocumentElement.InsertBefore(xeStoreItem, xnCategory.ParentNode); else // Otherwise, add it after xdStoreItems.DocumentElement.InsertAfter(xeStoreItem, xnCategory.ParentNode); } else { /* If the new sub-category was not found in the document, compare its item number * to that of the existing store item. * If the item number of the existing store item is higher than that of * the new store item, add the new store item before the existing one */ if (int.Parse(xnCategory.PreviousSibling!.InnerText) > itemNumber) xdStoreItems.DocumentElement.InsertBefore(xeStoreItem, xnCategory.ParentNode); else // Otherwise, add it after xdStoreItems.DocumentElement.InsertAfter(xeStoreItem, xnCategory.ParentNode); } categoryFound = true; break; } } // If the new category was not found, ... if (categoryFound == false) { /* If there are already five store items in the document, * add the new one as the first */ if (xdStoreItems.ChildNodes.Count < 5) xdStoreItems.DocumentElement.PrependChild(xeStoreItem); else // Otherwise, add the new store item the the last element xdStoreItems.DocumentElement.AppendChild(xeStoreItem); } // Now the the new store item has been added or inserted, save the XML file xdStoreItems.Save(strFileName); InitializeStoreItem(); } private void btnClose_Click(object sender, EventArgs e) { Close(); } } }
Editing or Updating a Store Item
Once you have created some records for a database, some time to time, you may need to change some or more records. We will provide a form to do that.
Practical Learning: Updating a Record
Control | (Name) | Text | |
Button | btnFind | &Find | |
Button | btnUpdateStoreItem | Up&date Store Item |
using System.Xml; namespace SoloMusicStore { public partial class StoreItemEditor : Form { public StoreItemEditor() { InitializeComponent(); } private void InitializeStoreItem() { XmlDocument xdStoreItems = new XmlDocument(); string strFileName = @"C:\Solo Music Store\StoreItems.xml"; if (File.Exists(strFileName)) { cbxCategories.Items.Clear(); cbxSubCategories.Items.Clear(); txtItemName.Text = string.Empty; txtUnitPrice.Text = string.Empty; txtItemNumber.Text = string.Empty; xdStoreItems.Load(strFileName); XmlNodeList xnlCategories = xdStoreItems.DocumentElement!.GetElementsByTagName("category"); foreach (XmlNode xnCategory in xnlCategories) { if (!cbxCategories.Items.Contains(xnCategory.FirstChild!.InnerText)) cbxCategories.Items.Add(xnCategory.FirstChild.InnerText); } pbxSelectedItem.Image = Image.FromFile(@"C:\Solo Music Store\Generic.png"); Width = pbxSelectedItem.Right + 40; Height = pbxSelectedItem.Bottom + 75; } } private void StoreItemEditor_Load(object sender, EventArgs e) { InitializeStoreItem(); } private void btnFind_Click(object sender, EventArgs e) { if (string.IsNullOrEmpty(txtItemNumber.Text)) { MessageBox.Show("You must enter a store item number.", "Solo Music Store", MessageBoxButtons.OK, MessageBoxIcon.Information); return; } bool storeItemFound = false; XmlDocument xdStoreItems = new XmlDocument(); string strFileName = @"C:\Solo Music Store\StoreItems.xml"; string strPictureFile = @"C:\Solo Music Store\" + txtItemNumber.Text + ".png"; if (File.Exists(strFileName)) { xdStoreItems.Load(strFileName); XmlElement xeStoreItem = xdStoreItems.DocumentElement!; XmlNodeList xnlStoreItems = xeStoreItem.GetElementsByTagName("item-number"); // Check each store item foreach (XmlNode xnStoreItem in xnlStoreItems) { // Check the item number of each store item if (xnStoreItem.InnerText == txtItemNumber.Text) { // If you find the store item, display its values in the controls cbxCategories.Text = xnStoreItem?.NextSibling?.InnerText; cbxSubCategories.Text = xnStoreItem?.NextSibling?.NextSibling?.InnerText; txtItemName.Text = xnStoreItem?.NextSibling?.NextSibling?.NextSibling?.InnerText; txtUnitPrice.Text = xnStoreItem?.NextSibling?.NextSibling?.NextSibling?.NextSibling?.InnerText; if (File.Exists(strPictureFile)) pbxSelectedItem.Image = Image.FromFile(strPictureFile); else pbxSelectedItem.Image = Image.FromFile(@"C:\Solo Music Store\Generic.png"); Width = pbxSelectedItem.Right + 40; Height = pbxSelectedItem.Bottom + 75; storeItemFound = true; break; } } } if (storeItemFound == false) { MessageBox.Show("There is no store item with that number.", "Solo Music Store", MessageBoxButtons.OK, MessageBoxIcon.Information); } } private void cbxCategories_SelectedIndexChanged(object sender, EventArgs e) { XmlDocument xdStoreItems = new XmlDocument(); string strFileName = @"C:\Solo Music Store\StoreItems.xml"; if (File.Exists(strFileName)) { xdStoreItems.Load(strFileName); XmlElement xeStoreItem = xdStoreItems.DocumentElement!; XmlNodeList xnlCategories = xeStoreItem.GetElementsByTagName("category"); cbxSubCategories.Text = ""; cbxSubCategories.Items.Clear(); // Display the sub-categories in the combo box foreach (XmlNode xnCategory in xnlCategories) { // Get only the sub-categories of the selected category if (xnCategory.InnerText == cbxCategories.Text) { if (!cbxSubCategories.Items.Contains(xnCategory.NextSibling!.InnerText)) cbxSubCategories.Items.Add(xnCategory.NextSibling.InnerText); } } } } private void btnNewCategory_Click(object sender, EventArgs e) { Category editor = new Category(); if (editor.ShowDialog() == DialogResult.OK) { if (!string.IsNullOrEmpty(editor.txtCategory.Text)) { string strCategory = editor.txtCategory.Text; // Make sure the category is not yet in the list if (cbxCategories.Items.Contains(strCategory)) { MessageBox.Show(strCategory + " is already in the list.", "Solo Music Store", MessageBoxButtons.OK, MessageBoxIcon.Information); } else { // Since this is a new category, add it to the combox box cbxCategories.Items.Add(strCategory); // Just in case the user wanted to use this new category // select it cbxCategories.Text = strCategory; } } } } private void btnNewSubCategory_Click(object sender, EventArgs e) { SubCategory editor = new(); if (editor.ShowDialog() == DialogResult.OK) { if (!string.IsNullOrEmpty(editor.txtSubCategory.Text)) { string strSubCategory = editor.txtSubCategory.Text; if (cbxSubCategories.Items.Contains(strSubCategory)) { MessageBox.Show(strSubCategory + " exists already.", "Solo Music Store", MessageBoxButtons.OK, MessageBoxIcon.Information); } else { cbxSubCategories.Items.Add(strSubCategory); cbxSubCategories.Text = strSubCategory; } } } } private void btnUpdateStoreItem_Click(object sender, EventArgs e) { int itemNumber; double unitPrice; string category, subCategory, itemName; XmlDocument xdStoreItems = new XmlDocument(); string strFileName = @"C:\Solo Music Store\StoreItems.xml"; if( string.IsNullOrEmpty(txtItemNumber.Text) | string.IsNullOrEmpty(cbxCategories.Text) | string.IsNullOrEmpty(cbxSubCategories.Text) | string.IsNullOrEmpty(txtItemName.Text)) { MessageBox.Show("You must provide all the information about the store item to be updated.", "Solo Music Store", MessageBoxButtons.OK, MessageBoxIcon.Information); return; } // Get the values that were provided for the new store item itemNumber = int.Parse(txtItemNumber.Text); category = cbxCategories.Text.Replace("&", "&"); ; subCategory = cbxSubCategories.Text.Replace("&", "&"); ; itemName = txtItemName.Text.Replace("&", "&"); ; unitPrice = double.Parse(txtUnitPrice.Text); // Find out if the file exists already // If it doesn't, then create it if(!File.Exists(strFileName)) { MessageBox.Show("There is no store items inventory to update.", "Solo Music Store", MessageBoxButtons.OK, MessageBoxIcon.Information); return; } // Open the XML file of the store items xdStoreItems.Load(strFileName); // Get all the store items that have a Category node XmlNodeList xnlItemNumbers = xdStoreItems.DocumentElement!.GetElementsByTagName("item-number"); // Since we will create a new store item, let's initialize its new node XmlElement xeStoreItem = xdStoreItems.CreateElement("store-item"); xeStoreItem.InnerXml = "<item-number>" + itemNumber + "</item-number>" + "<category>" + category + "</category>" + "<sub-category>" + subCategory + "</sub-category>" + "<item-name>" + itemName + "</item-name>" + "<unit-price>" + unitPrice + "</unit-price>"; // Check each store item foreach (XmlNode xnStoreItem in xnlItemNumbers) { // If you find the same item number, ... if (int.Parse(xnStoreItem.InnerText) == itemNumber) { xdStoreItems.DocumentElement.ReplaceChild(xeStoreItem, xnStoreItem.ParentNode!); break; } } // Now the the new store item has been added or inserted, save the XML file xdStoreItems.Save(strFileName); InitializeStoreItem(); } private void btnClose_Click(object sender, EventArgs e) { Close(); } } }
Deleting a Store Item
In your application, if you have a record you don't need anymore, you can remove it. We will provide a form to support this operation.
Practical Learning: Updating a Record
Control | (Name) | Text | |
Text Box | txtCategory | ||
Text Box | txtSubCategory | ||
Button | btnDeleteStoreItem | &Delete Store Item |
using System.Xml; namespace SoloMusicStore { public partial class StoreItemDelete : Form { public StoreItemDelete() { InitializeComponent(); } private void InitializeStoreItem() { txtCategory.Text = string.Empty; txtSubCategory.Text = string.Empty; txtItemName.Text = string.Empty; txtUnitPrice.Text = string.Empty; txtItemNumber.Text = string.Empty; pbxSelectedItem.Image = Image.FromFile(@"C:\Solo Music Store\Generic.png"); Width = pbxSelectedItem.Right + 40; Height = pbxSelectedItem.Bottom + 75; } private void StoreItemDelete_Load(object sender, EventArgs e) { InitializeStoreItem(); } private void btnFind_Click(object sender, EventArgs e) { if (string.IsNullOrEmpty(txtItemNumber.Text)) { MessageBox.Show("You must enter a store item number.", "Solo Music Store", MessageBoxButtons.OK, MessageBoxIcon.Information); return; } bool storeItemFound = false; XmlDocument xdStoreItems = new XmlDocument(); string strFileName = @"C:\Solo Music Store\StoreItems.xml"; string strPictureFile = @"C:\Solo Music Store\" + txtItemNumber.Text + ".png"; if (File.Exists(strFileName)) { xdStoreItems.Load(strFileName); XmlElement xeStoreItem = xdStoreItems.DocumentElement!; XmlNodeList xnlStoreItems = xeStoreItem.GetElementsByTagName("item-number"); // Check each store item foreach (XmlNode xnStoreItem in xnlStoreItems) { // Check the item number of each store item if (xnStoreItem.InnerText == txtItemNumber.Text) { // If you find the store item, display its values in the controls txtCategory.Text = xnStoreItem?.NextSibling?.InnerText; txtSubCategory.Text = xnStoreItem?.NextSibling?.NextSibling?.InnerText; txtItemName.Text = xnStoreItem?.NextSibling?.NextSibling?.NextSibling?.InnerText; txtUnitPrice.Text = xnStoreItem?.NextSibling?.NextSibling?.NextSibling?.NextSibling?.InnerText; if (File.Exists(strPictureFile)) pbxSelectedItem.Image = Image.FromFile(strPictureFile); else pbxSelectedItem.Image = Image.FromFile(@"C:\Solo Music Store\Generic.png"); Width = pbxSelectedItem.Right + 40; Height = pbxSelectedItem.Bottom + 75; storeItemFound = true; break; } } } if (storeItemFound == false) { MessageBox.Show("There is no store item with that number.", "Solo Music Store", MessageBoxButtons.OK, MessageBoxIcon.Information); } } private void btnDeleteStoreItem_Click(object sender, EventArgs e) { XmlDocument xdStoreItems = new XmlDocument(); string strFileName = @"C:\Solo Music Store\StoreItems.xml"; if( string.IsNullOrEmpty(txtItemNumber.Text) ) { MessageBox.Show("You must type the number of the store item you want to delete.", "Solo Music Store", MessageBoxButtons.OK, MessageBoxIcon.Information); return; } if (!File.Exists(strFileName)) { MessageBox.Show("There is no store items inventory to update.", "Solo Music Store", MessageBoxButtons.OK, MessageBoxIcon.Information); return; } // Open the XML file of the store items xdStoreItems.Load(strFileName); // Get all the store items that have a Category node XmlNodeList xnlItemNumbers = xdStoreItems.DocumentElement!.GetElementsByTagName("item-number"); // Check each store item foreach (XmlNode xnStoreItem in xnlItemNumbers) { // If you find the same item number, ... if (xnStoreItem.InnerText == txtItemNumber.Text) { if (MessageBox.Show("Are you sure you want to remove this item from the store inventory?", "Solo Music Store", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes) { xdStoreItems.DocumentElement.RemoveChild(xnStoreItem.ParentNode!); break; } } } // Now the the new store item has been added or inserted, save the XML file xdStoreItems.Save(strFileName); InitializeStoreItem(); } private void btnClose_Click(object sender, EventArgs e) { Close(); } } }
The Central Object of a Database
An application should have an object from which the user can select the operations to perform. For that purpose, we will use the first form that was created in the project.
Practical Learning: Using the Central Form of the Project
Control | (Name) | Text | Other Properties | |||||||||||||||||
Label | Item Category | Font: Garamond, 14.25pt, style=Bold | ||||||||||||||||||
Label | Item Sub-Category | Font: Garamond, 14.25pt, style=Bold | ||||||||||||||||||
Label | Available Items | Font: Garamond, 14.25pt, style=Bold | ||||||||||||||||||
List Box | lbxCategories | Font: Garamond, 12pt, style=Bold | ||||||||||||||||||
List Box | lbxSubCategories | Font: Garamond, 12pt, style=Bold | ||||||||||||||||||
List View | lvwAvailableItems | Font: Garamond, 12pt
Columns
|
||||||||||||||||||
Picture Box | pbxSelectedItem | BorderStyle: Fixed3D SizeMode: AutoSize |
||||||||||||||||||
Button | btnNewStoreItem | New Store Item... | ||||||||||||||||||
Button | btnUpdateStoreItem | Update Store Item... | ||||||||||||||||||
Button | btnDeleteStoreItem | Delete Store Item... | ||||||||||||||||||
Button | btnClose | &Close |
using System.Xml; namespace SoloMusicStore { public partial class StoreInventory : Form { public StoreInventory() { InitializeComponent(); } // This function is used to reset the form when necessary private void InitializeStoreItems() { XmlDocument xdStoreItems = new XmlDocument(); string strFileName = @"C:\Solo Music Store\StoreItems41.xml"; // If a file for the records in this project was created already, ... if (File.Exists(strFileName)) { // before doing anything, reset/empty the list boxes and the list view. lbxCategories.Items.Clear(); lbxSubCategories.Items.Clear(); lvwAvailableItems.Items.Clear(); // Open the file that contains the records of this project, ... using (FileStream fsStoreItems = new FileStream(strFileName, FileMode.Open, FileAccess.Read)) // ... put those records in the XML DOM xdStoreItems.Load(fsStoreItems); // Get a reference to the XML DOM XmlElement xeStoreItem = xdStoreItems.DocumentElement!; // Get a list of all the nodes in the XML document XmlNodeList xnlStoreItems = xeStoreItem.ChildNodes; // Prepare toisplay the categories in the left list box for (int i = 0; i < xnlStoreItems.Count; i++) { // Make sure the list box doesn't yet have the category being added if (!lbxCategories.Items.Contains(xnlStoreItems[i]!["category"]!.InnerText)) lbxCategories.Items.Add(xnlStoreItems[i]!["category"]!.InnerText); } } /* Since the form is likely being reset, no store item is selected at this time. * Therefore, display the default picture of the store items. */ pbxSelectedItem.Image = Image.FromFile(@"C:\Solo Music Store\Generic.png"); /* Every time throughout this project, we will resize the form * to display the complete picture of a store item. */ Width = pbxSelectedItem.Right + 40; Height = pbxSelectedItem.Bottom + 75; } private void StoreInventory_Load(object sender, EventArgs e) { InitializeStoreItems(); } private void lbxCategories_SelectedIndexChanged(object sender, EventArgs e) { lbxSubCategories.Items.Clear(); lvwAvailableItems.Items.Clear(); XmlDocument xdStoreItems = new XmlDocument(); string strFileName = @"C:\Solo Music Store\StoreItems41.xml"; if (File.Exists(strFileName)) { xdStoreItems.Load(strFileName); XmlElement xeStoreItem = xdStoreItems.DocumentElement!; XmlNodeList xnlStoreItems = xeStoreItem.ChildNodes; // Display the sub-categories in the combo box for (int i = 0; i < xnlStoreItems.Count; i++) { // Get only the sub-categories of the selected category if (xnlStoreItems[i]?["category"]?.InnerText == lbxCategories.SelectedItem.ToString()) { if (!lbxSubCategories.Items.Contains(xnlStoreItems[i]!["sub-category"]!.InnerText)) lbxSubCategories.Items.Add(xnlStoreItems[i]!["sub-category"]!.InnerText); } } } } private void lbxSubCategories_SelectedIndexChanged(object sender, EventArgs e) { XmlDocument xdStoreItems = new XmlDocument(); string strFileName = @"C:\Solo Music Store\StoreItems41.xml"; /* When the user clicks an item in the sub-categories combo box, * remove everything in the list view because it is about to be populated. */ lvwAvailableItems.Items.Clear(); // Make sure the file that contains the store items was already created... if (File.Exists(strFileName)) { // ... It that's the case, open it and put its records in the XML DOM xdStoreItems.Load(strFileName); // Get a reference to the XML DOM XmlElement xeStoreItem = xdStoreItems.DocumentElement!; // Get a list of nodes named "sub-category" XmlNodeList xnlSubCategories = xeStoreItem.GetElementsByTagName("sub-category"); // Visit each "sub-category" node foreach (XmlNode xnSubCategory in xnlSubCategories) { /* If you find a "category" node (which is the node previous to the * selected "sub-category" node) whose value is the same as the selected Category, * and you find a "sub-category" node whose value is the same as the selected sub-category... */ if ( (xnSubCategory.PreviousSibling?.InnerText == lbxCategories.SelectedItem.ToString()) & (xnSubCategory.InnerText == lbxSubCategories.SelectedItem.ToString()) ) { // ... display the values of the corresponding item in the Available Store Items list view ListViewItem lviStoreItem = new ListViewItem(xnSubCategory?.PreviousSibling?.PreviousSibling?.InnerText); lviStoreItem.SubItems.Add(xnSubCategory?.NextSibling?.InnerText); lviStoreItem.SubItems.Add(double.Parse(xnSubCategory!.NextSibling!.NextSibling!.InnerText).ToString("F")); lvwAvailableItems.Items.Add(lviStoreItem); } } } } private void lvwAvailableItems_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e) { if (File.Exists(@"C:\Solo Music Store\" + e.Item.Text + ".png")) pbxSelectedItem.Image = Image.FromFile(@"C:\Solo Music Store\" + e.Item.Text + ".png"); else pbxSelectedItem.Image = Image.FromFile(@"C:\Solo Music Store\Generic.png"); Width = pbxSelectedItem.Right + 40; Height = pbxSelectedItem.Bottom + 75; } private void btnNewStoreItem_Click(object sender, EventArgs e) { // When the user clicks the New Store Item button, ... StoreItemNew sin = new StoreItemNew(); // display the corresponding form as a dialog box sin.ShowDialog(); // When the user has finished using the dialog box, reset the current form InitializeStoreItems(); } private void btnUpdateStoreItem_Click(object sender, EventArgs e) { StoreItemEditor sie = new StoreItemEditor(); sie.ShowDialog(); InitializeStoreItems(); } private void btnDeleteStoreItem_Click(object sender, EventArgs e) { StoreItemDelete sid = new StoreItemDelete(); sid.ShowDialog(); InitializeStoreItems(); } private void btnClose_Click(object sender, EventArgs e) { Close(); } } }
Executing and Testing the Application
After creating the project, you can test it with sample values and operations
Practical Learning: Executing and Testing the Application
Item # | Category | Sub-Category | Item Name | Unit Price |
759240 | Guitars | Electric | EART E-335 6 String Semi-Hollow-Body Electric Guitar, Stainless Steel Frets | 444.86 |
184920 | Band & Orchestra | Violins | Mendini By Cecilio Violin - MV500+92D - Size 4/4 (Full Size), Black Solid Wood - Flamed, 1-Piece Violins w/Case, Tuner, Shoulder Rest, Bow, Rosin, Bridge & Strings | 164.82 |
824083 | Keyboards | Synthesizers | Yamaha MX88 88-Key Weighted Action Synthesizer | 1224.74 |
302805 | Amplifiers & Effects | Guitar & Bass Amplifiers | Fender Rumble 25 V3 Bass Amplifier | 124.95 |
517279 | Drum Sets | Acoustic | Rise by Sawtooth Full Size 5-Piece Student Drum Set with Hardware and Cymbals, Pitch Black | 426.92 |
729704 | Keyboards | Digital Pianos | LAGRIMA Digital Piano with Bench, 88 Key Electric Piano for Beginner/Adults with Padded Piano Bench+Music Stand+Power Adapter+3-Pedal Board+Instruction Book+Headphone Jack | 379.37 |
828384 | Concert Percussion | Xylophones | Voodans 32 Note Xylophone Professional Wooden Glockenspiel Xylophone with Mallet and Adjustable Stand | 247.68 |
280483 | Guitars | Bass | Ibanez 4 String Bass Guitar, Right Handed, Black | 234.95 |
926082 | Wind & Woodwind Instruments | Clarinets | Glory GLY-PBK Professional Ebonite Bb Clarinet with 10 Reeds, Stand, Hard Case, Cleaning Cloth, Cork Grease, Mouthpiece Brush and Pad Brush, Black | 164.69 |
420304 | Keyboards | Synthesizers | Yamaha MX49 Music Production Synthesizer, Black | 555.55 |
695381 | Guitars | Acoustic | YAMAHA FG800 Solid Top Acoustic Guitar | 234.97 |
828479 | Wind & Woodwind Instruments | Clarinets | Wilmington Clarinet | 442.94 |
329374 | Keyboards | Synthesizers | Roland JD-XI 37-Key Interactive Analog/Digital Crossover Synthesizer, Black | 626.84 |
148048 | Band & Orchestra | Saxophones | E Flat Alto Saxophone | 495.95 |
649273 | Drum Sets | Electric | Alesis Drums Surge Mesh Kit - Electric Drum Set with USB MIDI Connectivity, Mesh Heads, Solid Rack and Drum Module Including 40 Kits and 385 Sounds | 617.82 |
302830 | Keyboards | Digital Pianos | ZHRUNS Digital Piano,88 Heavy Hammer Piano Keys with Touch Response Electric Keyboard Piano/Music Stand+Power Adapter+3 Metal Pedals+Instruction Book,Headphone Jack/MIDI Input/Outputp | 578.95 |
937304 | Guitars | Bass | Ibanez SR Premium 4-String Electric Bass Guitar (Right-Hand, Magic Wave Low Gloss) | 1428.88 |
492947 | Band & Orchestra | Flutes | SLADE Closed Hole C Flute with Gloves, Tuning Rod, Carrying Case, Joint Grease and Cleaning Kit, 16 Key Student Flute Nickel plated flute, Beginner Flute in Band & Orchestra, Silver | 124.86 |
408384 | Keyboards | Digital Pianos | Kawai ES110 88-Key Portable Digital Piano, Stylish Black, Bundle with H&A Monitor Headphones & H&A Keyboard Stand Bench Pedal | 721.62 |
688047 | Concert Percussion | Xylophones | TNZMART 32 Key Xylophone Set with Adjustable Stand Wooden Glockenspiel Percussion | 244.47 |
384083 | Guitars | Electric | Guild Guitars Starfire I DC Semi-Hollow Body Electric Guitar, Vintage Walnut, Double-Cut | 555.75 |
179274 | Keyboards | Digital Pianos | Yamaha P-45 Compact 88-Key Portable Digital Piano + Keyboard Stand + Keyboard Bench + Keyboard Pedal + Studio Monitor Headphones | 598.98 |
849684 | Drum Sets | Acoustic | Ashthorpe 5-Piece Complete Full Size Adult Drum Set with Remo Batter Heads - Silver | 386.64 |
505840 | Band & Orchestra | Mandolins | Donner A Style Mandolin Instrument Sunburst Beginner Adult Acoustic Mandolin Musical Instrument Mahogany 8 String, Bundle With Tuner String Bag Guitar Picks,DML-1 | 128.86 |
593577 | Keyboards | Digital Pianos | ZHRUNS Digital Piano,88 Heavy Hammer Piano Keys with Touch Response Electric Keyboard Piano/Music Stand+Power Adapter+3 Metal Pedals+Instruction Book,Headphone Jack/MIDI Input/Outputp | 579.93 |
300530 | Guitars | Acoustic | Donner 39 Inch Classical Guitar Full Size Brown Acoustic Guitar Beginner Bundle Kit Spruce Mahogany with Gig Bag Nylon Strings Capo Tuner | 154.55 |
184028 | Band & Orchestra | Saxophones | YAMAHA YAS-280 Saxophones | 1255.85 |
538508 | Keyboards | Synthesizers | Roland SYSTEM-8 PLUG-OUT Synthesizer, 49-key | 1828.66 |
257208 | Drum Sets | Electric | Donner Electronic Drum Kit Adult with 5 Drums 4 Cymbals, 225 Sounds,Audio Line/Drum Stick | 422.82 |
927948 | Keyboards | Digital Pianos | Donner DDP-100 88-Key Weighted Action Digital Piano, Beginner Bundle with Furniture Stand, Power Adapter, Triple Pedals, MP3 Function | 605.05 |
|
|||
Home | Copyright © 2001-2022, C# Key | Wednesday 08 December 2022 | Home |
|