views:

51

answers:

3

Is DataRow.NewRow() insufficient as the only row in a DataTable? I would expect this to work, but it doesn't. It's near the end of my Page_Load inside my If(!Postback) block. gridCPCP is GridView

DataTable dt = new DataTable();
dt.Columns.Add("ID", int.MinValue.GetType());
dt.Columns.Add("Code", string.Empty.GetType());
dt.Columns.Add("Date", DateTime.MinValue.GetType());
dt.Columns.Add("Date2", DateTime.MinValue.GetType());
dt.Columns.Add("Filename", string.Empty.GetType());

//code to add rows

if (dt.Rows.Count > 0)
{
    gridCPCP.DataSource = dt;
    gridCPCP.DataBind();
}
else
{
    dt.Rows.Add(dt.NewRow());
    gridCPCP.DataSource = dt;
    gridCPCP.DataBind(); //EXCEPTION
    int TotalColumns = gridCPCP.Rows[0].Cells.Count;
    gridCPCP.Rows[0].Cells.Clear();
    gridCPCP.Rows[0].Cells.Add(new TableCell());
    gridCPCP.Rows[0].Cells[0].ColumnSpan = TotalColumns;
    gridCPCP.Rows[0].Cells[0].Text = "No Record Found";   
}

The exception throws on gridCPCP.DataBind() and only when execution reaches the else block. If there were rows added above via dt.Rows.Add(new object[] { ... } binding works.

System.ArgumentOutOfRangeException: Length cannot be less than zero. Parameter name: length

+1  A: 

Sorry that I'm not answering your exact question but checking the code on the else block I wonder... why don't you use the GridView.EmptyDataTemplate for the case you query returned no data?

Claudio Redi
I tried adding `<EmptyDataTemplate>No data found.</EmptyDataTemplate>` before the closing GridView tag and it doesn't behave any different.
David
Have you removed if (dt.Rows.Count > 0) when testing the EmptyDataTemplate?
Claudio Redi
that's slick, thank you!
David
+2  A: 

Exception is because of the empty row. You should:

  1. Make a new .NewRow()
  2. Add desired fields
  3. Add into the DataTable.

-

myRow = dt.NewRow();
myRow["ID"] = 1001;
myRow["Code"] = "YourCode";

dt.Rows.Add(myRow);
gridCPCP.DataSource = dt;
gridCPCP.DataBind(); 
KMan
All fields were required to make it work. My example is trivial compared to a problem with more than 100 columns. How could I avoid setting a dummy value for each and every column?
David
@David: Usually when details are coming in from UI, you will *have to* set the fields manually. If the details are coming from some datastore then you may choose your fields in the `select` statement and then you can bind the datasource.
KMan
@David: Also, for empty values, you can `SELECT * FROM YOURTABLE WHERE 1>2` to set into your datasource.
KMan
no data source in my example. most resources on the interwebs call for a sqldatasource or at least an objectdatasource, but i chose the gridview and datatable for a pretty ui and a lack of other options im aware of. i just needed to do some file io here.
David
+1  A: 

This doesn't really answer the question either, but my solution would probably be to not bother calling the DataBind() method at all if there are no rows, and put the error message in a asp:Literal outside of the GridView, which gets shown only if there are no rows.

joelt