C# Visual C程序只将最后一个索引保存到XML文件

C# Visual C程序只将最后一个索引保存到XML文件,c#,xml,C#,Xml,我在保存和读取XML文件时遇到问题。当我将文本框中的一些数据添加到列表框时,只保存我添加的最后一个索引,但保存了多次 例如: private void button1_Click(object sender, EventArgs e) //add data to listBox { if (String.IsNullOrWhiteSpace(textBox1.Text) || String.IsNullOrWhiteSpace(textBox2.Text)) {

我在保存和读取XML文件时遇到问题。当我将文本框中的一些数据添加到列表框时,只保存我添加的最后一个索引,但保存了多次

例如:

private void button1_Click(object sender, EventArgs e) //add data to listBox
{
    if (String.IsNullOrWhiteSpace(textBox1.Text) || String.IsNullOrWhiteSpace(textBox2.Text))
    {
        MessageBox.Show("Proszę uzupełnić wszystkie pola, aby wprowadzić dane", "Błąd!", MessageBoxButtons.OK, MessageBoxIcon.Warning);
        return;
    }
    listBox1.Items.Add(textBox4.Text + " " + textBox1.Text + " " + textBox2.Text);
    listBox1.DisplayMember = textBox4.Text;
}

private void button2_Click(object sender, EventArgs e) //delete data from listbox
{
    if(listBox1.SelectedIndex == -1)
        {
        MessageBox.Show("Proszę zaznaczyć pozycję by usunąć", "Błąd!", MessageBoxButtons.OK, MessageBoxIcon.Warning);
        return;
        }
    listBox1.Items.Remove(listBox1.SelectedItem);
}

private void button3_Click(object sender, EventArgs e) //save to XML button
{
    DataSet ds = new DataSet();
    DataTable dt = new DataTable();
    dt.TableName = "Tabela";
    dt.Columns.Add("Name");
    dt.Columns.Add("Surname");
    dt.Columns.Add("PESEL");
    dt.Columns.Add("Room");
    ds.Tables.Add(dt);

    foreach (string item in listBox1.Items)
    {
        DataRow dr = ds.Tables["Tabela"].NewRow();
        dr["Name"] = textBox1.Text;
        dr["Surname"] = textBox2.Text;
        dr["PESEL"] = textBox3.Text;
        dr["Room"] = textBox4.Text;
        ds.Tables["Tabela"].Rows.Add(dr);
    }
    ds.WriteXml("D:\\data.xml");
}

private void button4_Click(object sender, EventArgs e) //read from XML button
    {
        DataSet ds = new DataSet();
        ds.ReadXml("D:\\data.xml");

        foreach (DataRow item in ds.Tables["Tabela"].Rows)
        {
        listBox1.Items.Add(string.Format("{0} {1} {2}", item["Room"],     item["Name"], item["Surname"]));
    }
}

private void listBox1_SelectedIndexChanged(object sender, EventArgs e) 
{
    DataSet ds = new DataSet();
    ds.ReadXml("D:\\data.xml");

    foreach (DataRow item in ds.Tables["Tabela"].Rows)
    {
        textBox1.Text = item["Name"].ToString();
        textBox2.Text = item["Surname"].ToString();
        textBox3.Text = item["PESEL"].ToString();
        textBox4.Text = item["Room"].ToString();
    }
}
当我从XML加载数据时,列表框工作正常,但当我在文本框中从此列表中选择一个索引时,只会显示最后一个索引,而不是我单击的索引。

在您的代码中

<Tabela>
    <Name>John</Name>
    <Surname>Johnson</Surname>
    <PESEL>123465789</PESEL>
    <Room>21</Room>
</Tabela>
<Tabela>
    <Name>John</Name>
    <Surname>Johnson</Surname>
    <PESEL>123465789</PESEL>
    <Room>21</Room>
</Tabela>
<Tabela>
    <Name>John</Name>
    <Surname>Johnson</Surname>
    <PESEL>123465789</PESEL>
    <Room>21</Room>
</Tabela>
对于列表框中的每个项目。由于文本框不会改变,它确实会为列表框中的每个项目添加一个文本框

我认为您需要对for循环中的项执行某些操作,而不是文本框

dr["Name"] = textBox1.Text;
dr["Surname"] = textBox2.Text;
dr["PESEL"] = textBox3.Text;
dr["Room"] = textBox4.Text;
我不知道你想做什么,但你可能想改变一些事情,比如从列表中读写什么


如果您告诉我们您正在使用asp.net、wpf等技术,我们可能可以帮助您。

更改listBox1\u SelectedIndexChanged方法,将所选listbox值用作表的筛选器,类似于以下内容:

