Gridview RowUpdating Error - Index was out of range - asp.net

When I click the "Update" button in the gridview, it fire the RowUpdating event, but it returns a error "Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index"
The following is the vb code:
Protected Sub GridView1_RowUpdating(ByVal sender As Object, ByVal e As GridViewUpdateEventArgs)
If e.RowIndex >= 0 Then
Dim row As GridViewRow = DirectCast(Gridview1.Rows(e.RowIndex), GridViewRow)
Dim Col1_SL As CheckBox = DirectCast(row.FindControl("cb1_SL"), CheckBox)
.................
Dim cmd As New System.Data.SqlClient.SqlCommand
Dim sql As String
Dim reader As System.Data.SqlClient.SqlDataReader
Using conn As New System.Data.SqlClient.SqlConnection(ConfigurationManager.ConnectionStrings("hris_shiftdutyConnectionString").ConnectionString)
conn.Open()
cmd.Connection = conn
sql = "SET DATEFORMAT dmy;UPDATE troster SET SL='" & Convert.ToInt32(Col1_SL.Checked) & "' where roster_key='" & Col1_RosterKey.Text & "';"
cmd.CommandText = sql
reader = cmd.ExecuteReader()
conn.Close()
reader.Close()
End Using
'Reset the edit index.
Gridview1.EditIndex = -1
'Bind data to the GridView control.
BindData()
End If
End Sub
Please help. Thanks
Joe

Since the ViewState is disabled and you are only databinding when the page is not being posted back, this line is always going to fail:
Dim row As GridViewRow = DirectCast(Gridview1.Rows(e.RowIndex), GridViewRow)
as the count on Gridview1.Rows is going to be 0.
When the page is posted back to the server, ASP.NET needs the ViewState to be enabled for the control so it can recreate the controls and properly determine which events to raise, which control values have changed, etc. You should enable the ViewState, and you'll have to figure out what is causing the control tree error. There must be some other modification that is taking place in the code.
Keep in mind that only databinding the GridView in Page_Load when the page is not posted back is correct, but you won't be able to properly handle events unless you enable ViewState on the control.

Related

Visual Basic ASP.NET Not Reading Unchecked Checkbox Properly

I have a web application that reads from a SQL database to create a gridview. From this gridview I want to select some data and transfer it back to another page via session variable. I have tried to create continuity by checking the boxes previously selected, but if I uncheck them and send the information back, the unchecked box remains in the session variable data.
This is the code that checks the session variable and checks boxes accordingly.
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim String1 As String = ""
Dim String2 As String = ""
Dim boolcheck As Boolean = False
For Each row As DataRow In employeelist.Rows
String1 = row.Item(0)
For Each row2 As GridViewRow In EmployeeListGridView.Rows
String2 = row2.Cells(1).Text
If String1 = String2 Then
Dim checkRow As CheckBox = TryCast(row2.Cells(0).FindControl("checkRow"), CheckBox)
checkRow.Checked = True
End If
Next
Next
End Sub
This is the code that stores a datatable to the session variable
Protected Sub SelectButton_Click(sender As Object, e As EventArgs) Handles SelectButton.Click
Dim dt As New DataTable()
dt.Columns.AddRange(New DataColumn() {New DataColumn("ZID"), New DataColumn("Last Name")})
For Each row As GridViewRow In EmployeeListGridView.Rows
If row.RowType = DataControlRowType.DataRow Then
Dim checkRow As CheckBox = TryCast(row.Cells(0).FindControl("checkRow"), CheckBox)
If checkRow.Checked Then
Dim zid As String = row.Cells(1).Text
Dim lastname As String = row.Cells(3).Text
dt.Rows.Add(zid, lastname)
End If
End If
Next
Session("employeedt") = dt
Response.Redirect("ManagerTraining.aspx")
End Sub
If a box is checked on page load from the first bit of code, unchecked by the user, the second piece of code will step into the "If checkRow.checked" statement even though the user has unchecked that box. The checkboxes are contained in a gridview. I am using ASP.NET and VB. I feel like the changes aren't being committed if the user unchecks.
Please read about the ASP.NET lifecycle.
Page.Load always executes before the event handlers on postback. You should wrap the code setting the checkbox values in
If not isPostback Then
Dim checkRow As CheckBox = TryCast(row2.Cells(0).FindControl("checkRow"), CheckBox)
checkRow.Checked = True
End If

Access the value of dropdownlist in gridview edit mode, in DropDownList_SelectedIndexChanged event

