Reputation: 297
I have an xml file (XMLFile1.xml).
I did the following, but datagridview sorting is not done correctly.
For example I have these 5 rows and 2 columns:
Id | Value |
---|---|
1 | before- |
2 | co- |
3 | -ly |
4 | -ing |
5 | after- |
But when I click on header of datagridview, the result of sorting is:
Id | Value |
---|---|
1 | before- |
2 | co- |
4 | -ing |
3 | -ly |
5 | after- |
private void Form1_Load(object sender, EventArgs e)
{
dataGridView1.ColumnCount = 2;
dataGridView1.RowCount = 5;
dataGridView1.Columns[0].Name = "Radif";
dataGridView1.Columns[1].Name = "Root";
dataGridView1.Columns[1].SortMode = DataGridViewColumnSortMode.Automatic;
dataGridView1.AutoGenerateColumns = true;
string myXMLfile = @"C:\Users\PC\Desktop\XMLFile1.xml";
DataSet ds = new DataSet();
ds.ReadXml(myXMLfile);
DataTable dt = ds.Tables["XMLFile1"];
for (int i = 0; i < dt.Rows.Count; i++)
{
dataGridView1.Rows[i].Cells[0].Value = dt.Rows[i][0].ToString();
dataGridView1.Rows[i].Cells[1].Value = dt.Rows[i][1].ToString();
}
}
EDIT1:
XMLFile1.xml
<dataroot xmlns:od="urn:schemas-microsoft-com:officedata"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="XMLFile1.xsd" generated="2016-03-09T13:36:40">
<XMLFile1>
<Radif>1</Radif>
<Root>before-</Root>
</XMLFile1>
<XMLFile1>
<Radif>2</Radif>
<Root>co-</Root>
</XMLFile1>
<XMLFile1>
<Radif>3</Radif>
<Root>-ly</Root>
</XMLFile1>
<XMLFile1>
<Radif>4</Radif>
<Root>-ing</Root>
</XMLFile1>
<XMLFile1>
<Radif>5</Radif>
<Root>after-</Root>
</XMLFile1>
</dataroot>
I click on the second column of datagridview (Root column).
EDIT2:
I added this code but my problem was not solved:
private void dataGridView1_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
dataGridView1.Refresh();
dataGridView1.ClearSelection();
dataGridView1.CurrentCell = dataGridView1.Rows[0].Cells[0];
dataGridView1.Rows[0].Selected = true;
}
EDIT 3:
private void Form1_Load(object sender, EventArgs e)
{
string myXMLfile = @"C:\Users\PC\Desktop\XMLFile1.xml";
ds = new DataSet();
ds.ReadXml(myXMLfile);
dt = ds.Tables["XMLFile1"];
dataGridView1.DataSource = dt;
}
I have a button for adding a row to XML file and the datagridview1. When I added the row, the last row (added row) participates in sorting, but I want that new data to be added to the end of the datagridview1 and sorted by clicking the datagridview1 header.
private void buttonAdd_Click(object sender, EventArgs e)
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(@"C:\Users\PC\Desktop\XMLFile1.xml");
XmlNode newElem = xmlDoc.CreateNode(XmlNodeType.Element, "XMLFile1", null);
XmlNode newElemRadif = xmlDoc.CreateElement("Radif");
newElemRadif.InnerText = tbRaAdd.Text;
newElem.AppendChild(newElemRadif);
XmlNode newElemName = xmlDoc.CreateElement("Root");
newElemName.InnerText = tbRoAdd.Text;
newElem.AppendChild(newElemName);
xmlDoc.DocumentElement.AppendChild(newElem);
xmlDoc.Save(@"C:\Users\PC\Desktop\XMLFile1.xml");
DataRow dr = dt.NewRow();
dr["Radif"] = tbRaAdd.Text;
dr["Root"] = tbRoAdd.Text;
dt.Rows.Add(dr);
}
EDIT 4:
I did these and my problem was solved:
private void Form1_Load(object sender, EventArgs e)
{
dataGridView1.ColumnCount = 2;
dataGridView1.Columns[0].Name = "Radif";
dataGridView1.Columns[1].Name = "Root";
string myXMLfile = @"C:\Users\PC\Desktop\XMLFile1.xml";
ds = new DataSet();
ds.ReadXml(myXMLfile);
dt = ds.Tables["XMLFile1"];
dataGridView1.RowCount = dt.Rows.Count + 1;
for (int i = 0; i < dt.Rows.Count; i++)
{
dataGridView1.Rows[i].Cells[0].Value = dt.Rows[i][0].ToString();
dataGridView1.Rows[i].Cells[1].Value = dt.Rows[i][1].ToString();
}
}
private void buttonAdd_Click(object sender, EventArgs e)
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(@"C:\Users\PC\Desktop\XMLFile1.xml");
XmlNode newElem = xmlDoc.CreateNode(XmlNodeType.Element, "XMLFile1", null);
XmlNode newElemRadif = xmlDoc.CreateElement("Radif");
newElemRadif.InnerText = tbRaAdd.Text;
newElem.AppendChild(newElemRadif);
XmlNode newElemName = xmlDoc.CreateElement("Root");
newElemName.InnerText = tbRoAdd.Text;
newElem.AppendChild(newElemName);
xmlDoc.DocumentElement.AppendChild(newElem);
xmlDoc.Save(@"C:\Users\PC\Desktop\XMLFile1.xml");
dataGridView1.Rows.Add(1);
dataGridView1.Rows[dataGridView1.Rows.Count - 2].Cells[0].Value = tbRaAdd.Text;
dataGridView1.Rows[dataGridView1.Rows.Count - 2].Cells[1].Value = tbRoAdd.Text;
}
Upvotes: 0
Views: 469
Reputation: 112279
The problem is that the RowCount
includes the new records row, where users can enter new data. The last data row with "after-" is added to this row, but this row appears always as the last row.
Therefore specify the row count in the gridview to be 1 higher than the number of data rows. You can then hide this extra row by specifying dataGridView1.AllowUserToAddRows = false;
.
Start by reading the XML file into the data table, then set
dataGridView1.RowCount = dt.Rows.Count + 1;
But you can simplify your code dramatically, if you just assign the data table to the data source of the gridview. This creates the columns and the rows automatically. The sort mode is automatic by default.
private void Form1_Load(object sender, EventArgs e)
{
string myXMLfile = @"C:\Users\PC\Desktop\XMLFile1.xml";
DataSet ds = new DataSet();
ds.ReadXml(myXMLfile);
DataTable dt = ds.Tables["XMLFile1"];
dataGridView1.DataSource = dt;
}
In response to your EDIT 3, I suggest a totally different solution. I have tried hard with DataSets, but run into a lot of problems. Therefore I suggest reading the XML into a list of custom objects.
Let's create a class for this:
class XMLFile1
{
public int? Radif { get; set; }
public string Root { get; set; }
}
Now, in the form we declare two fields and rewrite Form1_Load
like this:
private XDocument _xDoc;
private BindingList<XMLFile1> _bindingList;
private void Form1_Load(object sender, EventArgs e)
{
string myXMLfile = @"C:\Users\PC\Desktop\XMLFile1.xml";
_xDoc = XDocument.Load(myXMLfile);
var records = _xDoc.Root.Elements()
.Select(el => new XMLFile1 {
Radif = Int32.Parse(el.Element("Radif").Value),
Root = el.Element("Root").Value
})
.ToList();
_bindingList = new BindingList<XMLFile1>(records);
dataGridView1.DataSource = _bindingList;
}
Now you can do edits in dataGridView1, including adding new records through the bottom line. You don't need text boxes to enter new data. If you still want to enter new data through text boxes you can add a new entry like this:
private void buttonAdd_Click(object sender, EventArgs e)
{
_bindingList.Add(
new XMLFile1 { Radif = Int32.Parse(tbRaAdd.Text), Root = tbRoAdd.Text });
}
Note that this automatically updates dataGridView1. THis also works the other way round. All edits made in the grid are automatically persisted to _bindingList
. Therefore, we can now save all edits with:
private void btnSave_Click(object sender, EventArgs e)
{
string myXMLfile = @"C:\Users\PC\Desktop\XMLFile1.xml";
dataGridView1.EndEdit();
var root = _xDoc.Root;
root.RemoveNodes();
root.Add(_bindingList.Select(x => new XElement("XMLFile1",
new XElement("Radif", x.Radif),
new XElement("Root", x.Root))));
_xDoc.Save(myXMLfile);
}
Upvotes: 1