[Webinar] Streamline your web hosting managementRegister Today

x
?
Solved

Gridview - Add/remove rows on the fly without a database

Posted on 2008-02-11
22
Medium Priority
?
1,902 Views
Last Modified: 2013-11-26
I have a gridview created blank on the fly. At the end of every row, there's an Add/Remove link button that will add/remove rows. I have one textbox field they have to enter.
As they add new rows, the text they have entered in previous rows has to be displayed. Although I see this text (in debug mode), I can't display it in the table as I loop through the gridviewrow.

The error is: "Type of value has a mismatch with column type"

Thanks
Here's the sub that builds a blank gridview with one row:
    Private Sub BuildUploadTable()
        Dim dt As New DataTable
        Dim dc As New DataColumn("description")
        dtFiles.Columns.Add(dc)
        Dim dr As DataRow = dtFiles.NewRow
        dr("description") = "None"
        dtFiles.Rows.Add(dr)
        dsFiles.Tables.Add(dtFiles)
        'gFiles.DataSource = dsFiles
        gvFiles.DataSource = dtFiles
        gvFiles.DataBind()
        gvFiles.Visible = True
    End Sub
 
Here's the part that's problematic:
    Protected Sub gvFiles_RowCommand(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewCommandEventArgs) Handles gvFiles.RowCommand
        If dtFiles.Rows.Count = 0 Then
            dtFiles.Columns.Add("tbDesc", GetType(TextBox))
            dtFiles.Columns.Add("Add", GetType(ButtonColumn))
            dtFiles.Columns.Add("Remove", GetType(ButtonColumn))
        End If
        'Convert datagrid to dt
        Dim gr As GridViewRow
        Dim nr As DataRow
 
        For Each gr In gvFiles.Rows
            nr = dtFiles.NewRow
'BEGIN PROBLEM
            nr(0) = CType(gr.FindControl("tbDesc"), TextBox).Text 
            nr(1) = "Add"
            nr(2) = "Remove"
'END PROBLEM
            dtFiles.Rows.Add(nr)
        Next
 
        If e.CommandName = "Add" Then
            'Add new row to dt
            nr = dtFiles.NewRow
            dtFiles.Rows.Add(nr)
            dsFiles.Tables.Add(dtFiles)
            gvFiles.DataSource = dtFiles
            gvFiles.DataBind()
            gvFiles.Visible = True
        ElseIf e.CommandName = "Remove" Then
            dtFiles.Rows.RemoveAt(gvFiles.Rows(e.CommandArgument).RowIndex)
            dsFiles.Tables.Add(dtFiles)
            gvFiles.DataSource = dtFiles
            gvFiles.DataBind()
            gvFiles.Visible = True
        End If
    End Sub

Open in new window

0
Comment
Question by:tucson
  • 12
  • 10
22 Comments
 
LVL 96

Expert Comment

by:Bob Learned
ID: 20870912
You should be able to add/insert rows into the DataTable datasource, and rebind to get new rows.

Bob
0
 
LVL 1

Author Comment

by:tucson
ID: 20906671
I added and removed rows successfully in the sample code above. The problem is displaying the previous row contents when a new row is added. I can see the textbox value in the table and dataset in debug mode but can't assign those values back into the gridview to be displayed.
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 20906699
If you are correctly re-binding the GridView to the DataTable after adding a row, I don't see why it shouldn't work as expected.

Bob
0
The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

 
LVL 1

Author Comment

by:tucson
ID: 20928728
Please look at my code snippet. I can see the values in the dataset and datatable but once I rebind it, it's not in the gridview. Thanks.
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 20928830
I did look at your code, and I was trying to say that there is some missing bit of information to show why you are having a problem, because the code doesn't show it.

Bob
0
 
LVL 1

Author Comment

by:tucson
ID: 20931099
EnableViewState is True for the gridview.
I'm not sure what else to look for (what "missing bit"?) It doesn't show what?
0
 
LVL 1

Author Comment

by:tucson
ID: 20938554
It seems like my problem is that I'm trying to store the fileupload and textbox objects into the gridview AS WELL AS trying to store the string values of the fileupload and the textbox contents. And I can't do that? When I preview the datatable, the objects are in there but the values can't be displayed because the gridview also needs to display the objects.
I tried a placeholder but it doesn't work either.
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 20939348
Are you saying that you have a TemplateField defined with a FileUpload control and a TextBox in the same template?