I am trying to perfrom a postback with a Dropdownlist in a Gridview in Edit Mode. I am having problems getting to the value of the drop down. I can not do this in the RowDatabound event.
Postback is not over writing the row, I am stepping into the DropDownList7_SelectedIndexChanged event where I want to perform some operations, so it hasn't even gotten there. I do have the If Postback in the page load event.
Protected Sub DropDownList7_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs)
Dim row As GridViewRow = DirectCast(GridView1.Rows.Item(0), GridViewRow)
Dim newNumDDL As DropDownList = row.Cells(0).FindControl("DropDownList7")
Dim newVal As Integer = newNumDDL.SelectedValue
Dim newKey As String = newNumDDL.SelectedItem.ToString
Dim newindex As Integer = newNumDDL.SelectedIndex
Issue I believe is with the findcontrol I can not find the DDL, keeps coming back nothing.
Thanks for any help.
Can you not use:
Dim newNumDDL As DropDownList = DirectCast(sender, DropDownList)

change textbox's value from pageload event, submit new values issue

I have created a form to update an access DB table. My issue is that when the text in the text boxes is changed and the form is submitted, the .text values stay the same as they were when the datareader loaded them on the page load event. How can I submit the values that the user updates, not what is already there from page load.
Code:
Public Property vehicleid As Integer
Public Property connstring As String = "myconnectionstring..."
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
vehicleid = Integer.Parse(Request.QueryString("vehicID"))
Dim svEnterdate, stocknum, make, model, color As String
Dim conn As New OleDbConnection(connstring)
Dim sql As String = "select * from vehicle where vehicleid=#vid"
Dim cmd As New OleDbCommand(sql, conn)
cmd.Parameters.AddWithValue("#vid", vehicleid)
conn.Open()
Dim dr As OleDbDataReader = cmd.ExecuteReader
While dr.Read
svEnterdate = dr("enterdate").ToString()
stocknum = dr("stock_num").ToString()
make = dr("make").ToString()
model = dr("model").ToString()
color = dr("color").ToString()
End While
conn.Close()
EnterDateTXT.Text = svEnterdate
StockNumTXT.Text = stocknum
MakeTxt.Text = make
ModelTXT.Text = model
ColorTxt.Text = color
End Sub
'inbetween these 2 events the user can manipulate all the controls .text values, yet the
' .text values of the submitted controls below are the same as the ones filled by the
'datareader
Protected Sub SubmitBTN_Click(ByVal sender As Object, ByVal e As EventArgs) Handles SubmitBTN.Click
Dim conn As New OleDbConnection(connstring)
Dim sql As String = "UPDATE Vehicle" & _
" SET stock_num=#stock, make=#make, model=#model, color=#color, enterdate=#enter " & _
"WHERE vehicleid=#vid"
Dim cmd As New OleDbCommand(sql, conn)
cmd.Parameters.AddWithValue("#vid", vehicleid)
cmd.Parameters.AddWithValue("#stock", StockNumTXT.Text)
cmd.Parameters.AddWithValue("#make", MakeTxt.Text)
cmd.Parameters.AddWithValue("#model", ModelTXT.Text)
cmd.Parameters.AddWithValue("#color", ColorTxt.Text)
cmd.Parameters.AddWithValue("#enter", EnterDateTXT.Text)
conn.Open()
cmd.ExecuteNonQuery()
conn.Close()
End Sub
In your page load code, Check For Post back
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
' Write your code to read data from database here
End
End Sub
If you dont check for postback in your page load event, Everytime when you click the submit button, It is going to excute the code in your page load ( load the content again to the text box) first. So whatever you entered in the textbox will be overwritten by the content form the database and that will be saved back again to the database.
To undestand this. Put a breakpoint in your Page_load event code and another in your button click event code. Now enter some value in textbox and click the button and see whether your code block in pageload is executing or not.
Checking the Postback check in your page_load will fix the problem.
http://msdn.microsoft.com/en-us/library/system.web.ui.page.ispostback.aspx

get value of label when button clicked in nested repeater asp.net vb

