Today, I had to bind a list of countries to a drop down list in ASP.NET 2.0. I wanted to use an XML file to store the countries. There are more than 200 so there was not way I was going to hard code them in the HTML.

I have done this many times before, but never from an XML file. Normally I store the countries in a database, because other database tables would reference it. Today, I just wanted a list of countries with no relation to any data at all.

My plan was clear and simple. Find an XML file of countries on the internet and bind them to a drop down list. How hard could that be? After 15 minutes of searching Google and Live.com for the XML country file I gave up. It wasn’t out there.

Luckily, I have dozens of country tables in various databases I’ve built during the last couple of years, so I generated my own XML list by exporting from SQL server to a CSV file and then created a method in C# that generated the XML file from it.

For anybody else in need for an XML country list, look no further. I’ll share mine with you.

If you want to bind it to a drop down list, here’s the code for that. First add the drop down list to your page:

<asp:DropDownList runat="Server" ID="ddlCountry" />

Then use this C# code to bind the countries to the drop down list:

using System.Xml;

protected void Page_Load(object sender, EventArgs e)
{
   if (!Page.IsPostBack)
      BindCountry();
}

private void BindCountry()
{
   XmlDocument doc = new XmlDocument();
   doc.Load(Server.MapPath("countries.xml"));

   foreach (XmlNode node in doc.SelectNodes("//country"))
   {
      ddlCountry.Items.Add(new ListItem(node.InnerText, node.Attributes["code"].InnerText));
   }
}

Remember to add the countries.xml in the root of your website.

Download countries.xml (12,48 KB)

The GridView is a new web control in ASP.NET 2.0 and is an improvement of the old DataGrid. One of the biggest issues with the DataGrid was the lack of standard compliance and accessibility. This has been fixed in the new GridView along with a lot of other things as well.

When setting the property UseAccessibleHeader = true, it replaces the <td> elements of the header row with the correct <th> which means table header. It also adds the scope property of these header elements making them more accessible.

For some strange reason, there is no property for setting the <thead>, <tbody> and <tfoot> elements which are more important from an accessibility point of view. There is however an easy way of adding these elements in C# and VB.NET.

Let’s add a simple GridView to our page like this:

<asp:GridView runat="server" ID="gvFlowers" />

To add the extra elements, we need this simple method in the code-behind:

private void MakeAccessible(GridView grid)
{
 if (grid.Rows.Count > 0)
 {
  //This replaces <td> with <th> and adds the scope attribute
  grid.UseAccessibleHeader = true;

  //This will add the <thead> and <tbody> elements
  grid.HeaderRow.TableSection = TableRowSection.TableHeader;

  //This adds the <tfoot> element. Remove if you don't have a footer row
  grid.FooterRow.TableSection = TableRowSection.TableFooter;
 }
}

Then we just call the method from the Page_Load event like this:

protected void Page_Load(object sender, EventArgs e)
{
 //Add data to the GridView
 ...

 MakeAccessible(gvFlowers);
}

And this is the actual HTML that is generated:

<table cellspacing="0" rules="all" border="1" id="gvFlowers" style="border-collapse:collapse;">
        <thead>
            <tr>
                <th scope="col">Name</th><th scope="col">Height</th><th scope="col">Width</th>
            </tr>
        </thead><tbody>
            <tr>
                <td>tulip.jpg</td><td>30</td><td>420</td>
            </tr><tr>
                <td>daisy.jpg</td><td>32</td><td>481</td>
            </tr><tr>
                <td>rose.jpg</td><td>54</td><td>530</td>
            </tr>
        </tbody><tfoot>

        </tfoot>
</table>

It is not apparent that you have to dig into the header and footer rows and add a TableSection. This should be done automatically or at least be easy to set through a property at design time. I think it is an obvious mistake, but luckily for us, it is easy to fix if you know where to look.