I have an editable gridview which the user can edit each row just by pressing linkbutton. I am getting an error and it stops my work. please help me.
HTML
<asp:GridView ID="gvList" runat="server" class="gv" CellPadding="2"
Font-Names="Calibri" ForeColor="#333333"
Font-Size="16px" Width="500px" AutoGenerateColumns="true" OnRowCancelingEdit="gvList_RowCancelingEdit"
OnRowEditing="gvList_RowEditing" OnRowUpdating="gvList_RowUpdating">
<Columns>
<asp:TemplateField HeaderText="User Name" HeaderStyle-ForeColor="White" HeaderStyle-Font-Bold="true" ItemStyle-Width="170px">
<ItemTemplate>
<asp:Label runat="server" ID="lblUsername" Text='<%# Eval("cUserName") %>'></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="Editusername" runat="server" Text='<%# Eval("cUserName") %>'></asp:TextBox>
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Dept User" HeaderStyle-ForeColor="White" HeaderStyle-Font-Bold="true" ItemStyle-Width="170px">
<ItemTemplate>
<asp:Label runat="server" ID="lblDept" Text='<%# iif(Eval("lDeptUser"),"Yes","No") %>'></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:RadioButtonList ID="RadioButtonList1" runat="server" >
<asp:ListItem>Yes</asp:ListItem>
<asp:ListItem>No</asp:ListItem>
</asp:RadioButtonList>
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Actions" HeaderStyle-ForeColor="White" HeaderStyle-Font-Bold="true" ItemStyle-Width="160px">
<ItemTemplate>
<asp:LinkButton ID="btnedit" CommandName="Edit" runat="server" Text="Edit" />
<asp:LinkButton ID="btnDelete" CommandName="Delete" runat="server" Text="Delete" />
</ItemTemplate>
<EditItemTemplate>
<asp:LinkButton ID="btnUpdate" CommandName="Update" runat="server" Text="Update" />
<asp:LinkButton ID="btnCancel" CommandName="Cancel" runat="server" Text="Cancel" />
</EditItemTemplate>
<HeaderStyle Font-Bold="True" ForeColor="White"></HeaderStyle>
<ItemStyle Width="120px"></ItemStyle>
</asp:TemplateField>
</Columns>
<EmptyDataTemplate>
No records available
</EmptyDataTemplate>
<HeaderStyle BackColor="#808380" Font-Bold="True" ForeColor="White" VerticalAlign="Top" />
<EditRowStyle BackColor="#2461BF" />
<AlternatingRowStyle BackColor="#E3E3E3" />
</asp:GridView>
VB
Protected Sub gvList_RowUpdating(sender As Object, e As System.Web.UI.WebControls.GridViewUpdateEventArgs) Handles gvList.RowUpdating
Dim oldname = DirectCast(gvList.Rows(e.RowIndex).FindControl("lblUsername"), Label)
Dim username As String = DirectCast(gvList.Rows(e.RowIndex).FindControl("Editusername"), TextBox).Text
Dim tempUser = DirectCast(gvList.Rows(e.RowIndex).FindControl("RadioButtonList1"), RadioButtonList).SelectedIndex
Dim query As String = "Update Intranet.dbo.Gn_ISCoordinators SET cUserName=#uname" +
",lDeptUser=#dept WHERE cUserName=#oldName"
Using con = New SqlConnection(ConfigurationManager.ConnectionStrings("IntranetConnectionString").ConnectionString)
con.Open()
Dim cmd = New SqlCommand(query, con)
cmd.Parameters.AddWithValue("#uname", username)
cmd.Parameters.AddWithValue("#dept", Convert.ToByte(tempUser))
cmd.Parameters.AddWithValue("#oldname", oldname)
cmd.ExecuteNonQuery()
End Using
gvList.EditIndex = -1
GetList()
End Sub
The problem is on the cmd.ExecuteNonQuery() it gives me The parameterized query '(#uname nvarchar(7),#dept tinyint,#oldname nvarchar(4000))Update' expects the parameter '#oldname', which was not supplied.
Any thing wrong in my query?
Try this
Dim oldname as Label =gvList.Rows(e.RowIndex).FindControl("lblUsername")
Dim username as TextBox = gvList.Rows(e.RowIndex).FindControl("Editusername")
Dim tempUser as RadioButtonList = DirectCast(gvList.Rows(e.RowIndex).FindControl("RadioButtonList1"), RadioButtonList).SelectedIndex
Dim query As String = "Update Intranet.dbo.Gn_ISCoordinators SET cUserName=#uname" +
",lDeptUser=#dept WHERE cUserName=#oldname"
Using con = New SqlConnection(ConfigurationManager.ConnectionStrings("IntranetConnectionString").ConnectionString)
con.Open()
Dim cmd = New SqlCommand(query, con)
cmd.Parameters.AddWithValue("#uname", username.Text)
cmd.Parameters.AddWithValue("#dept", Convert.ToByte(tempUser.SelectedIndex))
cmd.Parameters.AddWithValue("#oldname", oldname.Text)
cmd.ExecuteNonQuery()
End Using
you have change the parameter name by making "N" capital in #oldName,so due to that
you are getting that Error
there is a typo in your parameter
Dim query As String = "Update Intranet.dbo.Gn_ISCoordinators SET cUserName=#uname" +
",lDeptUser=#dept WHERE cUserName=#oldName"
And you have
cmd.Parameters.AddWithValue("#oldname", oldname)
isn't it should be
cmd.Parameters.AddWithValue("#oldName", oldname)
there is capital and small letter mistake.
Sorry I dont have enough rep to comment so I have to answer here...
Why are you casting label to label and trying to use it as string?:
Dim oldname as string = DirectCast(gvList.Rows(e.RowIndex).FindControl("lblUsername"), Label).text
seems more appropriate.
Im not sure about this but maybe because when you tried to hit the edit button and the gridview's mode is in edit mode the lblUsername label will be changed to Editusername textbox.. So what I suggest is you try to put a global variable string that will store the data of the lblUsername before updating or editing..
Try this
Code look fine, but this line command.commandtype = commandtype.text is missing may be that the problem.
Also while passing parameter Addwithvalue use username.text instead on username same for other controls too
Dim oldname As Label = DirectCast(gvList.Rows(e.RowIndex).FindControl("lblUsername"), Label)
Dim username As TextBox = DirectCast(gvList.Rows(e.RowIndex).FindControl("Editusername"), TextBox).Text
Dim tempUser As RadioButton = DirectCast(gvList.Rows(e.RowIndex).FindControl("RadioButtonList1"), RadioButtonList).SelectedIndex
Dim query As String = "Update Intranet.dbo.Gn_ISCoordinators SET cUserName=#uname, lDeptUser=#dept WHERE cUserName=#oldName"
Using con = New SqlConnection(ConfigurationManager.ConnectionStrings("IntranetConnectionString").ConnectionString)
con.Open()
Dim cmd = New SqlCommand(query, con)
cmd.commandtype = commandtype.text
cmd.Parameters.AddWithValue("#uname", username.text)
cmd.Parameters.AddWithValue("#dept", Convert.ToByte(tempUser.selectedvalue))
cmd.Parameters.AddWithValue("#oldname", oldname.text)
cmd.ExecuteNonQuery()
End Using
gvList.EditIndex = -1
GetList()
Related
I am using the AdminLTE library and have designed my master with 2 content placeholders; one in the head section and another in the body section. I am unable to get my gridview to render its content in a datatable.
I populate the gridview via a shared method from a class file which works fine. I have tried to write the Javascript document.ready function in the head section of my aspx form but the gridview seems not to recognize the function.
This is the markup
<div class="box">
<div class="box-header">
<h3 class="box-title">List of available regions</h3>
</div>
<div class="box-body">
<asp:GridView ID="grvRegions" runat="server" class="table table-bordered table-striped"
EmptyDataText="Empty region list" OnRowEditing="OnRowEditing"
OnRowCancelingEdit="OnRowCancelingEdit" OnRowUpdating="OnRowUpdating"
AutoGenerateColumns="False" DataKeyNames="ID" AllowPaging="True">
<Columns>
<asp:TemplateField HeaderText="ID" InsertVisible="False" SortExpression="ID">
<EditItemTemplate>
<asp:Label ID="lblID" runat="server" Text='<%# Eval("ID")%>'></asp:Label>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Bind("ID")%>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Region" InsertVisible="False" SortExpression="ID">
<EditItemTemplate>
<asp:TextBox ID="txtEditRegion" required="required" CssClass="form-control" MaxLength="50" runat="server" Text='<%# Eval("Region")%>'></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="lblRegion" runat="server" Text='<%# Bind("Region")%>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField ShowHeader="False">
<EditItemTemplate>
<asp:LinkButton ID="lbtUpdate" CssClass="btn btn-success" runat="server" CausesValidation="True" CommandName="Update" Text="Update"></asp:LinkButton>
<asp:LinkButton ID="lbtCancel" CssClass="btn btn-danger" runat="server" CausesValidation="False" CommandName="Cancel" Text="Cancel"></asp:LinkButton>
</EditItemTemplate>
<ItemTemplate>
<asp:LinkButton ID="lbtRemove" class="btn btn-info" runat="server" CausesValidation="False" CommandName="Edit" Text="Edit"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
</div>
This is the method that retrieves the data for the gridview
Public Shared Sub FillTabularData(container As Object, spName As String, Optional param As SqlParameter = Nothing)
Dim command As New SqlCommand(spName, connection)
command.CommandType = CommandType.StoredProcedure
If param IsNot Nothing Then
command.Parameters.Add(param)
End If
If connection.State = ConnectionState.Closed Then
connection.Open()
End If
Dim dTable As New DataSet
Dim dAdapter As SqlDataAdapter = New SqlDataAdapter(command)
dAdapter.Fill(dTable)
container.DataSource = dTable
container.DataBind()
End Sub
This is the calling of the "FillTabularData" method in my code behind file for the gridview
Sub BindData()
FillTabularData(grvRegions, "sp_list_regions")
grvRegions.UseAccessibleHeader = True
grvRegions.HeaderRow.TableSection = TableRowSection.TableHeader
End Sub
I expect the output to be rendered in a datatable with paging, sorting, searching and number of rows per page capabilities.
Try like this (I am not familiar with vb.net coding, please check the syntax)
Sub BindData()
Dim dt As New DataSet
dt= FillTabularData("sp_list_regions")
grvRegions.DataSource = dTable
grvRegions.DataBind()
grvRegions.UseAccessibleHeader = True
grvRegions.HeaderRow.TableSection = TableRowSection.TableHeader
End Sub
Public Shared Function FillTabularData(spName As String, Optional param As SqlParameter = Nothing) As DataSet
Dim command As New SqlCommand(spName, connection)
command.CommandType = CommandType.StoredProcedure
If param IsNot Nothing Then
command.Parameters.Add(param)
End If
If connection.State = ConnectionState.Closed Then
connection.Open()
End If
Dim dTable As New DataSet
Dim dAdapter As SqlDataAdapter = New SqlDataAdapter(command)
dAdapter.Fill(dTable)
return dTable
End Function
I'm trying to update GridView from code behind but stuck at a problem which I don't understand even after countless searches for a solution.
After editing a textbox in GridView EditItemTemplate, clicking an 'Update' button in the row would fire RowUpdating event. In the RowUpdating event handler, I use this code to get the string of the edited txtBox1:
Dim text1 As String = (CType(GridView1.Rows(e.RowIndex).FindControl("txtBox1"), TextBox)).Text
I am able to get a correct value for text1 but the problem is if I wrote GridView1.DataBind() in the same even handler, the code above will cause the error "Object reference not set to an instance of an object." I could not understand why the same code will work if delete/comment out GridView.DataBind() method.
I've been stuck with this problem for many days and I will really really appreciate any help.
Here's my VB.net code to handle GridView1.RowUpdating. This will only work if I delete or comment out GridView1.DataBind() method but GridView won't be updated with new data :
Protected Sub GridView1_RowUpdating(ByVal sender As Object, ByVal e As GridViewUpdateEventArgs) Handles GridView1.RowUpdating
Dim text1 As String = (CType(GridView1.Rows(e.RowIndex).FindControl("txtBox1"), TextBox)).Text
Dim text2 As String = (CType(GridView1.Rows(e.RowIndex).FindControl("txtBox2"), TextBox)).Text
Dim IDkey As String = GridView1.DataKeys(e.RowIndex).Values(0).ToString()
Dim sqlquery As String = "UPDATE tblPMU SET zone = '" & text1 & "', substation ='" & text2 & "' WHERE (ID ='" & IDKey & "')"
Dim sqlCmd As New SqlCommand(sqlquery, conn)
Dim sqlDa As New SqlDataAdapter(sqlCmd)
conn.open()
Dim dt As New DataTable()
sqlDa.Fill(dt)
conn.Close()
GridView1.EditIndex = -1
UpdateGridview()
GridView1.DataBind()
Label5.Text=text1
End Sub
My .aspx code for the GridView:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="ID" AllowSorting="True"
onrowediting="GridView1_RowEditing"
onrowcancelingedit="GridView1_RowCancelingEdit"
onrowupdating="GridView1_RowUpdating">
<Columns>
<asp:CommandField ButtonType="Button" ShowEditButton="True" />
<asp:BoundField DataField="ID" HeaderText="ID" SortExpression="ID" ReadOnly="True" Visible="False" />
<asp:TemplateField HeaderText="subzone" SortExpression="zone">
<EditItemTemplate>
<asp:TextBox ID="txtBox1" runat="server" Text='<%# Bind("zone") %>'></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Bind("zone") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="substation" SortExpression="station">
<EditItemTemplate>
<asp:TextBox ID="txtBox2" runat="server" Text='<%# Bind("station") %>'></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label2" runat="server" Text='<%# Bind("station") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
I have problem this gridview when I click on image button in gridview for delete row. I have this code
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False">
<Columns>
<asp:BoundField DataField="Username" HeaderText="Login Name">
<ItemStyle Width="150px" />
</asp:BoundField>
<asp:BoundField DataField="Question" HeaderText="Question">
<ItemStyle Width="200px" />
</asp:BoundField>
<asp:BoundField DataField="Answer" HeaderText="Answer">
<ItemStyle Width="150px" />
</asp:BoundField>
<asp:TemplateField ShowHeader="False">
<ItemTemplate>
<asp:ImageButton ID="ImageButton1" runat="server" CausesValidation="False" AutoPostback = "True"
CommandName="Select" ImageUrl="~/images/trash.png" Text="Select" OnClientClick="return confirm('Do you want to delete?');" />
</ItemTemplate>
</asp:TemplateField>
when i click trash image for delete any row it gives me error. Invalid postback or callback argument.
This is my vb.net code
Private Sub updatedata(ByVal sql As String)
connectdb()
cmd = New SqlCommand
cmd.Connection = conn
cmd.CommandType = CommandType.Text
cmd.CommandText = sql
cmd.ExecuteNonQuery()
conn.Close()
End Sub
Protected Sub GridView1_SelectedIndexChanged(sender As Object, e As System.EventArgs) Handles GridView1.SelectedIndexChanged
Dim sql4 As String = "delete from login WHERE username='" & GridView1.SelectedRow.Cells(0).Text.Trim() & "' "
updatedata(sql4)
Hey all i am wondering if it was possible to evaluate the datafield each time it places a new record into a row?
my gridview code is this:
<asp:Panel ID="pnlGrid" runat="server">
<div class="left_main_container" style="margin-bottom:20px;">
<asp:GridView ID="grdView" runat="server" CssClass="GridViewStyle"
AutoGenerateColumns="False" GridLines="None" Width="100%">
<Columns>
<asp:BoundField DataField="id" Visible="False" />
<asp:BoundField DataField="theName" HeaderText="Name" />
<asp:BoundField DataField="status" HeaderText="Status" />
</Columns>
<RowStyle CssClass="RowStyle" />
<EmptyDataRowStyle CssClass="EmptyRowStyle" />
<PagerStyle CssClass="PagerStyle" />
<SelectedRowStyle CssClass="SelectedRowStyle" />
<HeaderStyle CssClass="HeaderStyle" />
<EditRowStyle CssClass="EditRowStyle" />
<AlternatingRowStyle CssClass="AltRowStyle" />
</asp:GridView>
</div>
</asp:Panel>
The field i need to evaluate is status. I need to find out if the status is yes or if its no. If its no then i need to make it a link for the user to be able to change it to a yes.
The gridview is populated by this code:
Dim objConn As MySqlConnection
Dim objCmd As MySqlCommand
objConn = New MySqlConnection(strConnString)
objConn.Open()
Dim strSQL As String
strSQL = "SELECT id, status, " & _
"CONCAT(' ', first_name, last_name) AS theName " & _
"FROM(builder_requests) " & _
"ORDER BY status, id DESC;"
Dim dtReader As MySqlDataReader
objCmd = New MySqlCommand(strSQL, objConn)
dtReader = objCmd.ExecuteReader()
grdView.DataSource = dtReader
grdView.DataBind()
dtReader.Close()
dtReader = Nothing
objConn.Close()
objConn = Nothing
Any help would be great!
I like to use a TemplateField and a function in your code-behind to do this sort of thing.
I am assuming your status field is a string field not boolean but if not let me know and I can adjust the example.
Replace your BoundField with...
Markup:
<asp:TemplateField>
<ItemTemplate>
<%# Eval("status")%>
<asp:LinkButton ID="cmdChangeStatus" runat="server" CommandName="ChangeStatusToYes" CommandArgument='<%# Eval("id") %>'
Visible='<%# SetChangeStatusVisibility(Eval("status")) %>'>Change to Yes</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
And add code behind function...
Code:
Protected Function SetChangeStatusVisibility(status As Object) As String
Dim strStatus As String = status.ToString()
If strStatus = "no" Then
Return "True"
Else
Return "False"
End If
End Function
Then you can handle the GridView.RowCommand event to change the status value based on the id value in CommandArgument :)
I have the following gridview defined which is populating perfectly:
<asp:GridView runat="server" ID="chargeDetail" AutoGenerateColumns="false" DataKeyNames="LineItemNumber,DetailId,IsParking" CellSpacing="0" CellPadding="6"
HorizontalAlign="Center" EnableViewState="true" ShowFooter="true">
<Columns>
<asp:BoundField DataField="StudentID" HeaderText="Student ID" ReadOnly="True" ItemStyle-HorizontalAlign="Center" />
<asp:BoundField DataField="StudentName" HeaderText="Name" ReadOnly="true" />
<asp:BoundField DataField="CampusName" HeaderText="Campus" ReadOnly="true" />
<asp:TemplateField HeaderText="Description" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:Label runat="server" ID="LineItemDetailLabel" Text='<%# IIf(Eval("Mandatory") = "1", Eval("LineItemDetail") + " *", Eval("LineItemDetail")) %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Item Cost" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
$<asp:Label runat="server" ID="LineItemCostLabel" Text='<%# Eval("LineItemCost") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Options" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:Label runat="server" ID="lblOptionsAvailable"
Text='<%# IIf(Eval("AttributesAvailable") = "1", "Options will be available to select on the next screen.", "No options available.") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Pay Now" ItemStyle-HorizontalAlign="Center" FooterText="Total:">
<ItemTemplate>
<asp:Checkbox runat="server" ID="cbLineItemSelected" Checked='<%# IIf(Eval("Selected") = "1", "True", "False") %>'
Enabled='<%# IIf(Eval("Mandatory") = "1", "False", "True") %>' AutoPostBack="True" OnCheckedChanged="cbLineItemSelected_CheckedChanged" />
</ItemTemplate>
<FooterStyle Font-Bold="True" HorizontalAlign="Right" />
</asp:TemplateField>
<asp:TemplateField HeaderText="Total">
<ItemTemplate>
$<asp:Label runat="server" ID="lblLineTotalCost" Text='<%# IIf(Eval("Selected") = "1", Eval("LineItemCost"), "0.00") %>' />
</ItemTemplate>
<FooterTemplate>
$<asp:Label runat="server" ID="lblTotal" />
</FooterTemplate>
<FooterStyle Font-Bold="True" />
</asp:TemplateField>
</Columns>
</asp:GridView>
In the TemplateField where HeaderText="Options", I need to be able to create a variable number of drop-down lists. For each fee the school may be charging, they could have any number of attributes associated. For example, a TShirt fee may need to collect Size and Color and each attribute may have multiple options.
Right now, you can see I have a label that is populating correctly but I need to be able to create the two drop-down lists, in this case for Size and Color, so the parent can specify them when they check the box to include this fee in their charges. You'll notice that in the Pay Now column, the checkbox has an OnCheckedChanged event which currently updates the total column and overall total in the footer row.
I would ideally like that event to populate the drop-downs when it is checked so the parent can make their selections. I'll also need to know how to handle the post back from those drop-downs so I can get the selections recorded correctly.
From what I can find, I'm guessing I need to create a nested gridview where I can put the drop-downlists but I can't find any examples to point me in the right direction of how to make that work. I can easily populate the drop-downs from the code behind and if pointed in the right direction, access the data as the parents enter it. Just need a bit of direction or an easier way.
Thanks in advance!
OK, I came up with a solution that seems to work. Inside the gridview definition, I nested another gridview with the drop-down list inside of it as follows:
<asp:TemplateField HeaderText="Options" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:GridView runat="server" ID="gvOptions" AutoGenerateColumns="False" DataKeyNames="AttributeId" HorizontalAlign="center" EnableViewState="true"
GridLines="None" EmptyDataText="No available options." ShowHeader="False">
<Columns>
<asp:BoundField DataField="Description" ReadOnly="true" ItemStyle-HorizontalAlign="Center" />
<asp:TemplateField>
<ItemTemplate>
<asp:DropDownList runat="server" ID="ddlOptionSelection" DataTextField="Description" DataValueField="OptionId"
EnableViewState="true" AutoPostBack="true" OnSelectedIndexChanged="ddlOptionSelection_SelectedIndexChanged">
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</ItemTemplate>
</asp:TemplateField>
The challenge was figuring out how to tie everything together since data in the nested gridview relied on data keys from the parent gridview. The RowDataBound event for the parent finds the child gridview and populates the dropdowns as follows (gvOptions is the child and chargeDetail is the parent):
Protected Sub chargeDetail_RowDataBound(sender As Object, e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles chargeDetail.RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Then
Dim gv As GridView = DirectCast(e.Row.FindControl("gvOptions"), GridView)
Dim cb As CheckBox = DirectCast(e.Row.FindControl("cbLineItemSelected"), CheckBox)
Dim lineItem As String = chargeDetail.DataKeys(e.Row.RowIndex).Values("LineItemNumber")
gv.DataSource = GetOptions(chargeDetail.DataKeys(e.Row.RowIndex).Values("DetailId"))
gv.DataBind()
Dim gridLineCount As Integer = gv.Rows.Count()
Dim gridWorkingRow As Integer
For gridWorkingRow = 0 To gridLineCount - 1
Dim ddl As DropDownList = gv.Rows(gridWorkingRow).FindControl("ddlOptionSelection")
Dim AttribId As Integer = gv.DataKeys(gridWorkingRow).Values("AttributeId")
ddl.DataSource = PopulateOptions(AttribId)
ddl.DataBind()
ddl.SelectedValue = GetSelectedValue(AttribId, lineItem)
If cb.Checked Then
ddl.Enabled = True
Else
ddl.Enabled = False
End If
Next gridWorkingRow
End If
End Sub
When one of the dropdowns change, the following is fired. I found it easier, based on how the data is stored in the database, to re-send all of the options since the attribute:option pairs are concatenated to be stored in a single field:
Protected Sub ddlOptionSelection_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs)
Dim ddlSender As DropDownList = DirectCast(sender, DropDownList)
Dim row As GridViewRow = DirectCast(ddlSender.NamingContainer, GridViewRow)
Dim gvOption As GridView = DirectCast(row.NamingContainer, GridView)
Dim chargeDetailRow As GridViewRow = DirectCast(gvOption.Parent.Parent, GridViewRow)
Dim LineItemNumber As Integer = CInt(chargeDetail.DataKeys(chargeDetailRow.RowIndex).Values("LineItemNumber"))
Dim gridLineCount As Integer = gvOption.Rows.Count()
Dim gridWorkingRow As Integer
Dim OptionString As String = ""
For gridWorkingRow = 0 To gridLineCount - 1
Dim ddl As DropDownList = gvOption.Rows(gridWorkingRow).FindControl("ddlOptionSelection")
Dim AttribId As String = gvOption.DataKeys(gridWorkingRow).Values("AttributeId")
If gridWorkingRow = gridLineCount - 1 Then
OptionString = OptionString + AttribId + ":" + ddl.SelectedValue
Else
OptionString = OptionString + AttribId + ":" + ddl.SelectedValue + ","
End If
Next gridWorkingRow
Dim PortalConn As New SqlConnection
PortalConn.ConnectionString = ConfigurationManager.ConnectionStrings("PortalConnStr").ConnectionString
PortalConn.Open()
Dim WriteBackSQL As New SqlCommand("sp_schedulePickup_UpdateOption", PortalConn)
WriteBackSQL.CommandType = Data.CommandType.StoredProcedure
WriteBackSQL.Parameters.Add(New SqlParameter("#SessionID", Session.SessionID.ToString()))
WriteBackSQL.Parameters.Add(New SqlParameter("#LineItemNumber", LineItemNumber))
WriteBackSQL.Parameters.Add(New SqlParameter("#Option", OptionString))
Dim returnStatus As Integer
Dim rsReturn As SqlDataReader = WriteBackSQL.ExecuteReader()
Do While rsReturn.Read()
returnStatus = rsReturn("ReturnStatus")
Loop
rsReturn.Close()
rsReturn = Nothing
PortalConn.Close()
PortalConn = Nothing
chargeDetail.DataSource = GetChargeDetails()
chargeDetail.DataBind()
getTotal()
End Sub