单击“添加”按钮后,为什么输入的数据会消失?

时间:2017-04-14 19:19:00

标签: asp.net vb.net gridview

我们有几个Gridview控件,grvSource和grvSpouse,当你点击下面每个截图的Add按钮时,每个控件都会动态添加额外的行:

enter image description here

在标有 1 的顶部图片上,用户将数据输入三个单元格中的每一个,然后点击添加按钮以创建其他行。

问题是,点击添加按钮后,输入第一行的数据会消失,如标有 2 的图片所示。

为什么会发生这种情况?

<asp:GridView ID="grvSource" AutoGenerateColumns="false" gridlines="None" ShowFooter="true" runat="server" OnRowDataBound="grvSource_RowDataBound"
        OnRowDeleting="grvSource_RowDeleting">
        <Columns>
            <asp:TemplateField HeaderText="Name">
                            <headerstyle horizontalalign="Left" />
                <ItemTemplate>
                    <asp:TextBox ID="txtsourcename" placeholder="Name..." runat="server" Style="width: 250px;
                        height: 20px" class="form-control"></asp:TextBox>
                </ItemTemplate>
            </asp:TemplateField>
                <asp:TemplateField HeaderText="Address">
                                <headerstyle horizontalalign="Center" />
                <ItemTemplate>
                    <asp:TextBox ID="txtsourceaddress" placeholder="Address..." runat="server" Style="width: 250px;
                        height: 20px" class="form-control"></asp:TextBox>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="Income">
                            <headerstyle horizontalalign="Center" />
                <ItemTemplate>
                    <asp:TextBox ID="txtsourceincome" placeholder="Income..." runat="server" Style="width: 250px;
                        height: 20px" class="form-control"></asp:TextBox>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="&nbsp;">
                <ItemTemplate>
                    <asp:Button ID="ButtonAdd1" runat="server" Text="Add" OnClick="ButtonAdd1_Click" CssClass="grvAddButton" OnClientClick="return ValidateEmptyValue();" />
                </ItemTemplate>
            </asp:TemplateField>
            <asp:CommandField ShowDeleteButton="True">
                <ControlStyle CssClass="grvDelButton" />
            </asp:CommandField>
        </Columns>
    </asp:GridView>
    <br />
<asp:GridView ID="grvSpouse" AutoGenerateColumns="false" gridlines="None" ShowFooter="true" runat="server" OnRowDataBound="grvSpouse_RowDataBound"
        OnRowDeleting="grvSpouse_RowDeleting">
        <Columns>
            <asp:TemplateField HeaderText="Name">
                            <headerstyle horizontalalign="Left" />
                <ItemTemplate>
                    <asp:TextBox ID="txtspousename" placeholder="Name..." runat="server" Style="width: 250px;
                        height: 20px" class="form-control"></asp:TextBox>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="Address">
                            <headerstyle horizontalalign="Center" />
                <ItemTemplate>
                    <asp:TextBox ID="txtspouseaddress" placeholder="Address..." runat="server" Style="width: 250px;
                        height: 20px" class="form-control"></asp:TextBox>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="Income">
                            <headerstyle horizontalalign="Center" />
                <ItemTemplate>
                    <asp:TextBox ID="txtspouseincome" placeholder="Income..." runat="server" Style="width: 250px;
                        height: 20px" class="form-control"></asp:TextBox>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="&nbsp;">
                <ItemTemplate>
                    <asp:Button ID="ButtonAdd2" runat="server" Text="Add" OnClick="ButtonAdd2_Click"
                         CssClass="grvAddButton" OnClientClick="return ValidateSPEmptyValue();" />
                </ItemTemplate>
            </asp:TemplateField>
            <asp:CommandField ShowDeleteButton="True">
                <ControlStyle CssClass="grvDelButton" />
            </asp:CommandField>
        </Columns>
    </asp:GridView>