Bob
0
 
LVL 1

Author Comment

by:tucson
ID: 20939439
No they are 2 in different template columns. But I want to display the fileupload and textbox objects and their perviously entered values each time a new blank row is added.

In this example: http://geekswithblogs.net/casualjim/archive/2006/05/04/77151.aspx, you keep the fileupload/textbox objects in the footer row and adds the records into the gridview rows as labels. I want every row to be like the footer row in this example. I may just decide to to the footer row method since I'm not sure if what I'm trying to accomplish can be done in a gridview.
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 20939711
How do you define your columns?  Through the designer?  In code?

You can't do this:

           dtFiles.Columns.Add("Add", GetType(ButtonColumn))
            dtFiles.Columns.Add("Remove", GetType(ButtonColumn))
 
And, then this:

            nr(1) = "Add"
            nr(2) = "Remove"

The type is not string, so you would need to add a ButtonColumn object.  I don't think that is what you meant to do.

Bob
0
 
LVL 1

Author Comment

by:tucson
ID: 20939788
I added the columns through the designer.
The code below displays the blank rows with the appropriate controls when I added a new row.
The problem is that I can't display the values that were entered in the previous row as they add new rows. Every row is blank. The datatable and gridview only store the controls and can't display the values.
In the example below, I can't do:
nr(0) = fileU.FileName
nr(1) = tb.text, which is what I want to do.
       For Each gr In gFiles.Rows
            nr = dtFiles.NewRow
            fileU = CType(gr.FindControl("FileToUpload"), FileUpload)
            tb = CType(gr.FindControl("tbDesc"), TextBox)
            bAdd = CType(gr.FindControl("btnAdd"), LinkButton)
            nr(0) = fileU
            nr(1) = tb
            nr(2) = bAdd
            dtFiles.Rows.Add(nr)
        Next
            gFiles.DataSource = dtFiles
            gFiles.DataBind()

Open in new window

0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 20939904
So, you want a dynamic number of file uploads, instead of a fixed number of rows (the usual way of doing business)?

Bob
0
 
LVL 1

Author Comment

by:tucson
ID: 20939929
Yes, because the range of number of uploads varies from 1 to 30.
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 20940113
Does the <Add> button just insert a new row to upload?  After you upload are you keeping track of the file name?

Bob
0
 
LVL 1

Author Comment

by:tucson
ID: 20940441
The upload will occur as a batch, at the very end.
Yes, the Add button adds an empty row. I need to keep track of all the previous rows already entered before finally doing a batch upload.
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 20940489
Attached is my version of a dynamic uploader page.

Bob
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 20940492

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="DynamicUploader.aspx.vb"
    Inherits="DynamicUploader" %>
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <title>Untitled Page</title>
    <style type="text/css">
        body { font-family: Tahoma; font-size: 10pt; }
    </style>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <asp:GridView ID="GridView1" runat="server" Height="50%" Width="100%" AutoGenerateColumns="False"
                Font-Names="Tahoma" Font-Size="10pt" OnRowCommand="GridView1_RowCommand" OnRowDataBound="GridView1_RowDataBound">
                <Columns>
                    <asp:TemplateField HeaderText="Upload">
                        <ItemTemplate>
                            <asp:FileUpload ID="FileUpload" runat="server" Font-Names="Tahoma" Font-Size="10pt"
                                Width="100%" />
                            <asp:TextBox ID="FileName" runat="server" Width="100%" Visible="false" Text='<%# Eval("FileName") %>'></asp:TextBox>
                        </ItemTemplate>
                        <HeaderStyle Width="30%" />
                    </asp:TemplateField>
                    <asp:BoundField DataField="Description" HeaderText="Description">
                        <HeaderStyle Width="40%" />
                    </asp:BoundField>
                    <asp:ButtonField CommandName="Add" Text="Add">
                        <HeaderStyle Width="5%" />
                    </asp:ButtonField>
                </Columns>
            </asp:GridView>
        </div>
    </form>
</body>
</html>

Open in new window

0
 
LVL 96

Accepted Solution

by:
Bob Learned earned 500 total points
ID: 20940494

Imports System
Imports System.Data
 
