View RSS Feed

leokoach

My C# Study Application with XML file

Rate this Entry
by , 03-10-2010 at 01:21 AM (1083 Views)
It has been about a week I am changing my latest code so it would use XML file as a database instead of Access Database. Why? Because I just got a laptop, which came with 64 bit Win 7. Somehow jet DB engine didn't like the new machine and OS... I checked around for the problem and there are some fixes and fix-arounds... I justs didn't want to deal with it more than I had to, so I decided to use XML as the program database.

Access database, ADODB connection code is much easier for me, since I had experiences in the past. One thing I don't like is to "bound" databases to controls on my applications. I like more freedom connecting to a database, not depending on automated ties and stuff. I like the SQL express edition, but again, it doesn't have the freedom I like to get. These days OS security settings bit more difficult to untie, and that probably is the biggest downsize of my approach, besides writing more code.

Ok, now let's talk about my C# program 'CodeDatabase' a little bit...

It's a very small, simple program. I have three fields that I keep in an XML file. ID, Code subject and main code. Program lets me search the subject field using wild-card option as default. I used text box for the main code viewer and ListView with 'Details' mode for my Code Subjects. I used two columns there. One to hide my ID field, and the other Code Subject name.

Code I am posting here could also be a good source for people who are starting C# and want to learn more about XML files. There are... creating a new XML file, editing an XML file, appending records into XML file, deleting records from an XML file and searching an XML file options included.

It is my study application. I am new in C# although not new in coding world. I had some gaps during 25 years, but I am getting there and catching up a little more everyday.

Following are my C# codes. It could be useful to put them here naked, to show to the other C# programmer. I am pretty sure most of the C# programmers will find many things wrong with the code, and I am open to suggestions, ideas, critiques etc.