'//Codefile
    Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
        If Not IsPostBack Then
          Me.SetInitialRow()  
        End If
    End Sub

        Private Sub SetInitialRow()
            Dim dt As New DataTable()
            Dim dr As DataRow = Nothing
            dt.Columns.Add(New DataColumn("RowNumber", GetType(String)))
            dt.Columns.Add(New DataColumn("Column1", GetType(String)))
            dt.Columns.Add(New DataColumn("Column2", GetType(String)))
            dt.Columns.Add(New DataColumn("Column3", GetType(String)))
            dr = dt.NewRow()
            dr("RowNumber") = 1
            dr("Column1") = String.Empty
            dr("Column2") = String.Empty
            dr("Column3") = String.Empty
            dt.Rows.Add(dr)
            ViewState("CurrentTable" & 0) = dt
            ViewState("CurrentTable" & 1) = dt
            BindGridview()
    End Sub

        Private Sub BindGridview()
            Dim dt As DataTable = DirectCast(ViewState("CurrentTable" & 0), DataTable)
            grvSource.DataSource = dt
            grvSource.DataBind()
            Dim dt1 As DataTable = DirectCast(ViewState("CurrentTable" & 1), DataTable)
        grvSpouse.DataSource = dt1
    End Sub

    Protected Sub GrvSource_RowDataBound(sender As Object, e As GridViewRowEventArgs)
        If e.Row.RowType = DataControlRowType.Header Then
            If e.Row.RowIndex = -1 Then
                DirectCast(DirectCast(e.Row.Cells(4), DataControlFieldCell).ContainingField, CommandField).ShowDeleteButton = False
            End If
        Else

            If Convert.ToInt32(ViewState("rowIndex" & 0)) = e.Row.RowIndex Then
                DirectCast(DirectCast(e.Row.Cells(4), DataControlFieldCell).ContainingField, CommandField).ShowDeleteButton = True
            End If
        End If
    End Sub
    Protected Sub GrvSpouse_RowDataBound(sender As Object, e As GridViewRowEventArgs)
        If e.Row.RowType = DataControlRowType.Header Then
            If e.Row.RowIndex = -1 Then
                DirectCast(DirectCast(e.Row.Cells(4), DataControlFieldCell).ContainingField, CommandField).ShowDeleteButton = False
            End If
        Else

            If Convert.ToInt32(ViewState("rowIndex" & 1)) = e.Row.RowIndex Then
                DirectCast(DirectCast(e.Row.Cells(4), DataControlFieldCell).ContainingField, CommandField).ShowDeleteButton = True
            End If
        End If
    End Sub

    Private Sub AddNewRowToGrid(viewId As Integer, gv As GridView)
        Dim rowIndex As Integer = 0
        If ViewState("CurrentTable" & viewId) IsNot Nothing Then
            Dim dtCurrentTable As DataTable = DirectCast(ViewState("CurrentTable" & viewId), DataTable)
            Dim drCurrentRow As DataRow = Nothing
            If dtCurrentTable.Rows.Count > 0 Then
                For i As Integer = 1 To dtCurrentTable.Rows.Count
                    Dim box1 As New TextBox()
                    Dim box2 As New TextBox()
                    Dim box3 As New TextBox()
                    If viewId = 0 Then
                        box1 = DirectCast(gv.Rows(rowIndex).Cells(1).FindControl("txtsourcename"), TextBox)
                        box2 = DirectCast(gv.Rows(rowIndex).Cells(2).FindControl("txtsourceaddress"), TextBox)
                        box3 = DirectCast(gv.Rows(rowIndex).Cells(3).FindControl("txtsourceincome"), TextBox)
                    End If
                    If viewId = 1 Then
                        box1 = DirectCast(gv.Rows(rowIndex).Cells(1).FindControl("txtspousename"), TextBox)
                        box2 = DirectCast(gv.Rows(rowIndex).Cells(2).FindControl("txtspouseaddress"), TextBox)
                        box3 = DirectCast(gv.Rows(rowIndex).Cells(3).FindControl("txtspouseincome"), TextBox)
                    End If
                    drCurrentRow = dtCurrentTable.NewRow()
                    drCurrentRow("RowNumber") = i + 1
                    dtCurrentTable.Rows(i - 1)("Column1") = box1.Text
                    dtCurrentTable.Rows(i - 1)("Column2") = box2.Text
                    dtCurrentTable.Rows(i - 1)("Column3") = box3.Text
                    rowIndex += 1
                Next

                dtCurrentTable.Rows.Add(drCurrentRow)
                ViewState("CurrentTable" & viewId) = dtCurrentTable
                gv.DataSource = dtCurrentTable
                gv.DataBind()
            End If
        Else

            Response.Write("ViewState is null")
        End If

        SetPreviousData(viewId, gv)
    End Sub

    Private Sub SetPreviousData(viewId As Integer, gv As GridView)
        Dim rowIndex As Integer = 0

        If ViewState("CurrentTable" & viewId) IsNot Nothing Then
            Dim dt As DataTable = DirectCast(ViewState("CurrentTable" & viewId), DataTable)
            If dt.Rows.Count > 0 Then
                For i As Integer = 0 To dt.Rows.Count - 1
                    Dim box1 As New TextBox()
                    Dim box2 As New TextBox()
                    Dim box3 As New TextBox()
                    If viewId = 0 Then
                        box1 = DirectCast(gv.Rows(rowIndex).Cells(1).FindControl("txtsourcename"), TextBox)
                        box2 = DirectCast(gv.Rows(rowIndex).Cells(2).FindControl("txtsourceaddress"), TextBox)
                        box3 = DirectCast(gv.Rows(rowIndex).Cells(3).FindControl("txtsourceincome"), TextBox)
                    End If
                    If viewId = 1 Then
                        box1 = DirectCast(gv.Rows(rowIndex).Cells(1).FindControl("txtspousename"), TextBox)
                        box2 = DirectCast(gv.Rows(rowIndex).Cells(2).FindControl("txtspouseaddress"), TextBox)
                        box3 = DirectCast(gv.Rows(rowIndex).Cells(3).FindControl("txtspouseincome"), TextBox)
                    End If
                    box1.Text = dt.Rows(i)("Column1").ToString()
                    box2.Text = dt.Rows(i)("Column2").ToString()
                    box3.Text = dt.Rows(i)("Column3").ToString()
                    rowIndex += 1
                Next
            End If
        End If
    End Sub  

     Protected Sub ButtonAdd1_Click(sender As Object, e As EventArgs)
        Dim row As GridViewRow = TryCast(TryCast(sender, Button).NamingContainer, GridViewRow)
        If grvSource.Rows.Count - 1 = row.RowIndex Then
            ViewState("rowIndex" & 0) = row.RowIndex
        End If

        AddNewRowToGrid(0, grvSource)
        Me.BindGridview()
    End Sub
    Protected Sub ButtonAdd2_Click(sender As Object, e As EventArgs)
        Dim row As GridViewRow = TryCast(TryCast(sender, Button).NamingContainer, GridViewRow)
        If grvSpouse.Rows.Count - 1 = row.RowIndex Then
            ViewState("rowIndex" & 1) = row.RowIndex
        End If

        AddNewRowToGrid(1, grvSpouse)
        Me.BindGridview()
    End Sub   

