1

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,

1
  • If you have an identity field in each Information just use it as name of your XML file ;). Commented Jan 12, 2017 at 9:20

3 Answers 3

1

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; }
        }

    }

}
Sign up to request clarification or add additional context in comments.

2 Comments

This worked for me in creating the duty chart of the staff, Thx so much.
Now I'll look for ways to edit/update those entries ;)
0

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

1 Comment

Using of XDocument will bring no value, instead you will need manually write values to the XDocument. Where XmlSerializer will generate xml file automatically based on the type of provided object.
0

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.

3 Comments

Thanks for your reply Mong Zhu, I like the option of the List<Information> InfoList, but can't get my brain around how to structure it (Online tutorials aren't working for me!) Any chance you could briefly run through how this would be structured in this instance? Much appreciated.
@el_beeto You are welcome. I added a run through to my answer, hope it helps. Have a look
Thanks very much for taking the time to respond @MongZhu, apologies for my slow reply! I will run thru your walkthru and see how I go, Kind regards

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.