1

ASP.NET Visual Basic I am trying to update the data of the connected sql table displayed in GridView. But my Visual Basic code doesn't find the VRMModel-TextBox in the GridView. I can see the data in GridView. I click to update the data, it finds the RowIndex but not the TextBox or the GridView-Control. It response the value of VRMModel and ComponentDefect as NOTHING. Here is my code:

Protected Sub GridView1_RowUpdating(ByVal sender As Object, ByVal e As GridViewUpdateEventArgs)
    Dim row As GridViewRow = GridView1.Rows(e.RowIndex)
    Dim VRMModel As TextBox = CType(row.FindControl("VRMModel"), TextBox)
    Dim ComponentDefect As TextBox = CType(row.FindControl("ComponentDefect"), TextBox)
    Dim connectionString As String = ConfigurationManager.ConnectionStrings("VRM_Test").ConnectionString
    Using connection As New SqlConnection(connectionString)
        Using command As New SqlCommand("UPDATE tblVRMModel SET VRMModel = @VRMModel, ComponentDefect = @ComponentDefect ", connection)
            command.Parameters.AddWithValue("@VRMModel", VRMModel)
            command.Parameters.AddWithValue("@ComponentDefect", ComponentDefect)
            connection.Open()
            command.ExecuteNonQuery()
        End Using
    End Using
    GridView1.EditIndex = -1
    BindGrid()
End Sub

What is missing here?

I think the issue happens in the part:

    Dim VRMModel As TextBox = CType(row.FindControl("VRMModel"), TextBox)
    Dim ComponentDefect As TextBox = CType(row.FindControl("ComponentDefect"), TextBox)

It doesn't find any control (Cell of the GridView) to declare it as TextBox to get value of that.

6
  • Can you please edit your question and post the code for the control that isn't being found? If you believe that's where the problem is, we need to see the control in order to determine why it isn't being found. Commented Oct 23, 2024 at 22:53
  • Thanks, devlin carnate. The code is posted. The two lines are part of the posted code. Commented Oct 24, 2024 at 0:23
  • do you have template fields declared for the Gridview in the markup template? Commented Oct 24, 2024 at 6:54
  • Thanks J.Salas, If you mean the .aspx page, yes I have declared field such as: <asp:BoundField DataField="VRMModel" HeaderText="VRMModel" /> Commented Oct 24, 2024 at 18:31
  • Sorry, I wasn't clear. I meant the GridView1 control code on the aspx page so we can see why the textboxes aren't being found with row.FindControl("VRMModel") and row.FindControl("ComponentDefect"). Please edit your question and add those details. Commented Oct 25, 2024 at 15:39

1 Answer 1

0

Why not consider placing ONE save button at the bottom of the GridView, and then allow the user to freely tab around and edit any row (much like in Excel, or even on desktop data grid). Hence, the user can bounce around, tab around and make changes to all rows, and then we have ONE save button.

Above not only presents a common type of UI for editing, but it also dispenses with a convoluted UI and also dispenses with a lot of convoluted code, and trick events for the GridView. Just dump all of the GridView events, and write some clean easy to read code.

Hence, say this markup:

        <style>
            .borderhide input {
                border: none;
                background-color: transparent
            }

            .borderhide textarea {
                border: none;
                background-color: transparent
            }
        </style>


        <asp:GridView ID="GridView1" runat="server"
            AutoGenerateColumns="False" 
            DataKeyNames="ID"
            CssClass="table table-hover borderhide" Width="50%">
            <Columns>
                <asp:TemplateField HeaderText="First"><ItemTemplate>
                    <asp:TextBox ID="txtFirst" runat="server" Text='<%#Eval("FirstName") %>' >
                    </asp:TextBox>
                </ItemTemplate></asp:TemplateField>
                <asp:TemplateField HeaderText="Last"><ItemTemplate>
                    <asp:TextBox ID="txtLast" runat="server" Text='<%#Eval("LastName") %>' >
                    </asp:TextBox>
                </ItemTemplate></asp:TemplateField>
                <asp:TemplateField HeaderText="HotelName"><ItemTemplate>
                    <asp:TextBox ID="txtHotel" runat="server" Text='<%#Eval("HotelName") %>' >
                    </asp:TextBox>
                </ItemTemplate></asp:TemplateField>
                <asp:TemplateField HeaderText="Description">
                    <ItemTemplate>
                        <asp:TextBox ID="txtDescription"
                            runat="server" TextMode="MultiLine"
                            Text='<%# Eval("Description") %>'
                            Height="60px" Width="330px">
                        </asp:TextBox>
                    </ItemTemplate>
                </asp:TemplateField>
            </Columns>
        </asp:GridView>
        <br />
        <asp:Button ID="cmdSave" runat="server" Text="Save/Done"
            CssClass="btn btn-dark"
            OnClick="cmdSave_Click" />