(Please forgive my spelling and grammar errors here and in my code's comments... English is not my native language and I basically learned just using it in daily life, nothing more.)

Code:
********************************************************

Main Form Class

Code 1 of 4

********************************************************
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace CodeDatabase
{
    public partial class frmMain : Form
    {
        public frmMain()
        {
            // Form Main Constructor
            InitializeComponent();
        }

        private void GetSettings() // Method that gets the settings
                                   // from 'app.ini' file if exist.
        {
            IOFile clsIO = new IOFile(); // Create instance of IOFile class

                if (clsIO.ErrHap != null) // 'ErrHap' is "Error Happened" bool sent by clsIO object
                {
                    EnableDisableButtons(false); // A private method to enable or
                                                 //desable some controls on the form

                }
                else
                {
                    // Set some of the control values
                    if (clsIO.onTopOption == "1")
                    { chkOnTop.Checked = true; }
                    else { chkOnTop.Checked = false; }

                    if (clsIO.WrapOption == "1")
                    {
                        TSWrap.Checked = true;
                        txtCodeMain.ScrollBars = ScrollBars.Vertical;
                        txtCodeMain.WordWrap = true;
                    }
                    else
                    {
                        TSWrap.Checked = false;
                        txtCodeMain.ScrollBars = ScrollBars.Both;
                        txtCodeMain.WordWrap = false;
                    }
                    EnableDisableButtons(true);
                }
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            GetSettings(); // A private method to set some of the control values on the form

            #region ToolTips
            // Set some tooltips here
            _toolTip.SetToolTip(btnCopy, "Copy to ClipBoard");
            _toolTip.SetToolTip(btnNew, "Add new code with this subject");
            _toolTip.SetToolTip(btnExit, "Exit program");
            _toolTip.SetToolTip(lstSubjects, "Click to see the code");
            _toolTip.SetToolTip(chkOnTop, "Check to keep this window top of all windows");
            _toolTip.SetToolTip(btnSearch, "Search DB");
            _toolTip.SetToolTip(txtCodeMain, "Double Click to copy code into clipboard");
            #endregion

            // Resize the form using current screen size
            this.Width = Screen.PrimaryScreen.Bounds.Width / 2;
            this.Height = Screen.PrimaryScreen.Bounds.Height - 300;

            if (btnNew.Enabled == true) // If 'new' button desabled, that means 'app.ini' file is missing
                                        // or never creaated (first run)
            {
                FillSubjectList("*"); // 'app.ini' is exist. Load data into form
            }
        }

        private void XMLCheck(string XMLCurrentLocation) // This method checks the path of the XML file
                                                         // It is important to have an xml file located or created
                                                         // before run the program very first time.
        {
            Scripting.FileSystemObject FsO = new Scripting.FileSystemObject(); // Create instance of FileSystemObject class

            if (FsO.FileExists(XMLCurrentLocation) == false)
            {
                if (MessageBox.Show("XML file is not exist!. Continue with settings?", "Missing XML",
                                    MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) == DialogResult.Yes)
                {
                    frmSettings OpenSettings = new frmSettings(); // Create instance of Settings form
                                                                  // and show as dialog form.
                    OpenSettings.ShowDialog();
                }
            }
        }

        private void FillSubjectList(string SearchWord) // This method fills the ListView object
                                                        // with all the code subjects or just selected
                                                        // subjects through the search box.
        {
            IOFile clsIO = new IOFile(); // Create instance ofIOFile class

            if (clsIO.ErrHap != null) // 'ErrHap' is "Error Happened bool sent by clsIO object
            {
                MessageBox.Show("Error while reading 'app.ini' file: " + clsIO.ErrHap, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                frmSettings OpenSettings = new frmSettings();// Create instance of Settings form
                                                             // and show as dialog form.
                OpenSettings.ShowDialog();
                return;
            }
            else
            {
                // Reset some controls
                lstSubjects.Items.Clear(); // Clear ListView
                txtCodeMain.Text = "CODE VIEW"; // Put default text to main code viewer
                txtSubject.Text = ""; // Clear Subject/Search box
                lblSelected.Text = ""; // Clear Full Subject Name label

                XMLCheck(clsIO.XMLPath); // Check the path of the XML file
            }

            XMLDatabase clsXML = new XMLDatabase(); // Create instance of XMLDatabase class
            ArrayList CurrentSubjectList = new ArrayList(); // Create instance of ArrayList
                                                            // This will loaded with the ArrayList
                                                            // sent by clsXML object
            string[] SplitText = new string[2]; // Each item in the array will contain a tring
                                                // that will be splited by 'Backspace' character

            CurrentSubjectList = clsXML.GetSubjectList(clsIO.XMLPath, SearchWord); // Get the ArrayList from clsXML
            char Splitchr = (char)8; // 'char 8' is Backspace character.

            foreach (string FullString in CurrentSubjectList) // Start looping the ArrayList
            {
                SplitText = FullString.Split(Splitchr); // Split Item
                ListViewItem s_Items; // Set ListView item to add new information
                s_Items = lstSubjects.Items.Add(SplitText[0]); // Add Subject ID to the first (not visiable) colomn
                s_Items.SubItems.Add(SplitText[1]); // Add Subjectname to second (visiable) colomn
            }
        }

        private void ExitApp()
        {
            if (btnNew.Enabled == true)
                // Check if 'Auto Save' option is checked and if 'app.ini' file exist
            {
                // Before we save the setting file, we need to know
                // what are the current settings and DB path value

                IOFile clsIO = new IOFile(); // Create instance of IOFile class

                if (clsIO.ErrHap != null) // 'ErrHap' is "Error Happened" bool sent by clsIO object
                {
                    // Just show an error message, but do nothing else
                    MessageBox.Show("Error while reading 'app.ini' file: " + clsIO.ErrHap, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    if (clsIO.AutoSave == "1")
                    {
                        // Set default values in clsIO object
                        clsIO.onTopOption = "0";
                        clsIO.WrapOption = "0";
                        clsIO.AutoSave = "0";

                        // Then reset the values that are changed during use of the application
                        // By setting above settings to default made coding lesser when set them back here
                        if (chkOnTop.Checked == true)
                        { clsIO.onTopOption = "1"; }

                        if (TSWrap.Checked == true)
                        { clsIO.WrapOption = "1"; }

                        clsIO.createINIFile(); // Creating 'app.ini' file overwrites the older one
                        // with the new settings information
                    }
                }
            }

            // Exit the program
            if (Application.MessageLoop)
            {
                // Use this since we are a WinForms app
                Application.Exit();
            }
            else
            {
                // Use this since we are a console app
                Environment.Exit(1);
            }
        }

        private void EnableDisableButtons(bool EDButtons) // Change some of the control states here
        {
            // Menu items
            TSAddNew.Enabled = EDButtons;
            TSEdit.Enabled = EDButtons;
            TSDelete.Enabled = EDButtons;
            TSRefresh.Enabled = EDButtons;
            
            // Buttons
            btnSearch.Enabled = EDButtons;
            btnNew.Enabled = EDButtons;
            btnEdit.Enabled = EDButtons;
            btnDelete.Enabled = EDButtons;

            // Main codeview
            txtCodeMain.Enabled = EDButtons;
            txtSubject.Enabled = EDButtons;
        }
        
        private void GetMainCodeForSelectedListItem(int lineIndex) // This method fills the Main Code window
                                                                   // with the code for selected ListView item
        {
                IOFile clsIO = new IOFile(); // Create instance of IOFile class

                if (clsIO.ErrHap != null) // 'ErrHap' is "Error Happened" bool sent by clsIO object
                {
                    MessageBox.Show("Error while reading 'app.ini' file: " + clsIO.ErrHap, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    frmSettings OpenSettings = new frmSettings();
                    OpenSettings.ShowDialog();
                    // No response needed from the dialog box, since there is nothing else follwoing in this method
                }
                else
                {
                    XMLCheck(clsIO.XMLPath); // Check XML file path if the file exist

                    try
                    {
                        XMLDatabase clsXML = new XMLDatabase(); // Create instance of XMLDatabase class
                        txtCodeMain.Text = clsXML.XMLGetinfo(lstSubjects.Items[lineIndex].SubItems[0].Text, clsIO.XMLPath);
                    }
                    catch (Exception exc)
                    {
                        MessageBox.Show("Error while getting main code! : " + exc.Message,"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        // Returned error from clsXML object
                    }

                    lblSelected.Text = lstSubjects.Items[lineIndex].SubItems[1].Text; // Full subject on the label

                    txtCodeMain.ForeColor = Color.Black; // Change the text color to black in main code view
                }

        }

        private void lstSubjects_SelectedIndexChanged(object sender, EventArgs e)
        {
            // Aparently this fires twice. Check if anything selected first
            // this will by-pass the empty round.
            if (lstSubjects.SelectedItems.Count > 0)
            {
                GetMainCodeForSelectedListItem(lstSubjects.SelectedIndices[0]);
            }
        }

        private void txtSubject_KeyPress(object sender, KeyPressEventArgs e)
        {
            // As soon as start typing into search box, clear the main codeview
            txtCodeMain.Text = "";
            lblSelected.Text = "";
        }

        private void txtCodeMain_DoubleClick(object sender, EventArgs e)
        {
            // Either double clicking on the main codeview or clicking
            // on the 'C' (Copy) button gets a copy of all the text in the main codeview.
            CopyAllMyText(true);
            txtCodeMain.Focus();
        }

        private void CopyAllMyText(bool blnSelectAll)
        {
            // Check to see if any text(s) selected in the TextBox control.
            // This way either selected text or all can be copied into clipboard
            if (txtCodeMain.SelectionLength == 0 || blnSelectAll == true)
            {
                // Select all text in the text box.
                txtCodeMain.SelectAll();
            }
            // Copy the contents of the control to the Clipboard.
            txtCodeMain.Copy();
        }
 
        private void chkOnTop_CheckedChanged(object sender, EventArgs e)
        {
            // Set the form 'always on top' if selected
            this.TopMost = chkOnTop.Checked;
        }

        private void txtCodeMain_TextChanged(object sender, EventArgs e)
        {
            // If any changes made to the text in the code view
            // change the text color to red to remind user to save
            // the edited version
            txtCodeMain.ForeColor = Color.Red;
        }

        #region BUTTONS

        private void btnSearch_Click(object sender, EventArgs e)
        {

            // Program does wild-card search by default
            // Put any word that you wish to find and listed
            FillSubjectList(txtSubject.Text);
        }

        private void btnCopy_Click(object sender, EventArgs e)
        {
            // 'Copy' button copies all text, or highligted text in the main code view.
            CopyAllMyText(false);
            txtCodeMain.Focus();
        }

        private void btnDelete_Click(object sender, EventArgs e)
        {
            DBWork("Delete");
        }

        private void btnEdit_Click(object sender, EventArgs e)
        {
            DBWork("Edit");
        }

        private void btnNew_Click(object sender, EventArgs e)
        {
            DBWork("New");
        }

        private void btnExit_Click(object sender, EventArgs e)
        {
            ExitApp();
        }

        #endregion


        #region MENU ITEMS

        private void TSAddNew_Click(object sender, EventArgs e)
        {
            DBWork("New");
        }

        private void TSEdit_Click(object sender, EventArgs e)
        {
            DBWork("Edit");
        }

        private void TSDelete_Click(object sender, EventArgs e)
        {
            DBWork("Delete");
        }

        private void TSWrap_Click(object sender, EventArgs e)
        {
            // With 'word wrap' option, we set a couple other things...
            if (TSWrap.Checked == false)
            {
                TSWrap.Checked = true;
                txtCodeMain.ScrollBars = ScrollBars.Vertical;
                txtCodeMain.WordWrap = true;
            }
            else
            {
                TSWrap.Checked = false;
                txtCodeMain.ScrollBars = ScrollBars.Both;
                txtCodeMain.WordWrap = false;
            }
        }

        private void TSRefresh_Click(object sender, EventArgs e)
        {
            // Send '*' to 'fillSubjectList' method for its 'SELECT' case
            // to load all the items in subject field (Refresh the list box)
            FillSubjectList("*");
        }

        private void TSExit_Click(object sender, EventArgs e)
        {
            ExitApp();
        }

        private void TSAbout_Click(object sender, EventArgs e)
        {
            // Set and show 'About' form. This form is a default 'About'
            // from the Visual Studio itself.
            AboutBox1 AboutBox = new AboutBox1();
            AboutBox.ShowDialog();
        }

        private void TSCodeDatabase_Click(object sender, EventArgs e)
        {
            Scripting.FileSystemObject FsO = new Scripting.FileSystemObject(); // Create instance of FileSystemObject class

            if (FsO.FileExists("help.rtf") == true)
            {
                System.Diagnostics.Process.Start("help.rtf"); // Open 'help.rtf' file if exist
            }
            else
            {
                MessageBox.Show("Missing help file (help.rtf).", "Help file", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
        }

        private void TSSettings_Click(object sender, EventArgs e)
        {
            string a1 = "0";
            string b1 = "0";
            string c1 = "0";

            // Set some of the variables that will pass to the settings form

            IOFile clsIO = new IOFile();
            if (clsIO.ErrHap == null)
            {
                if (chkOnTop.Checked == true)
                { a1 = "1"; }

                if (TSWrap.Checked == true)
                { b1 = "1"; }

                if (clsIO.AutoSave == "1") // there is no control on the form for the
                                           // 'AutoSave' option. Get it from clsIO
                { c1 = "1"; }
            }

            frmSettings OpenSettings = new frmSettings(a1, b1, c1);
            OpenSettings.ShowDialog();
            GetSettings();
            FillSubjectList("*");
        }

        #endregion

        private void DBWork(string DoThis)
        {
            string CurrentID = ""; // Current Subject ID set by the location of the listview's first field 'ID'.
            string LastSubjectID; // Sets the Subject ID for the next record
            string XMLCurrentPath; // Sets the latest recorded XML file path
            string EndMessage; // Sets the message string per selected action
            string MainCodeString = txtCodeMain.Text; // Main codeview text
            string SubjectString = txtSubject.Text; // Subject text
            MainCodeString = MainCodeString.Trim(); // Trim main code text
            SubjectString = SubjectString.Trim(); // Trim subject text

            IOFile clsIO = new IOFile(); // Create instance of 'IOFile' class

            if (clsIO.ErrHap != null) // 'ErrHap' is "Error Happened" bool sent by clsIO object
            {
                MessageBox.Show("Error while reading 'app.ini' file: " + clsIO.ErrHap, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                frmSettings OpenSettings = new frmSettings();
                OpenSettings.ShowDialog();
                return;
            }

            XMLCurrentPath = clsIO.XMLPath;

            // Set the next ID value
            XMLDatabase DBXml = new XMLDatabase(); // Create instance of XMLDatabase class
            LastSubjectID = DBXml.GetLatestID(XMLCurrentPath);

            if (DoThis == "Edit" || DoThis == "Delete")
            {
                if (lstSubjects.SelectedItems.Count == 0){ return; }
                CurrentID = lstSubjects.Items[lstSubjects.SelectedIndices[0]].SubItems[0].Text;
            }

            // Process request in this 'Switch' statment
            switch (DoThis)
            {
                case "New":
                    if (MainCodeString == "" || SubjectString == "")
                    {
                        MessageBox.Show("Please enter the code/subject before continue!", "Missing Info", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                        return;
                    }
                    DBXml.XMLwork(LastSubjectID, 'a', XMLCurrentPath, SubjectString, MainCodeString);
                    EndMessage = "New item added.";
                    break;
                case "Edit":
                    if (MainCodeString == "")
                    {
                        MessageBox.Show("Please enter the code before continue!", "Missing Info", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                        return;
                    }
                    DBXml.XMLwork(CurrentID, 'e', XMLCurrentPath, "", MainCodeString);
                    EndMessage = "Item edited.";
                    break;
                case "Delete":
                    if (MessageBox.Show("Are you sure about deleting this record?", "Delete current record", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
                    {
                        return;
                    }
                    DBXml.XMLwork(CurrentID, 'd', XMLCurrentPath, "", "");
                    EndMessage = "Item deleted.";
                    break;
                default:
                    return;
            }

            // Messagebox is necessary here to slow down the code for refresh
            MessageBox.Show(EndMessage, "Process done.", MessageBoxButtons.OK, MessageBoxIcon.Information);

            if (DoThis == "Edit")
            {
                txtCodeMain.ForeColor = Color.Black;
                lstSubjects.Focus();
            }
            else
            {
                // Refill
                FillSubjectList("*");
            }
        }
    }
}

********************************************************

Settings Form Class

Code 2 of 4

********************************************************
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace CodeDatabase
{
    public partial class frmSettings : Form
    {
        private string XMLDatabaseLocation = null;

        // Form Main Constructor
        public frmSettings()
        {
            InitializeComponent();
        }

        // Form Main Constructor overload
        public frmSettings(string OnTopStr, string WordWrapStr, string AutoSaveStr)
        {
            InitializeComponent();

            // Set some control values
            if (OnTopStr == "1")
            { chkOnTop.Checked = true; }

            if (WordWrapStr == "1")
            { chkWordWrap.Checked = true; }

            if (AutoSaveStr == "1")
            { chkAutoSave.Checked = true; }

            IOFile clsIO = new IOFile(); // Create instance of IOFile class

            if (clsIO.ErrHap == null)
            {
                Scripting.FileSystemObject FsO = new Scripting.FileSystemObject(); // Create instance of FileSystemObject class
                lblXML.Text = "XML File Name : " + FsO.GetFileName(clsIO.XMLPath); // XML file name into label box
                XMLDatabaseLocation = clsIO.XMLPath; // Set XML file path
            }
        }

        private void frmSettings_Load(object sender, EventArgs e)
        {
            this.TopMost = true; // Keep settings form on top of main form
        }

        private void btnLocateDB_Click(object sender, EventArgs e)
        {
            if (fleOpen.ShowDialog() == DialogResult.Cancel)
            { return; }
            XMLDatabaseLocation = fleOpen.FileName; // Set new location of the XML file
        }

        private void btnNewXML_Click(object sender, EventArgs e)
        {
            {
                string strNewLocation;
                Scripting.FileSystemObject FsO = new Scripting.FileSystemObject(); // Create instance of FileSystemObject class

                // If 'into program file' checked, just enter the name of XML file
                // otherwise, open 'Save' dialog box to create new xml file into
                // another location.
                if (chkSameFolder.Checked != true)
                {
                    if (fleSave.ShowDialog() == DialogResult.OK)
                    {
                        strNewLocation = fleSave.FileName;
                        lblXML.Text = FsO.GetFileName(fleSave.FileName);
                    }
                    else
                    {
                        return;
                    }
                }
                else
                {
                    strNewLocation = txtNewName.Text.Trim() + ".xml";
                    lblXML.Text = txtNewName.Text.Trim() + ".xml";
                }

                if (FsO.FileExists(fleSave.FileName) == true) // Make sure there are no other XML file with same name
                {
                    if (MessageBox.Show("This XML file is allready exist. Would you like to overwrite?", "File Exist",
                                                    MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) == DialogResult.Yes)
                    {
                        try
                        {
                            FsO.DeleteFile(strNewLocation, true); // Overwrite will delete the existing file
                        }
                        catch
                        {
                            // Sometime permission problems won't let program to delete files
                            MessageBox.Show("Can not create new XML!", "Write Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            return;
                        }
                    }
                    else
                    {
                        return;
                    }
                }

                XMLDatabaseLocation = strNewLocation;

                try
                {
                    XMLDatabase XMLDB = new XMLDatabase(); // Create instance of XMLDatabase class
                    XMLDB.XMLwork("", 'n', strNewLocation, "",""); // Create XML file
                    MessageBox.Show("New XML DB created succefuly");
                }
                catch
                {
                    MessageBox.Show("Error while writing new XML File!");
                }
            }
        }

        private void chkSameFolder_CheckedChanged(object sender, EventArgs e)
        {
            // Couple of control status need to change if 'Into same folder' option selected
            if (chkSameFolder.Checked == true)
            {
                btnNewXML.Enabled = false;
                txtNewName.Enabled = true;
            }
            else
            {
                btnNewXML.Enabled = true;
                txtNewName.Enabled = false;
                txtNewName.Text = "";
            } 
        }

        private void txtNewName_TextChanged(object sender, EventArgs e)
        {
            // Force user not to use buttons before something in the text box
            // In one condition only (Into same folder)

            if (txtNewName.Text.Trim() == "" && chkSameFolder.Checked == true)
            { btnNewXML.Enabled = false; }
            else
            { btnNewXML.Enabled = true; }
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            if (XMLDatabaseLocation == null) // Check if XML location variable has any value
            {
                MessageBox.Show("Select or create an XML file first.", "Missing XML path", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }

            IOFile clsIO = new IOFile(); // Create instance of IOFile class
            clsIO.ErrHap = null; // Ignore any error for now.

            // By calling 'BoolToString' method, set clsIO properties
            clsIO.onTopOption = BoolToString(chkOnTop.Checked);
            clsIO.WrapOption = BoolToString(chkWordWrap.Checked);
            clsIO.AutoSave = BoolToString(chkAutoSave.Checked);
            clsIO.XMLPath = XMLDatabaseLocation;

            clsIO.createINIFile(); // Create 'app.ini' file

            if (clsIO.ErrHap != null)
            {
                MessageBox.Show("Error while creating 'app.ini' file: " + clsIO.ErrHap
                                                            ,"Error",MessageBoxButtons.OK,MessageBoxIcon.Error);
            }
            else
            {
                MessageBox.Show("'app.ini' file create dsuccefuly",
                                                        "Success!",MessageBoxButtons.OK,MessageBoxIcon.Information);
            }
        }

        private string BoolToString(bool blnOption)
        {
            string strReturnValue = "0";
            if (blnOption == true)
            { strReturnValue = "1"; }
            return strReturnValue;
        }

        private void btnCloseApp_Click(object sender, EventArgs e)
        {
            this.Close(); // Close settings
        }
    }
}


********************************************************

IOFile Class (Custom class)

Code 3 of 4

********************************************************
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace CodeDatabase
{
    class IOFile
    {

        // Set fields
        private string _onTopOption;
        private string _WrapOption;
        private string _AutoSave;
        private string _XMLPath;
        private string _ErrHap = null;

        // Set properties
        public string onTopOption
        {
            get {return _onTopOption;} // 'Always on top' checkbox option on the main form
            set { _onTopOption = value; }
        }

        public string WrapOption
        {
            get {return _WrapOption;} // 'Word wrap' option in the file menu of the main form
            set { _WrapOption = value; }
        }

        public string AutoSave
        {
            get { return _AutoSave; } // 'Word wrap' option in the file menu of the main form
            set { _AutoSave = value; }
        }

        public string XMLPath
        {
            get { return _XMLPath;} // XML path
            set { _XMLPath = value; }
        }

        public string ErrHap
        {
            get { return _ErrHap; } // 'Always on top' checkbox option on the main form
            set { _ErrHap = value; }
        }

        // IOFile Constructor
        public IOFile()
        {
            string[] SettingItem = new string[4]; // there are only 4 lines to read from the ini file
                                                  // set the array for that number
            int i = 0;
            Scripting.FileSystemObject FsO = new Scripting.FileSystemObject(); // Create instance of FileSystemObject class

            if (FsO.FileExists("app.ini") == true) // Check if 'app.ini' is exist
            {
                try
                {
                    using (StreamReader sr = new StreamReader("app.ini")) // Open 'app.ini' file
                    {
                        do
                        {
                            SettingItem[i] = Convert.ToString(sr.ReadLine());
                            if (SettingItem[i] == null) { break; } // Set the array values
                            i++;
                        }
                        while (i < SettingItem.Length);

                        if (i < (SettingItem.Length - 1)) // If 'while' loop ends early
                                                          // there could be a file error
                        {
                            _ErrHap = "1";
                        }
                        else // set property values
                        {
                            _onTopOption = SettingItem[0]; // a1
                            _WrapOption = SettingItem[1]; // b1
                            _AutoSave = SettingItem[2]; // c1
                            _XMLPath = SettingItem[3]; // d1
                        }
                    }
                }
                catch (Exception exc)
                {
                    _ErrHap = exc.Message; // other file read error
                }
            }
            else
            {
                _ErrHap = "2"; // 'app.ini' file is not exist
            }
        }

        public void createINIFile()
        {
            try
            {
                using (StreamWriter sw = new StreamWriter("app.ini")) // Open 'app.ini' to write
                {
                    sw.WriteLine(_onTopOption);
                    sw.WriteLine(_WrapOption);
                    sw.WriteLine(_AutoSave);
                    sw.WriteLine(_XMLPath);
                }
            }
            catch (Exception exc)
            {
                _ErrHap = exc.Message ; // error when try to write to a file
            }
        }

    }
}

********************************************************

XML Class (Custom class)

Code 4 of 4

********************************************************
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Collections;

namespace CodeDatabase
{
    class XMLDatabase
    {
        public void XMLwork(string SubjectID, char XMLProcess, string XMLPath, string CodeSubject, string CodeMain)
        {
            switch (XMLProcess)
            {
                case 'n':
                    // Create new XML Document
                    // **********************************************************************
                    XmlTextWriter XMLWrite = new XmlTextWriter(XMLPath, System.Text.Encoding.UTF8);

                    XMLWrite.WriteStartDocument();
                    XMLWrite.WriteStartElement("Codes");
                    XMLWrite.WriteStartElement("NewCode");
                    XMLWrite.WriteElementString("ID", "1");
                    XMLWrite.WriteElementString("DBSubject", "Welcome");
                    XMLWrite.WriteElementString("DBCode", "Thank you for using CodeDatabase by Leo Koach (2010)");
                    XMLWrite.WriteEndElement();
                    XMLWrite.WriteEndElement();
                    XMLWrite.WriteEndDocument();

                    XMLWrite.Flush();
                    XMLWrite.Close();
                    break;
                case 'a':
                    // Append a node with information to same XML file
                    // **********************************************************************

                    XmlDocument xmlDoc = new XmlDocument();
                    xmlDoc.Load(XMLPath);
                    XmlElement subRoot = xmlDoc.CreateElement("NewCode");

                    //ID
                    XmlElement appendedElementID = xmlDoc.CreateElement("ID");
                    XmlText xmlTextID = xmlDoc.CreateTextNode(GetLatestID(XMLPath));
                    appendedElementID.AppendChild(xmlTextID);
                    subRoot.AppendChild(appendedElementID);
                    xmlDoc.DocumentElement.AppendChild(subRoot);

                    //Subject
                    XmlElement appendedElementSubject = xmlDoc.CreateElement("DBSubject");
                    XmlText xmlTextSubject = xmlDoc.CreateTextNode(CodeSubject);
                    appendedElementSubject.AppendChild(xmlTextSubject);
                    subRoot.AppendChild(appendedElementSubject);
                    xmlDoc.DocumentElement.AppendChild(subRoot);

                    //Code
                    XmlElement appendedElementCode = xmlDoc.CreateElement("DBCode");
                    XmlText xmlTextCode = xmlDoc.CreateTextNode(CodeMain);
                    appendedElementCode.AppendChild(xmlTextCode);
                    subRoot.AppendChild(appendedElementCode);
                    xmlDoc.DocumentElement.AppendChild(subRoot);

                    xmlDoc.Save(XMLPath);
                    break;
                case 'e':
                    //Change information on a node
                    // **********************************************************************
                    XmlDocument XMLEdit = new XmlDocument();
                    XMLEdit.Load(XMLPath);

                    XmlElement XMLEditNode = XMLEdit.DocumentElement;

                    foreach (XmlNode node in XMLEditNode)
                    {
                        if (node["ID"].InnerText == SubjectID)
                        {
                            node["DBCode"].InnerText = CodeMain;
                            break;
                        }
                    }
                    XMLEdit.Save(XMLPath);
                    break;
                case 'd':
                    // Removing a node
                    // **********************************************************************
                    XmlDocument XMLDelete = new XmlDocument();
                    XMLDelete.Load(XMLPath);

                    XmlElement XMLDeleteNode = XMLDelete.DocumentElement;

                    foreach (XmlNode node in XMLDeleteNode)
                    {
                        if (node["ID"].InnerText == SubjectID)
                        {
                            node.ParentNode.RemoveChild(node);
                            break;
                        }
                    }
                    XMLDelete.Save(XMLPath);
                    break;
                default:
                    throw new Exception("1");
            }
        }

        public string XMLGetinfo(string SubjectID, string XMLPath)
        {
            string StrInf = "";

            // Retreive a nod from the same XML file
            // **********************************************************************
            XmlDocument XMLRead = new XmlDocument(); // Create instance of XmlDocument class

            try
            {
                XMLRead.Load(XMLPath); // Set XMLRead object's path value

                XmlNodeList XMLItems = XMLRead.SelectNodes("Codes/NewCode"); // Create instance of XmlNodeList class
                // and set its node value

                foreach (XmlNode node in XMLItems) // Loop Node for the child node items
                {
                    if (node["ID"].InnerText == SubjectID) // Find the ID number
                    {
                        StrInf = node["DBCode"].InnerText; // Set return value to Main Code value from the XML file
                        break; // Exit loop
                    }
                }
                return StrInf;
            }
            catch (Exception exc)
            {
                throw exc;
            }
        }

        public string GetLatestID(string xmlFilePath)
        {
            int LastIDEntry = 0;
            // Get the last ID of the ID field.
            // **********************************************************************
            XmlDocument XMLGetLastID = new XmlDocument();
            XMLGetLastID.Load(xmlFilePath);

            XmlNodeList XMLItems = XMLGetLastID.SelectNodes("Codes/NewCode");

            foreach (XmlNode node in XMLItems)
            {
                LastIDEntry = Convert.ToInt32(node["ID"].InnerText) + 1;
            }
            return Convert.ToString(LastIDEntry);
        }

        public ArrayList GetSubjectList(string xmlFilePath, string FindWord)
        {
            ArrayList SubjectArray = new ArrayList();
            string nodeString;
            string UpperFindWord;
            UpperFindWord = FindWord.ToUpper();

            // Get the last ID of the ID field.
            // **********************************************************************
            XmlDocument XMLGetLastID = new XmlDocument();
            XMLGetLastID.Load(xmlFilePath);

            XmlNodeList XMLItems = XMLGetLastID.SelectNodes("Codes/NewCode");
            char Splitchr = (char)8; // backspace
            foreach (XmlNode node in XMLItems)
            {
                if (FindWord == "*") // Get all the Code Subjects
                {
                    SubjectArray.Add(node["ID"].InnerText + Splitchr + node["DBSubject"].InnerText);
                }
                else
                {
                    nodeString = node["DBSubject"].InnerText.ToUpper();
                    if (nodeString.IndexOf(UpperFindWord) != -1) // Find only selected wording
                    {
                        SubjectArray.Add(node["ID"].InnerText + Splitchr + node["DBSubject"].InnerText);
                    }
                }
            }
            return SubjectArray;
        }
    }
}

Submit "My C# Study Application with XML file" to Digg Submit "My C# Study Application with XML file" to del.icio.us Submit "My C# Study Application with XML file" to StumbleUpon Submit "My C# Study Application with XML file" to Google

Tags: c-sharp, xml Add / Edit Tags
Categories
Programming , ‎ Personal

Comments

  1. leokoach's Avatar
    I did some homework and checked LINQ. It is a very powerful tool... changes the whole thing and make XML coding easier.

    I have came up with a few changes for my article code so far, and I am going to stop here until I get myself a LINQ book or set of videos.

    I found a website which I suggest you to visit if you want to learn more about LINQ. Very nice, easy to understand videos done by Mike Taulty. His Linq videos from 2007, although still up to date for most I believe...

    Screencasts by Mike Taulty

    ---------------------------------------------------------

    Here are the code changes i made for my article piece (I will post them here, I won't change the original post)

    Adding new XML file now has shorter lines of code.
    Code:
    // Create new XML Document
    // **********************************************************************
    
    XDocument XMLNew = new XDocument(
    new XDeclaration("1.0", "UTF8", "true"),
    new XElement("Codes",
    new XElement("NewCode",
    new XElement("ID", "1"),
    new XElement("DBSubject", "Welcome"),
    new XElement("DBCode", "Thank you for using CodeDatabase by Leo Koach (2010)")
    )));
    
    XMLNew.Save(XMLPath);
    As you can see, I am using nodes and their vlaues instead of nodes and their attributes. I felt more comfortable that way.
    (And I really am not sure what is the difference between two other than how to read them syntax wise.)
    The second code I have changed is "Appending new data" into our XML file...
    Code:
    // Append a node with information to same XML file
    // **********************************************************************
    XDocument XMLAdd = XDocument.Load(XMLPath);
    
    XMLAdd.Element("Codes").Add(new XElement("NewCode", new XElement("ID", GetLatestID(XMLPath)),
                               new XElement("DBSubject", CodeSubject), new XElement("DBCode", CodeMain)));
    
    XMLAdd.Save(XMLPath);
    So far I am pretty good to use linq, but then it got more complicated for me to understand the concept deeper. That's why I need to study a lot about Linq more. Easy, although it's a new text for me.

    Editing portion of the code is half done. I might need your help to find out the solution. It is on the code if you read it,
    Code:
    //Change information on a node
    // **********************************************************************
    
    XElement XMLEdit = XElement.Load(XMLPath);
    var DBCodes = from NewCode in XMLEdit.Descendants("NewCode")
                  where NewCode.Element("ID").Value == SubjectID
         select NewCode;
    
    // This should be one line code. Since count is always 1, there is no reason for 'foreach'
    foreach (var NewCode in DBCodes)
    {
        NewCode.Element("DBCode").ReplaceNodes(CodeMain);
    }
    
     XMLEdit.Save(XMLPath);
    I also couldn't find a "deletion" option the way my XML file structured. There are options for with attributes, but mine doesn't have any... so, the code stays as is for now.

    Also, I will get rid of the ArrayList if I can find another way to carry a list of information from XML class to my main form class. I wanted to keep all XML work in one class, so the best way is to pass it through right now, using ArrayList.
  2. leokoach's Avatar
    "Performance Considerations
    In deciding whether to use the List(T) or ArrayList class, both of which have similar functionality, remember that the List(T) class performs better in most cases and is type safe. If a reference type is used for type T of the List(T) class, the behavior of the two classes is identical. However, if a value type is used for type T, you need to consider implementation and boxing issues."-MS

    From MS website. Sometimes my findings are "first-come-first-served". If one works, I don't even conceder there would be a second almost identical option.

    Changed the ArrayList to List(T) on my code,

    Code:
    // Method that I send List < T > from (in XMLDatabase class)
    public List < string > GetSubjectList(string xmlFilePath, string FindWord)
         {
         List < string > SubjectArray = new List < string > (); // I kept the name
         ...
         ...
         SubjectArray.Add(node["ID"].InnerText + Splitchr + node["DBSubject"].InnerText); // in a loop
         ...
    
    *******************
    // Where I set my List in Form class
         ...
    XMLDatabase clsXML = new XMLDatabase(); // Create instance of XMLDatabase class
    List < string > CurrentSubjectList = new List < string > (); // Create instance of List < T >
                                                          // This will loaded with the List < T >
                                                          // sent by clsXML object
         ...
    It's like saying "My name is Leo, but it's better if you call me Mr. Leo so you'll get my gender right each time"

    ArrayList vs List < T >