I have nested repeaters, each item in the nested repeater has a label and a button on it, i want to beable to access the label.text when the button is clicked, I think i'm nearly there as I can return the index of the repeater and nested repeater that is clicked, i'm just having some trouble finding the label itself.
You might be able to help me without me posting the repeater code. Here is my code behind for when the button is clicked.
Protected Sub btnEditUser_Click(ByVal sender As Object, ByVal e As System.EventArgs)
Dim btnEditUser As Button = DirectCast(sender, Button)
Dim reClient As RepeaterItem = DirectCast(btnEditUser.NamingContainer.Parent.Parent, RepeaterItem)
Dim reUser As RepeaterItem = DirectCast(btnEditUser.NamingContainer, RepeaterItem)
Dim selectedClient As Integer = reClient.ItemIndex
Dim selectedUser As Integer = reUser.ItemIndex
Dim UserId As Label = DirectCast(reClients.Items(selectedClient).FindControl("lUserName"), Label)
Response.Write(selectedClient & " " & selectedUser & " " & UserId.Text)
End Sub
I'm currently getting this error 'Object reference not set to an instance of an object.' when trying to write the value of UserId.Text so i think i've got it slightly wrong in this line:
Dim UserId As Label = DirectCast(reClients.Items(selectedClient).FindControl("lUserName"), Label)
This is just a guess, but sometimes you get errors like this when not all rows contain the control you're looking for. Often the code loops through the rows in order, hits a header row first that doesn't contain the relevant control, and fails.
Here is a good MSDN article - Locating a Control Inside a Hierarchy of Naming containers.
Private Function FindControlRecursive(
ByVal rootControl As Control, ByVal controlID As String) As Control
If rootControl.ID = controlID Then
Return rootControl
End If
For Each controlToSearch As Control In rootControl.Controls
Dim controlToReturn As Control =
FindControlRecursive(controlToSearch, controlID)
If controlToReturn IsNot Nothing Then
Return controlToReturn
End If
Next
Return Nothing
End Function
Try it,
Dim UserId As Label =DirectCast(FindControlRecursive(repClient,"lUserName"),Label)

Gridview - Cannot get updated cell value for RowUpdating

I am using ItemTemplate & EditTemplate for editing the gridview. (ASP.net + VB).
I click EDIT button then I can check/uncheck those checkbox and amend the textbox value.
When click UPDATE button, it will fire the RowUpdating Event, But I found that when I get the value for update statement, it still get the value before editing, not updated value.
How can I get the latest & updated value ? Thanks.
Joe
The following is the VB code:
Protected Sub GridView1_RowUpdating(ByVal sender As Object, ByVal e As GridViewUpdateEventArgs)
'Update the values.
Dim row = Gridview1.Rows(e.RowIndex)
Dim Col1_SL = CType(Gridview1.Rows(e.RowIndex).FindControl("cb1_SL"), CheckBox)
Dim Col1_VL = CType(Gridview1.Rows(e.RowIndex).FindControl("cb1_VL"), CheckBox)
Dim Col1_ML = CType(Gridview1.Rows(e.RowIndex).FindControl("cb1_ML"), CheckBox)
Dim Col1_PH = CType(Gridview1.Rows(e.RowIndex).FindControl("cb1_PH"), CheckBox)
Dim Col1_APH = CType(Gridview1.Rows(e.RowIndex).FindControl("cb1_APH"), CheckBox)
Dim Col1_TOIL = CType(Gridview1.Rows(e.RowIndex).FindControl("cb1_TOIL"), CheckBox)
Dim Col1_Others = CType(Gridview1.Rows(e.RowIndex).FindControl("tb1_Others"), TextBox)
Dim Col1_RosterKey = CType(Gridview1.Rows(e.RowIndex).FindControl("lb1_rosterkey"), Label)
Using conn As New System.Data.SqlClient.SqlConnection(ConfigurationManager.ConnectionStrings("hris_shiftdutyConnectionString").ConnectionString)
conn.Open()
cmd.Connection = conn
sql = "SET DATEFORMAT dmy;UPDATE troster SET SL='" & Convert.ToInt32(Col1_SL.Checked) & "' where roster_key='" & Col1_RosterKey.Text & "';"
cmd.CommandText = Sql
reader = cmd.ExecuteReader()
conn.Close()
reader.Close()
End Using
'Reset the edit index.
Gridview1.EditIndex = -1
'Bind data to the GridView control.
BindData()
End Sub
The most likely reason will be this.
You are calling BindData() on Page_Load without using !IsPostBack
Protected Sub Page_Load Handles Me.Load
If Not IsPostBack
' Bind Grid only at the first load
' Do not load Grid again at Postbacks
BindData()
End If
End Sub
You have 2 options:
There is a separate RowUpdated method that is fired after updates have been performed by the data source that is bound to the grid view. This method will contain the new values for edits and inserts.
The RowUpdating method should have a parameter of type GridViewEventArgs. This will have a property called NewValues that contains the new values. In your example this was the variable e.

Resources