And our code behind is also rather simple.

Dim rstHotels As New DataTable
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    If Not IsPostBack Then
        LoadData()
        Session("rstHotels") = rstHotels
    Else
        rstHotels = Session("rstHotels")
    End If

End Sub


Sub LoadData()

    Dim strSQL =
        "SELECT * FROM tblHotelsA
        WHERE Active = 1
        ORDER BY HotelName"

    rstHotels = MyRst(strSQL)
    GridView1.DataSource = rstHotels
    GridView1.DataBind()

End Sub

Sub GridToTable()

    ' send grid rows back to persisted table

    For Each gRow As GridViewRow In GridView1.Rows
        If gRow.RowType = DataControlRowType.DataRow Then

            Dim OneRow As DataRow = rstHotels.Rows(gRow.DataItemIndex)
            OneRow("FirstName") = DirectCast(gRow.FindControl("txtFirst"), TextBox).Text
            OneRow("LastName") = DirectCast(gRow.FindControl("txtLast"), TextBox).Text
            OneRow("HotelName") = DirectCast(gRow.FindControl("txtHotel"), TextBox).Text
            OneRow("Description") = DirectCast(gRow.FindControl("txtDescription"), TextBox).Text

        End If
    Next

End Sub

Protected Sub cmdSave_Click(sender As Object, e As EventArgs)

    GridToTable()
    Using conn As New SqlConnection(My.Settings.TEST4)
        Using cmdSQL As New SqlCommand("SELECT * FROM tblHotelsA", conn)

            Dim da As New SqlDataAdapter(cmdSQL)
            Dim daU As New SqlCommandBuilder(da)

            conn.Open()
            da.Update(rstHotels)

        End Using
    End Using

    ' at this point all changes saved to database
    ' we no doubt at this point will navagate to another page.
    'Response.Redirect("Some other page.aspx")

End Sub

So, end result is like this:

enter image description here

So, user can tab around, make changes. And then we have one save button, and we also only have one save operation for sending “all of” the edits back to the database.

Also, since one fast becomes tired of typing code over and over to get some table data, then I have these 2 global helper routines that I placed in a standard code module.

Public Function MyRst(strSQL As String, Optional strCon As String = "") As DataTable
    ' general get any data from SQL

    If strCon = "" Then
        strCon = GetConStr()    ' my defualt connection string
    End If
    Dim rstData As New DataTable
    Using conn As New SqlConnection(strCon)
        Using cmdSQL As New SqlCommand(strSQL, conn)
            conn.Open()
            rstData.Load(cmdSQL.ExecuteReader)
            rstData.TableName = strSQL
        End Using
    End Using
    Return rstData
End Function

Public Function MyRstP(cmdSQL As SqlCommand, Optional strCon As String = "") As DataTable
    ' general get any data from SQL command
    If strCon = "" Then strCon = GetConStr()

    Dim rstData As New DataTable
    Using conn As New SqlConnection(strCon)
        Using (cmdSQL)
            cmdSQL.Connection = conn
            conn.Open()
            rstData.Load(cmdSQL.ExecuteReader)
        End Using
    End Using

    Return rstData

End Function
Sign up to request clarification or add additional context in comments.

12 Comments

Thank you, Albert. Your advice helped me. The button "Save" still doesn't save, but I am working on that. I am pretty much new at asp.net, so I have to test things several times to find out how it works.
Thank you, Albert. I could use your code, and it works properly. But now the format of the GridView has changed and when I try to import an Excel file it imports empty cell without the values. I think it has to do with the format of the GridView cells. The values of the GridView cells are in a frame. Similar issue when I want to export the Gridview in an Excel file it exports the formatted cells of the Gridview into the Excel. The GridView Cell values exported with the frame into the Excel cells. What is the issue? Thank you
Concept of separating data operations (code behind) and that of the user interface and display should be considered two different tasks. It not at all clear why exporting from the GV does not work, but then again, that's a bad idea, and you should export the data table that was used to drive the GV in the first place. In other words, go to the data source that filled the GV, and not try to use the GV as some data store, as that is just HTML markup designed for display of data, not for exporting of data. However, if importing issues persist, then I suggest a new question that shows the issue.
Thanks for your quick response Albert. You are right to export data I am supposed to do it direct from sql table and not from GV. But I need to import data from Excel into the GridView. How can I do that since the GV has a formatted cells which makes some issue. Do you have any idea? Thanks a lot in advance.
Well, then import the data from Excel into the database, and then send that same data to the GridView. You can thus allow editing of data, but for a export to Excel after such tasks, then once again, we back to sending the data from the database to Excel, not from the GridView.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.