'///Errors:

There is no row at position -1. 
  Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

 Exception Details: System.IndexOutOfRangeException: There is no row at position -1.

Source Error: 

Line 231:                    drCurrentRow = dtCurrentTable.NewRow()
Line 232:                    drCurrentRow("RowNumber") = i + 1
Line 233:                    dtCurrentTable.Rows(i - 1)("Column1") = box1.Text
Line 234:                    dtCurrentTable.Rows(i - 1)("Column2") = box2.Text
Line 235:                    dtCurrentTable.Rows(i - 1)("Column3") = box3.Text

 Source File:  C:\inetpub\wwwroot\folder\closures.aspx.vb    Line:  233 

 Line 233 starts from here:

 dtCurrentTable.Rows(i - 1)("Column1") = box1.Text

 on the AddNewRowToGrib sub.

 This has been the consistent error.

 This error occurs when I enter data into the first row and click the Add button to add another row

 I remove the "0" in CurrentTable, when I try to run the code, I get the following error:

 Object reference not set to an instance of an object. 
   Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

  Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.

 Source Error: 

 Line 87:         Dim dtCurrentTable As DataTable = DirectCast(ViewState("CurrentTable"), DataTable)
 Line 88:         If e.Row.RowType = DataControlRowType.DataRow Then
 Line 89:             If dtCurrentTable.Rows.Count > 0 Then
 ---
 ---

1 个答案:

答案 0 :(得分:0)

您的问题是您希望表格中的数据显示在文本框中,但事实并非如此。您必须将单元格中的Textbox.Text设置为要在该单元格中显示的数据。从IDE代码窗口顶部的下拉列表中,从左侧选择一个grvSource,从右侧选择一个RowDataBound。在为GridView副本创建的RowDataBound事件中:

        Dim dtCurrentTable As DataTable = DirectCast(ViewState("CurrentTable0"), DataTable)
        If e.Row.RowType = DataControlRowType.DataRow Then
            If dtCurrentTable.Rows.Count > 0 Then
                If e.Row.Cells.Count > 0 Then
                    'The textbox's start in cell 3 (index 2)
                    Dim box1 As TextBox = DirectCast(e.Row.Cells(2).FindControl("txtsourcename"), TextBox)
                    Dim box2 As TextBox = DirectCast(e.Row.Cells(3).FindControl("txtsourceaddress"), TextBox)
                    Dim box3 As TextBox = DirectCast(e.Row.Cells(4).FindControl("txtsourceincome"), TextBox)
                    'Handle any Null data 
                    box1.Text = If(IsDBNull(dtCurrentTable.Rows(e.Row.RowIndex)("column1")), "", dtCurrentTable.Rows(e.Row.RowIndex)("column1"))
                    box2.Text = If(IsDBNull(dtCurrentTable.Rows(e.Row.RowIndex)("column2")), "", dtCurrentTable.Rows(e.Row.RowIndex)("column2"))
                    box3.Text = If(IsDBNull(dtCurrentTable.Rows(e.Row.RowIndex)("column3")), "", dtCurrentTable.Rows(e.Row.RowIndex)("column3"))
                End If
            End If
        End If
相关问题