0

I do not want to bind it till its been looped through. What I have here is a csv file uploaded to a gridview.I would like to loop through it before it is bound. Any Advice is great.

   protected void btnUpload_Click(object sender, EventArgs e)
     {
         if (FileUpload1.HasFile)
        try
        {
            FileUpload1.SaveAs(Server.MapPath("") +
                 FileUpload1.FileName);
            Label1.Text = "File name: " +
                 FileUpload1.PostedFile.FileName + "<br>" +
                 FileUpload1.PostedFile.ContentLength + " kb<br>" +
                 "Content type: " +
                 FileUpload1.PostedFile.ContentType + "<br><b>Uploaded Successfully";
        }
        catch (Exception ex)
        {
            Label1.Text = "ERROR: " + ex.Message.ToString();
        }
    else
    {
        Label1.Text = "You have not specified a file.";
    }



        CSVReader reader = new CSVReader(FileUpload1.PostedFile.InputStream);
        string[] headers = reader.GetCSVLine();
        DataTable dt = new DataTable();

        foreach (string strHeader in headers)
            dt.Columns.Add(strHeader);
        string[] data;
        while ((data = reader.GetCSVLine()) != null)
            dt.Rows.Add(data);
        csvReaderGv.DataSource = dt;

        csvReaderGv.DataBind();


            }



    }
Jay
  • 41
  • 8
  • What prevents you from doing `foreach(DataRow row in dt.Rows)...`? – Tim Schmelter Aug 20 '13 at 19:30
  • Do I put that before the csvReaderGv.DataSource = dt; csvReaderGv.DataBind(); or after. Its confusion that is preventing me. – Jay Aug 20 '13 at 19:33
  • Yes, because your requirement is: _"I would like to loop through it before it is bound"_. This question is a little bit strange, isn't it? – Tim Schmelter Aug 20 '13 at 19:34
  • Didn't think the question was strange. Sorry for that, I was really trying to be as clear as I could. – Jay Aug 20 '13 at 19:37

3 Answers3

0

Try this:

// Loop through each row in the data table
foreach (DataRow row in dt.Rows) 
{
    // Loop through each column in row
    for (int i = 0; i <= dt.Columns.Count - 1; i++) 
    {
        // Do whatever you want here for each cell
    }
}

Here is what your code should look like:

protected void btnUpload_Click(object sender, EventArgs e)
{
    if (FileUpload1.HasFile)
    {
        try
        {
            FileUpload1.SaveAs(Server.MapPath("") + FileUpload1.FileName);
            Label1.Text = "File name: " +
            FileUpload1.PostedFile.FileName + "<br>" +
            FileUpload1.PostedFile.ContentLength + " kb<br>" + "Content type: " +
             FileUpload1.PostedFile.ContentType + "<br><b>Uploaded Successfully";
        }
        catch (Exception ex)
        {
            Label1.Text = "ERROR: " + ex.Message.ToString();
        }
    }
    else
    {
        Label1.Text = "You have not specified a file.";
    }

    CSVReader reader = new CSVReader(FileUpload1.PostedFile.InputStream);
    string[] headers = reader.GetCSVLine();
    DataTable dt = new DataTable();

    foreach (string strHeader in headers)
    {
        dt.Columns.Add(strHeader);
    }

    string[] data;
    while ((data = reader.GetCSVLine()) != null)
    {
        dt.Rows.Add(data);
    }

    // Loop through each row in the data table
    foreach (DataRow row in dt.Rows) 
    {
        // Loop through each column in row
        for (int i = 0; i <= dt.Columns.Count - 1; i++) 
        {
            // Do whatever you want here for each cell
        }
    }

    csvReaderGv.DataSource = dt;
    csvReaderGv.DataBind();
}
Karl Anderson
  • 34,606
  • 12
  • 65
  • 80
  • do I put it before or after binding where to put the foreach is what is confusing me. – Jay Aug 20 '13 at 19:35
0

Firstly, get your data;

CSVReader reader = new CSVReader(FileUpload1.PostedFile.InputStream);
string[] headers = reader.GetCSVLine();
DataTable dt = new DataTable();

foreach (string strHeader in headers)
{
    dt.Columns.Add(strHeader);
}       

string[] data;

while ((data = reader.GetCSVLine()) != null)
{
    dt.Rows.Add(data);
}

Secondly, process your data what ever way you want;

foreach (DataRow row in dt.Rows) 
{
    // do what you want with it
}

Thirdly, when you have nothing else left to do with the data, bind it;

csvReaderGv.DataSource = dt;
csvReaderGv.DataBind();
Tim B James
  • 20,084
  • 4
  • 73
  • 103
0

Your question is not really clear. You're asking how to loop a DataTable before you databind it. So what prevents you from simply doing:

foreach(DataRow row in dt.Rows)
{
    // do something with the row and it's fields, e.g.
    string field1 = row.Field<string>(0);
    // or all columns_
    foreach(DataColumn col in dt.Columns)
    {
        string field = row.Field<string>(col);
    }
}
csvReaderGv.DataBind();

But i assume that you want to know what is the best way to loop a DataTable that is bound to an ASP.NET GridView. I suggest to use the RowDataBound which enables to access all rows in the table and also all rows in the GridView:

protected void csvReaderGv_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        DataRow row = ((DataRowView) e.Row.DataItem).Row;
        string col1 = row.Field<string>(0);
        // set first cell in GridViewRow:
        e.Row.Cells[0].Text = col1;
    }
}

This event is triggered for every row in the grid as soon as you DataBind it to it's DataSource anyway at this line:

 csvReaderGv.DataBind();

So it is the "cheapest" loop. Note that it's triggered only if you DataBind it, so not necessarily on every postback. If you need to access the GridViewRows on every postback(for example to create dynamic controls in the grid) you should use RowCreated instead.

Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
  • Thank you very much, will this also allow me to only have whatever columns I want show up. – Jay Aug 20 '13 at 21:03
  • @Jay: I must admit that i've not understood your comment. If you want to hide columns use `GridView.Columns[index].Visible = false;`. If you want to hide cells (or do something other like apply `CSS` or change `ColumnSpan`) use `e.Row.Cells[index].Visible=false;`. – Tim Schmelter Aug 20 '13 at 21:08
  • Sorry, What I was asking was whether after I did the databind that I could use . – Jay Aug 20 '13 at 21:13
  • That's aspx not codebehind. So you can use `BoundFields` or `TemplateFields` and access them (or modify their `Text`) from codebehind. But it's still not clear what you're actually trying to achieve. – Tim Schmelter Aug 20 '13 at 21:15
  • I got what I need from all the help, I much appreciated it. – Jay Aug 20 '13 at 21:23
  • @Jay: Consider to accept an answer then. Otherwise people will think that the question is still open. – Tim Schmelter Aug 20 '13 at 21:24