Partial Public Class DynamicUploader
  Inherits System.Web.UI.Page
 
  Private _UploadData As DataTable
 
  Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
 
    If Not Page.IsPostBack Then
      Me.CreateUploadTable()
    Else
      _UploadData = DirectCast(Session("UploadData"), DataTable)
    End If
 
    Me.GridView1.DataSource = _UploadData
    Me.GridView1.DataBind()
  End Sub
 
  Protected Sub GridView1_RowCommand(ByVal sender As Object, ByVal e As GridViewCommandEventArgs)
    If e.CommandName = "Add" Then
      Me.SaveUploadedFileNames()
 
      Dim dr As DataRow = _UploadData.NewRow()
 
      _UploadData.Rows.Add(dr)
 
      Session("UploadData") = _UploadData
 
      Me.GridView1.DataSource = _UploadData
      Me.GridView1.DataBind()
    End If
  End Sub
 
  Private Sub CreateUploadTable()
    _UploadData = New DataTable("Upload")
 
    _UploadData.Columns.Add("FileName")
    _UploadData.Columns.Add("Description")
 
    Dim dr As DataRow = _UploadData.NewRow()
 
    _UploadData.Rows.Add(dr)
 
    Session("UploadData") = _UploadData
  End Sub
 
  Private Sub SaveUploadedFileNames()
    For i As Integer = 0 To Me.GridView1.Rows.Count - 1
      Dim row As GridViewRow = Me.GridView1.Rows(i)
 
      Dim upload As FileUpload = TryCast(row.FindControl("FileUpload"), FileUpload)
      Dim textBox As TextBox = TryCast(row.FindControl("FileName"), TextBox)
 
      If upload IsNot Nothing AndAlso textBox IsNot Nothing AndAlso textBox.Text.Length = 0 Then
        Dim dr As DataRow = _UploadData.Rows(i)
        dr("FileName") = upload.FileName
      End If
    Next
    Session("UploadData") = _UploadData
  End Sub
 
  Protected Sub GridView1_RowDataBound(ByVal sender As Object, ByVal e As GridViewRowEventArgs)
    Dim upload As FileUpload = TryCast(e.Row.FindControl("FileUpload"), FileUpload)
    Dim textBox As TextBox = TryCast(e.Row.FindControl("FileName"), TextBox)
 
    If upload IsNot Nothing AndAlso textBox IsNot Nothing Then
      textBox.Visible = (textBox.Text.Length > 0)
      upload.Visible = Not textBox.Visible
    End If
  End Sub
End Class

Open in new window

0
 
LVL 1

Author Comment

by:tucson
ID: 20940726
Thanks, I'm looking into this after lunch.
0
 
LVL 1

Author Comment

by:tucson
ID: 20941906
You are indeed a genius. Thank you for taking the time. You put the fileupload and a textbox in the same template column and hide/unhide the textbox. The textbox is used to store the filename for displaying it further.
Thanks
0
 
LVL 1

Author Closing Comment

by:tucson
ID: 31429947
I didn't expect to have the code provided to me at all. Initially his responses were vague ("missing things," "should work"). But at the end it's very clear. I will try to modify his code so that users can still browse to get their files even after a new row is inserted, perhaps create my own FileUpload subclass.
0
 
LVL 1

Author Comment

by:tucson
ID: 20979722
Sorry to open this ticket again. When I upload the files at the end, what's the best way to read/write the files to upload them to the server? Since the upload control is no longer there (just the path is stored in a textbox), I can't call FileUpload.SaveAs method.
Thanks
0

Featured Post

Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

ASP.Net to Oracle Connectivity Recently I had to develop an ASP.NET application connecting to an Oracle database.As I am doing it first time ,I had to solve several problems. This article will help to such developers  to develop an ASP.NET client…
Today I had a very interesting conundrum that had to get solved quickly. Needless to say, it wasn't resolved quickly because when we needed it we were very rushed, but as soon as the conference call was over and I took a step back I saw the correct …
How can you see what you are working on when you want to see it while you to save a copy? Add a "Save As" icon to the Quick Access Toolbar, or QAT. That way, when you save a copy of a query, form, report, or other object you are modifying, you…
SQL Database Recovery Software repairs the MDF & NDF Files, corrupted due to hardware related issues or software related errors. Provides preview of recovered database objects and allows saving in either MSSQL, CSV, HTML or XLS format. Ensures recov…
Suggested Courses

591 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question