Nathanial s-c
Nathanial s-c

Reputation: 31

How can I search an XML file and output the results to data grid for editing?

This can be done by using SQL, however I would like to use an XML file to have that ease for the user. I can make it display the data in the data-grid-view normally, but I'm not sure how to search for it as you normally would in an SQL database.

All I need to do is allow the person to search for a name, information or the day visited to put the data in the data-grid-view.

Following is my XML code:

<root>
  <place>
    <Name>home</Name>
    <Location>x-292 z 277</Location>
    <Info>home</Info>
    <Dayvisited>10</Dayvisited>
  </place>
  <place>
    <Name>town</Name>
    <Location>x 990 z-2485</Location>
    <Info>gas station</Info>
    <Dayvisited>12</Dayvisited>
  </place>
  <place>
    <Name>crossing</Name>
    <Location>x 90 z-2998</Location>
    <Info>working stiff</Info>
    <Dayvisited>11</Dayvisited>
  </place>
</root>

this is how i made it load in to a grid so far

ds.ReadXml("Database.xml");
dataGridView1.DataSource = ds.Tables[0];
dataGridView1.Rows[0].Visible = false;

im new at using xml files so any help is appreciated.

Upvotes: 1

Views: 850

Answers (1)

TaW
TaW

Reputation: 54433

Let's simplfy the task by keeping the data in only one DataGridView and hiding those rows that don't match the search string.

Since you already have loaded the XML into a DataTable and bound a DataGridView to it we don't really need to search in the XML data..

The way to go for data-bound DGVs is to set a Filter on the DataSource. For this we need to insert a DataView between the DGV and the DataTable.

Let's start by filling a ComboBox with the DataTable's Columns:

combo_fields.Items.AddRange(ds.Tables[0].Columns.Cast<DataColumn>()
                                .Select(x => x.ColumnName).ToArray());
combo_fields.SelectedIndex = 1;  // start with the Location field

Next we add a TextBox where we enter the search text:

private void tb_filter_TextChanged(object sender, EventArgs e)
{
    string filter = ""; 
    if (tb_filter.Text != "")
        filter = combo_fields.Text + " LIKE '*" + tb_filter.Text + "*'";

    DataView dv = new DataView(ds.Tables[0]);
    dv.RowFilter = filter;
    dataGridView1.DataSource = dv;
}

That is really all we need. Of course you can easily change the condition from a 'like' to a full match..


You could also search in the XML data and hide rows from the DGV, but it won't get any simpler than the above code, just a little closer to your original question..

Here is how to search an XDocument xDoc:

var found = xDoc.Descendants(combo_fields.Text)
                .Where(x => x.Value.Contains( tb_filter.Text))
                .Select(x => x.Value).ToList();

Now you can use the list of strings to decide which rows we will hide:

dataGridView1.CurrentCell = null;  // necessary, so we don't try to hide the current row

foreach(DataGridViewRow row in dataGridView1.Rows)
{
    if (row.Cells[combo_fields.Text].Value != null)
        row.Visible = found.Contains(row.Cells["Location"].Value.ToString());
}

After we are done we can clear the filter TextBox to bring up all rows and and we can save the data..:

tb_filter.Text = "";

ds.Tables[0].WriteXml(someFileName);

Upvotes: 1

Related Questions