views:

588

answers:

4

I am declaring a SQL string that looks something similar to the following:

string SQL = "SELECT Column1, Column2, Column3, Date1, Date2 FROM Somewhere";

The number of columns can vary by circumstance and the dates can be called different names such as StartDate, InterestDate and so on.

What I would like to do is bind this to an ASP.NET Repeater and create a table as below for the example above:

<table>
  <tr>
    <th>Column1</th>
    <th>Column2</th>
    <th>Column3</th>
    <th>Date1</th>
    <th>Date2</th>
  </tr>
  <tr>
    Rows of values...
  </tr>
</table>

I am fine with binding the data to a Repeater and using Eval but that is dependant on a fixed number of columns and column names. Can this be done in a programmatic way?

A: 

You could use a GridView which automatically generates columns based on the data source.

Andrew Hare
I could but I specifically need a Repeater so I have full control of the presentation and formatting of the output.
Ian Roke
The GridView is surprisingly customizable - have you tried it yet?
Andrew Hare
It's also surprisingly heavy and avoided by a lot of people... ;)
Chris Lively
I have done GridView customisation in the past but I was never able to format date fields differently depending on if they contained seconds or if they were just dates. I was hoping I could use a Repeater that would give me a lot of control with minimal overhead. That might be another question though.
Ian Roke
If setting the dataformatstring does not get you what you need, you can always handle the rowdatabound event and customize the format of the date fields any way you like.
Jimmie R. Houts
@Jimmie Have you got an example of how I would do this?
Ian Roke
@Ian Roke, I have updated my answer with a sample RowDataBound event
Jimmie R. Houts
+3  A: 

If you use a GridView you can set the AutoGenerate columns property to true (it is true by default) and then bind the GridView to your data.

To make is super simple, you may want to use a SQLDataSource control.

The asp.net site has an overview of databinding in asp.net (uses the ObjectDataSource, but the concepts is exactly the same). This page also covers some of the ways to customize the GridView.

Update: Here is a sample of how you could handle the rowdatabound event to format the date columns (per comments on other answer). This could probably be done better, but this should get you started.

protected void gv_RowDataBound(object sender, GridViewRowEventArgs e)
{
    DataRowView rowView = (DataRowView)e.Row.DataItem;

    for (int i = 0; i < rowView.Row.ItemArray.Length; i++)
    {
        DateTime? tmpDate = rowView[i] as DateTime?;

        if (tmpDate.HasValue)
        {
            if (tmpDate.Value.Second > 0)
                e.Row.Cells[i].Text = tmpDate.Value.ToShortTimeString();
            else
                e.Row.Cells[i].Text = tmpDate.Value.ToShortDateString();
        }
    }
}
Jimmie R. Houts
That's a great tutorial if you know what you are binding too. In this case I don't know what columns are going to come out in which order. The SQL is generated based on filters on an ASP.NET webpage which then creates a string which I want to bind and process.
Ian Roke
This seems like a simple approach. In your example the columns coming from SQL are in the same order as those in the table you generate. Are you saying you may want them in a different order? How would you know?
n8wrl
@n8wrl The date column names are coming from a dropdown on the page and I am sending it as a SQL string to SQL Server and getting my values back. 1 thing I didn't think about I suppose I could just create the code block if the page has been posted back and dump the HTML in a label. It just doesn't feel like the right thing to do.
Ian Roke
@Jimmie Thanks for the code that is interesting.
Ian Roke
A: 

If you use a DataReader to retrieve the data, the columns can be accessed with their indices rather than with their names. You should be able to loop through them all, even if their number is not constant.

<% while(myRepeaterWithData.Read()) {
       for (int i = 0; i < myReaderWithData.FieldCount; i++) { %>
           The data on this row in column number <%= i%> is 
           <%= myRepeaterWithData[i] %>.
<%     }
    } %>
Tomas Lycken
That's an interesting idea but in this case I need to know the column names because they are part of the column headings on the table.
Ian Roke
A: 

Here's a link to an example of dynamically creating a repeater at runtime. The only requirement is that an ASP:Panel be on your form in order to inject it.

http://programming.top54u.com/post/ASP-Net-Repeater-dynamically-using-C-sharp-code.aspx

Chris Lively
Thanks for the link I will have a look into that method of doing things.
Ian Roke