foreach (string item in listBox1.Items)
{
    DataRow dr = ds.Tables["Tabela"].NewRow();
    dr["Name"] = textBox1.Text;
    dr["Surname"] = textBox2.Text;
    dr["PESEL"] = textBox3.Text;
    dr["Room"] = textBox4.Text;
    ds.Tables["Tabela"].Rows.Add(dr);
}

对于表示主要业务实体的listbox控件,您使用的方法非常糟糕。这是非常糟糕的

事实上,为了使您的解决方案正常工作,您应该在每次在预期文本框中添加新项数据时将其保存到xml文件中,并避免在保存时循环列表框项

当SelectedIndexChanged事件发生时,显示所选项目详细信息的方法也是错误的,因为您没有指向所选的正确列表框项目,而是每次在列表框中选择新项目时指向文件中最后保存的项目

因此,更好的方法是声明一个类,该类将成为您的实体,该类的集合将成为您的listbox的数据源:

private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
    DataSet ds = new DataSet();
    ds.ReadXml("D:\\data.xml");

    //split selected item by spaces
    var values = listBox1.SelectedItem.ToString().Split(' ');
    var selectedRow = ds.Tables["Tabela"].AsEnumerable()
        .Where
            (r => r["Room"].ToString() == values[0] && 
            r["Name"].ToString() == values[1] && 
            r["Surname"].ToString() == values[2]).FirstOrDefault();

    if (selectedRow != null)
    {
        textBox1.Text = selectedRow["Name"].ToString();
        textBox2.Text = selectedRow["Surname"].ToString();
        textBox3.Text = selectedRow["PESEL"].ToString();
        textBox4.Text = selectedRow["Room"].ToString();
    }
}
删除一个项目时:

保存项目时:

当您从文件加载时

您可以重构关于listbox刷新的重复语句

public class Booking{

    string Name;
    string Surname;
    string PESEL; //your key? remember to manage duplicates if you insert manually (better if it were generated automatically as unique data (Guid))
    string Room;
}

System.Collections.Generic.List<Booking> bookings; //instantiate in Form constructor method
 if (String.IsNullOrWhiteSpace(textBox1.Text) || String.IsNullOrWhiteSpace(textBox2.Text))
    {
        MessageBox.Show("Proszę uzupełnić wszystkie pola, aby wprowadzić dane", "Błąd!", MessageBoxButtons.OK, MessageBoxIcon.Warning);
        return;
    }

    bookings.Add(new Booking{ 
      Name = textBox1.Text,
      Surname = textBox2.Text,
      PESEL = textBox3.Text,
      Room = textBox4.Text
    });

    listBox.DataSource = null;
    listBox.DataSource = bookings; //use the datasource  property
    listBox.DisplayMember = "Room";
    listBox.ValueMember = "PESEL";
    if (listBox.SelectedIndex == -1) {
        MessageBox.Show("Proszę zaznaczyć pozycję by usunąć", "Błąd!", MessageBoxButtons.OK, MessageBoxIcon.Warning);
        return;
    }

    bookings.Remove(bookings.Find(c => c.PESEL == listBox.SelectedValue as string));
    listBox.DataSource = null;
    listBox.DataSource = bookings; //use the datasource  property
    listBox.DisplayMember = "Room";
    listBox.ValueMember = "PESEL";
DataSet ds = new DataSet();
DataTable dt = new DataTable();
dt.TableName = "Tabela";
dt.Columns.Add("Name");
dt.Columns.Add("Surname");
dt.Columns.Add("PESEL");
dt.Columns.Add("Room");
ds.Tables.Add(dt);

foreach (Booking item in bookings)
{
    DataRow dr = ds.Tables["Tabela"].NewRow();
    dr["Name"] = item.Name;
    dr["Surname"] = item.Surname;
    dr["PESEL"] = item.PESEL;
    dr["Room"] = item.Room;
    ds.Tables["Tabela"].Rows.Add(dr);
}
ds.WriteXml("D:\\data.xml");
    //attention to eventual new records appended to the list you may lose them

    DataSet ds = new DataSet();
    ds.ReadXml("D:\\data.xml");

    bookings.Clear(); //<<== avoids dirty loading (duplicates)

    foreach (DataRow item in ds.Tables["Tabela"].Rows) {
        bookings.Add(new Booking() {
            Name = item["Name"].ToString(),
            Surname = item["Surname"].ToString(),
            PESEL = item["PESEL"].ToString(),
            Room = item["Room"].ToString()
        });
    }

    listBox.DataSource = null;
    listBox.DataSource = bookings; //use the datasource  property
    listBox.DisplayMember = "Room";
    listBox.ValueMember = "PESEL";
        Booking booking = bookings.Find(c => c.PESEL == listBox.SelectedValue as string);

        if (booking == null) return;

        textBox1.Text = booking.Name;
        textBox2.Text = booking.Surname;
        textBox3.Text = booking.PESEL;
        textBox4.Text = booking.Room;