el_beeto
el_beeto

Reputation: 11

Creating separate XML documents for Winforms input data in C#

I'm fairly new to C# development, currently building a booking application for a marina.

(Have searched previous questions but haven't been successful in locating specifically what I'm seeking)

Use case:

  1. Enter client info via windows form interface,
  2. Store data as XML file - on button click (one per customer)
  3. Return data to gridView when searched by name via form. (e.g client lookup)

I have configured the program to create an XML file for the form input, However, I can not figure out how to create a separate XML file for each entry.

Currently, each time I enter the form data, it overwrites the previous XML data in the file.

Any solutions as to how to create separate/additional XML files as per above are much appreciated.

First time posting here, so apologies if I've omitted any necessary info.

Code is as follows:

  // Save XML.cs

     using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Xml.Serialization;
    using System.IO;

    namespace Popeye_Booking_application
    {
        public class SaveXml
        {
            public static void SaveData(object obj, string filename)
            {
                XmlSerializer sr = new XmlSerializer(obj.GetType());
                TextWriter writer = new StreamWriter(filename);
                sr.Serialize(writer, obj);
                writer.Close();
                }
            }
        }



// Information.cs



    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;

    namespace Popeye_Booking_application
    {
        public class Information
        {
            private string data1;
            private string data2;
            private string data3;
            private string data4;
            private string data5;
            private string data6;
            private string data7;

            public string Data1
            {
                get  { return data1; }
                set { data1 = value; }
            }

            public string Data2
            {
                get { return data2; }
                set { data2 = value; }
            }

            public string Data3
            {
                get { return data3; }
                set { data3 = value; }
            }

            public string Data4
            {
                get { return data4; }
                set { data4 = value; }
            }

            public string Data5
            {
                get { return data5; }
                set { data5 = value; }
            }

            public string Data6
            {
                get { return data6; }
                set { data6 = value; }
            }

            public string Data7
            {
                get { return data7; }
                set { data7 = value; }
            }

        }
    }


// Form.cs

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

namespace Popeye_Booking_application
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void buttonCreate_Click(object sender, EventArgs e)
        {
            try
            {
                Information info = new Information();
                info.Data1 = textBoxData1.Text;
                info.Data2 = textBoxData2.Text;
                info.Data3 = textBoxData3.Text;
                info.Data4 = textBoxData4.Text;
                info.Data5 = textBoxData5.Text;
                info.Data6 = textBoxData6.Text;
                info.Data7 = textBoxData7.Text;

               SaveXml.SaveData(info, "data.xml");

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void label1_Click(object sender, EventArgs e)
        {

        }

        private void label4_Click(object sender, EventArgs e)
        {

        }

        private void label10_Click(object sender, EventArgs e)
        {

        }

        private void label7_Click(object sender, EventArgs e)
        {

        }

        private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {

        }
    }
}

Thanks in advance,

Upvotes: 1

Views: 1200

Answers (3)

Mong Zhu
Mong Zhu

Reputation: 23732

However, I can not figure out how to create a separate XML file for each entry.

You need for each entry a specific distinguishable id or name. So I would suggest to make an extra property in the Class Information for it:

public class Information
{

    public string Name { get; set; }

this would also help you to manage the 3. point

3.Return data to gridView when searched by name via form. (e.g client lookup)

You would need an extra TextBox for the Name entry:

Information info = new Information();
info.Name= textBoxName.Text;

And if it does not already exist then save it: string filename = info.Name + ".XML"

if (!System.IO.File.Exists(filename))
{
    SaveXml.SaveData(info, filename);
}
else
{
    // notify that name is imabiguous
}

When Loading you could search for that file.

Another possibility would be to make an extra class with only 1 property: a List<Information> InfoList. That can be saved in one file with all the information entries. This can then be bound easily to a DataGridView and also can be search easily for specific items using the Name property.

EDIT:

Here is a little run through that you asked for:

The basic structure of your Information class remains the same:

public class Information
{
    public string Name { get; set; }
    public string Data1 { get; set; }
    public string Data2 { get; set; }

    // and so on... you get the drift
}

You need a container class for all those infos. So that you can use only file to save them all ;). This class can then also get the methods to save and load:

public class InformationSaveFile
{   // A list to safe all info entries
    public List<Information> InformationList { get; set; }

    public InformationSaveFile()
    {
        InformationList = new List<Information>();
    }

    // you method to save data
    public static void SaveData(object obj, string filename)
    {
        XmlSerializer sr = new XmlSerializer(obj.GetType());
        TextWriter writer = new StreamWriter(filename);
        sr.Serialize(writer, obj);
        writer.Close();
    }

    // a method to Load the Data
    public static InformationSaveFile LoadData(string FileName)
    {
        using (var stream = File.OpenRead(FileName))        // File ist aus dem Namensraum System.IO
        {
            var serializer = new XmlSerializer(typeof(InformationSaveFile));
            InformationSaveFile w = serializer.Deserialize(stream) as InformationSaveFile;

            return w;
        }
    }

}

In your form you would need an Instance of the container class:

// public is not necessary here
public InformationSaveFile InfoSaveFile { get; set; }

now to add data you would use the InformationList, and to save the data the SaveData method like this:

private void buttonCreate_Click(object sender, EventArgs e)
{
    //Adding of Info Items:
    Information info = new Information();
    info.Name = "Specific Name";
    info.Data1 = textBoxData1.Text;
    // and so on...
    InfoSaveFile.InformationList.Add(info);

    InformationSaveFile.SaveData(InfoSaveFile, "YourFileName.XML");

For loading the data you would now need only the same filename and all your data that you added to the InformationList and saved will be at your disposal:

InfoSaveFile = InformationSaveFile.LoadData("YourFileName.XML");

Now you can use the List to filter the data for the entry that you need:

// Search for certain names:
List<Information> infoList = InfoSaveFile.InformationList.FindAll(x => x.Name == "Search Name");
// OR looking with contains (makes the search broader)
List<Information> infoList_broad = InfoSaveFile.InformationList.FindAll(x => x.Name.Contains("Search Name"));

Now that became a very long answer. I hope you can follow that run through, and the answer helps. If not just drop me a comment.

Upvotes: 0

jdweng
jdweng

Reputation: 34421

Use a DataTable. It is easier to read and write. Also add a DataGridView to the form

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; 
using System.Data;
using System.Drawing;
using System.Windows.Forms;
using System.IO;

namespace Popeye_Booking_application
{
    public partial class Form1 : Form
    {
        const string FILENAME = @"c:\temp\test.xml";
        DataTable dt = new DataTable();
        public Form1()
        {
            InitializeComponent();
            if (File.Exists(FILENAME))
            {
                dt.ReadXml(FILENAME);
                dataGridView1.DataSource = dt;
            }
            else
            {
                dt.TableName = "Data";
                dt.Columns.Add("Data1",typeof(string));
                dt.Columns.Add("Data2", typeof(string));
                dt.Columns.Add("Data3", typeof(string));
                dt.Columns.Add("Data4", typeof(string));
                dt.Columns.Add("Data5", typeof(string));
                dt.Columns.Add("Data6", typeof(string));
                dt.Columns.Add("Data7", typeof(string));
                SaveXml.SaveData(dt, FILENAME);
            }

        }

        private void buttonCreate_Click(object sender, EventArgs e)
        {
            try
            {
                Information info = new Information();
                info.Data1 = textBoxData1.Text;
                info.Data2 = textBoxData2.Text;
                info.Data3 = textBoxData3.Text;
                info.Data4 = textBoxData4.Text;
                info.Data5 = textBoxData5.Text;
                info.Data6 = textBoxData6.Text;
                info.Data7 = textBoxData7.Text;

                dt.Rows.Add(new object[] {
                    info.Data1,
                    info.Data2,
                    info.Data3,
                    info.Data4,
                    info.Data5,
                    info.Data6,
                    info.Data7
                });
                dt.AcceptChanges();

                dataGridView1.DataSource = null;
                dataGridView1.DataSource = dt;
                SaveXml.SaveData(dt, FILENAME);


            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void label1_Click(object sender, EventArgs e)
        {

        }

        private void label4_Click(object sender, EventArgs e)
        {

        }

        private void label10_Click(object sender, EventArgs e)
        {

        }

        private void label7_Click(object sender, EventArgs e)
        {

        }

        private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {

        }


    }
    public class SaveXml
    {
        public static void SaveData(DataTable dt, string filename)
        {
            dt.WriteXml(filename, XmlWriteMode.WriteSchema);
        }
    }

    public class Information
    {
        private string data1;
        private string data2;
        private string data3;
        private string data4;
        private string data5;
        private string data6;
        private string data7;

        public string Data1
        {
            get { return data1; }
            set { data1 = value; }
        }

        public string Data2
        {
            get { return data2; }
            set { data2 = value; }
        }

        public string Data3
        {
            get { return data3; }
            set { data3 = value; }
        }

        public string Data4
        {
            get { return data4; }
            set { data4 = value; }
        }

        public string Data5
        {
            get { return data5; }
            set { data5 = value; }
        }

        public string Data6
        {
            get { return data6; }
            set { data6 = value; }
        }

        public string Data7
        {
            get { return data7; }
            set { data7 = value; }
        }

    }

}

Upvotes: 1

Ali Ezzat Odeh
Ali Ezzat Odeh

Reputation: 2163

Use XDocument class to create an object for each entry and then use Save method inside it, check this link : https://msdn.microsoft.com/en-us/library/system.xml.linq.xdocument(v=vs.110).aspx

Upvotes: 0

Related Questions