简体   繁体   中英

Add the contents of a DataGridView to an existing XML file

So I finally was able to create a XML and change it as I want but now I needed to add the contents of a DataGridView to it. I thought that's quite easy as I saw the options to place it into a DataSet and use XmlWrite , but that was a mistake of me. Note that I'm still trying to learn C# so probably I make a silly mistake here. It is still not working maybe someone is willing to point me out what I am doing wrong?

I actually have two issues with this:

  1. It ForEach loop doesn't get the existing column names

  2. It doesn't add the table and its contents to the XML file

    private void CreateClientFile() { string filename; filename = Company + "_" + SiteName + ".xml";

     XmlDocument doc = new XmlDocument(); XmlElement root = doc.CreateElement("CompanyProfile"); doc.AppendChild(root); //Save document on Harddisk doc.Save(@"C:\Users\NLRAGIL\Documents\10 - VibroManager\" + filename); //Need to save first and than load again???? //Load document into program doc.Load(@"C:\Users\NLRAGIL\Documents\10 - VibroManager\" + filename); XmlNode main = doc.SelectSingleNode("CompanyProfile"); //Create Company name element XmlElement companyname = doc.CreateElement("CompanyName"); companyname.InnerText = CompanyName; main.AppendChild(companyname); //Create sitename element XmlElement sitename = doc.CreateElement("Sitename"); sitename.InnerText = SiteName; main.AppendChild(sitename); //Create IMO element XmlElement imo = doc.CreateElement("IMO"); imo.InnerText = IMO; main.AppendChild(imo); DataTable dt = new DataTable(); for (int i = 0; i < dataGridView1.Columns.Count; i++) { dt.Columns.Add("column" + i.ToString()); } foreach (DataGridViewRow row in dataGridView1.Rows) { DataRow dr = dt.NewRow(); for (int j = 0; j < dataGridView1.Columns.Count; j++) { dr["column" + j.ToString()] = row.Cells[j].Value ; } dt.Rows.Add(dr); } //Create DataSet and add the datatable DataSet ds = new DataSet(); ds.Tables.Add(dt); //Give the file name for where to write to. ds.WriteXml(@"C:\Users\NLRAGIL\Documents\10 - VibroManager\" + filename); //Show example for debugging doc.Save(@"C:\Users\NLRAGIL\Documents\10 - VibroManager\" + filename); System.Console.WriteLine(doc.InnerXml); }

EXTRA CLARIFICATION: The form I have looks as below: 客户资料

The Textbox in the groupbox "Client Information" I'm able to save in a XML file. By altering the value of the numeric control I can express how much machine the particular client has. And the DataGridView gets more or less rows. But the information from the DataGridView I'm unable to append to the created XML file.

So the information from "Machine Name", "Serial No" etc I can't add to the XML file.

This is what I wanted to do, so later on in the program I can add certain measurements of each machine to it and store also in the same file.

But whatever I do my XML file looks like this: 在此处输入图像描述

I hope I explained it better now sorry for the confusion

Your question is Add the contents of a DataGridView to an existing XML file and you say your first issue is that your ForNext loop is not giving you the column names and your second issue is that the code fails to serialize the record to an XML file on disk. These two goals can be simplified by using Data Binding . This decouples your data from the view, making it easier to process. I would like to give you some insight if you wanted to try it out using the CompanyProfile in your code.

First, a CompanyProfile class declares the intended public properties:

public class CompanyProfile
{
    public string CompanyName { get; set; } 
    public string SiteName { get; set; }
    public string IMO { get; set; } = "Some Value";
} 

Next, in your MainForm class a BindingList<CompanyProfile> is declared and attached to the DataGridView like this:

BindingList<CompanyProfile> DataSource = new BindingList<CompanyProfile>();
protected override void OnHandleCreated(EventArgs e)
{
    base.OnHandleCreated(e);
    if(!DesignMode)
    {
        // Attach the data source to the view. Now changes to source records refresh in the view.
        dataGridView1.DataSource = this.DataSource;
        // Adding one or more records will generate the columns.
        DataSource.Add(new CompanyProfile { CompanyName = "Linear Technology", SiteName = "Colorado Design Center"});
        DataSource.Add(new CompanyProfile { CompanyName = "Analog Devices", SiteName = "1-1-2"});

        // Use string indexer to get a column
        dataGridView1.Columns[nameof(CompanyProfile.CompanyName)].AutoSizeMode = dataGridViewAutoSizeColumnMode.Fill;
        dataGridView1.Columns[nameof(CompanyProfile.SiteName)].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;

        DataGridView1.AllowUserToAddRows = false;
    }
}

The resulting DataGridView now looks like this:

具有两条记录的数据网格视图

This method makes a single file from a CompanyProfile record using XmlSerializer (but this is just one approach - and you could also serialize the entire list at one time if you choose).

private void CreateClientFile(CompanyProfile companyProfile, string fileName)
{
    System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(typeof(CompanyProfile));
    using (var writer = new StreamWriter(fileName))
    {
        x.Serialize(writer, companyProfile);
    }
    // Open the file to view the result
    Process.Start("notepad.exe", fileName);
}

Now, iterate a ForNext loop on the DataSource not the DataGridView . You no longer need to worry about columns because you have the bound properties instead.

private void btnSerialize_Click(object sender, EventArgs e)
{
    var appData = Path.Combine(
            Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
            "datagridview_to_xml");
    Directory.CreateDirectory(appData);

    // Iterate the datasource list, not the DataGridView.
    foreach (CompanyProfile companyProfile in DataSource)
    {
        CreateClientFile(
            companyProfile,
            fileName: Path.Combine(appData,
            $"{companyProfile.CompanyName}_{companyProfile.SiteName}.xml")
        );
    }
}

Clicking the [Serialize] button reveals the two files.

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM