Having difficulty populating a DropDownList within a GridView - asp.net

As the title states I am having a lot of difficulty populating a drop down list that is within a gridview on my web form. I feel like this process should be relatively straight forward as I have populated many gridviews and drop down lists in the past without a hitch. Below, I have detailed what I have tried and will post any associated code. I am relatively new to software development and any help in solving this problem would be greatly appreciated.
To start I have added a drop down list to the gridview in question. Code below.
<asp:GridView ID="GridView3" runat="server"
EmptyDataText="No Claimed Parts" AutoGenerateColumns="False"
ShowHeaderWhenEmpty="True" DataKeyNames="RecID"
ShowFooter="True" DataSourceID="SqlDataSource5" Width="95%">
<EmptyDataTemplate>
<asp:DropDownList ID="ddlPartEquipmentNew" runat="server" DataSourceID="SqlDataSourcePartEquipment" DataValueField="EquipmentType" DataTextField="EquipmentType"
AppendDataBoundItems="True" Width="270px" Height="20px" Style="margin-left: 70px;">
<asp:ListItem Value="0">---SELECT---</asp:ListItem>
</asp:DropDownList>
<asp:DropDownList ID="ddlPartNew" runat="server" DataSourceID="SqlDataSourcePart" DataValueField="RecID"
DataTextField="description" AppendDataBoundItems="True" Width="270px" Height="20px"
style="margin-left: 70px; margin-right: 110px">
<asp:ListItem Value="0">---SELECT---</asp:ListItem>
</asp:DropDownList>
<asp:textbox ID="txtUnitPriceNew" runat="server" Width="95px"/>
<asp:textbox ID="txtTaxNew" runat="server" Width="95px" text="0"/>
<asp:Button ID="InsertDetail" runat="server" CommandName="InsertDetail" Height="25px" Text="Add Detail" Width="85px" />
</EmptyDataTemplate>
<AlternatingRowStyle BackColor="#CCCCCC" />
<Columns>
<asp:CommandField ShowEditButton="True" footertext="Add -->" ShowDeleteButton="True" HeaderStyle-Width="70px"/>
<asp:BoundField DataField="RecID" HeaderText="RecID" SortExpression="RecID" ReadOnly="True" Visible="False" />
<asp:TemplateField HeaderText="Parts Description" ItemStyle-HorizontalAlign="center">
<ItemTemplate>
<asp:label ID="lblDescriptionAdd" Text='<%# Bind("PartFailed") %>' runat="server"/>
</ItemTemplate>
<EditItemTemplate>
<asp:DropDownList ID="ddlPartEquipmentEdit" runat="server" DataValueField="Agreement" DataTextField="EquipmentType"
AppendDataBoundItems="True" Width="270px" Height="20px" Style="margin-left: 70px;">
<asp:ListItem Value="0">---SELECT---</asp:ListItem>
</asp:DropDownList>
<asp:DropDownList ID="ddlPartEdit" runat="server" DataSourceID="SqlDataSourcePart" DataValueField="RecID" DataTextField="description" SelectedValue='<%# Eval("RepairID")%>' AppendDataBoundItems="True" Width="270px"/>
</EditItemTemplate>
<FooterTemplate>
<asp:DropDownList ID="ddlPartEquipmentInsert" runat="server" DataValueField="Agreement" DataTextField="EquipmentType"
AppendDataBoundItems="True" Width="270px" Height="20px" Style="margin-left: 70px;">
<asp:ListItem Value="0">---SELECT---</asp:ListItem>
</asp:DropDownList>
<asp:DropDownList ID="ddlPartInsert" runat="server" DataSourceID="SqlDataSourcePart" DataValueField="RecID" DataTextField="description" AppendDataBoundItems="True" Width="270px">
<asp:ListItem Value="0">---SELECT---</asp:ListItem>
</asp:DropDownList>
</FooterTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Part Cost Requested" ItemStyle-HorizontalAlign="center" HeaderStyle-Width="100px">
<ItemTemplate>
<asp:label ID="lblUnitPrice" Text='<%# Bind("PartCost", "{0:C}") %>' runat="server" Enabled="False"/>
</ItemTemplate>
<EditItemTemplate>
<asp:textbox ID="txtUnitPriceEdit" Text='<%# Bind("PartCost") %>' Enabled="true" runat="server"/>
</EditItemTemplate>
<FooterTemplate>
<asp:textbox ID="txtUnitPriceInsert" Text='<%# Bind("PartCost") %>' runat="server" style="width: 100%; box-sizing: border-box;"/>
</FooterTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Tax" ItemStyle-HorizontalAlign="Center" HeaderStyle-Width="100px">
<ItemTemplate>
<asp:LinkButton ID="lbTaxTotal" Text='<%# Bind("Tax", "{0:C}")%>' runat="server" CommandArgument="Part" OnClick="lblTaxTotal_Click"/>
<asp:HiddenField ID="hidPartGST" runat="server" Value='<%# Bind("GST")%>' />
<asp:HiddenField ID="hidPartPST" runat="server" Value='<%# Bind("PST")%>' />
<asp:HiddenField ID="hidPartQST" runat="server" Value='<%# Bind("QST")%>' />
<asp:HiddenField ID="hidPartHST" runat="server" Value='<%# Bind("HST")%>' />
</ItemTemplate>
<EditItemTemplate>
<asp:textbox ID="lblTaxTotalEdit" Text='<%# Bind("Tax")%>' Enabled="true" runat="server"/>
</EditItemTemplate>
<FooterTemplate>
<asp:textbox ID="txtTaxTotalInsert" Text="0" runat="server" Enabled="true" style="width: 100%; box-sizing: border-box;"/>
</FooterTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Insert New" HeaderStyle-Width="85px">
<ItemTemplate>
<asp:Label ID="lblEmpty" Text="" runat="server" Width="75px"/>
</ItemTemplate>
<FooterTemplate>
<asp:Button ID="Insert" runat="server" CommandName="InsertNewDetail" Height="22px" Text="Insert" style="width: 100%; box-sizing: border-box;" />
</FooterTemplate>
</asp:TemplateField>
</Columns>
<HeaderStyle BackColor="#336699" ForeColor="White" />
</asp:GridView>
In the above code, the gridview is declared and there are a series of controls within the gridview. The control in question is "ddlPartEquipmentNew" (technically I am having the same problem with the 2 other drop downs labeled "ddlPartEquipmentEdit" and "ddlPartEquipmentInsert" respectively, however we can ignore those at the moment.)
For whatever reason I cannot seem to figure out how to bind this ddl to the appropriate values I have in my database.
Below I will go into detail on what I have tried and the various outputs I have gotten.
One of the first things I have tried was to create a GetData() Function and then call that function in the gridviews OnDataBound() event, however when doing this, though I don't receive an error, the drop down has no values other than the default "---SELECT---" I setup in the aspx code above.
Below I have attached the code for the GetData() function and code for the OnDataBound() procedure.
GetData()
Private Function GetEquipmentData(query As String) As DataSet
Dim conString As SqlConnection = objCn
Dim cmd As New SqlCommand(query)
Using conString
Using sda As New SqlDataAdapter()
cmd.Connection = conString
sda.SelectCommand = cmd
Using ds As New DataSet()
sda.Fill(ds, txtAgreement.Text)
Return ds
End Using
End Using
End Using
End Function
OnDataBound()
Protected Sub GridView3_DataBound(sender As Object, e As EventArgs) Handles GridView3.DataBound
Dim partRequestedTotal As Decimal = Decimal.Zero
Dim partTotal As Decimal = Decimal.Zero
Dim gv As GridView = sender
If gv.EditIndex = -1 Then
For Each row As GridViewRow In gv.Rows
If row.RowType = DataControlRowType.DataRow Then
Dim lblAmount As Label = row.FindControl("lblUnitPrice")
Dim lblAmountRequested As Label = row.FindControl("lblUnitPrice")
Dim ddlPartEquipmentNew As DropDownList = row.FindControl("ddlPartEquipmentNew")
ddlPartEquipmentNew.DataSource = GetEquipmentData("SELECT EquipmentType FROM Equipment WHERE Agreement = #Agreement")
ddlPartEquipmentNew.DataTextField = "EquipmentType"
ddlPartEquipmentNew.DataValueField = "EquipmentType"
ddlPartEquipmentNew.DataBind()
'Dim lblMarkup As Label = row.FindControl("lblMarkup")
Dim partRequested As Decimal = Decimal.Parse(lblAmountRequested.Text, NumberStyles.Currency)
'Convert.ToDecimal(lblAmountRequested.Text.Replace("$", ""))
Dim partValue As Decimal = Decimal.Parse(lblAmount.Text, NumberStyles.Currency)
'Convert.ToDecimal(lblAmount.Text.Replace("$", ""))
'Dim markupValue As Decimal = Decimal.Parse(lblMarkup.Text, NumberStyles.Currency)
'Convert.ToDecimal(lblMarkup.Text.Replace("$", ""))
'partTotal = partValue + partTotal + markupValue
partRequestedTotal = partRequestedTotal + partRequested
End If
Next
'txtPartsTotal.Text = partTotal.ToString
txtPartsRequested.Text = partRequestedTotal.ToString("N2")
If GridView3.Rows.Count > 0 Or GridView1.Rows.Count > 0 Then
calculateTotalTax()
calculateTotal()
Else
txtTax.Text = "0"
Me.txtGrandTotal.Text = "0"
End If
End If
End Sub
With this attempt at binding the drop down list I receive no errors however the drop down in question remains empty.
I have also tried to create a databind event for the drop down list specifically and in the OnDataBind() event for the control I reference the procedure I created, however when I do this I get an exception error stating that I have a connection to the database that has not been closed, or a timeout exception.
Below is the code for the ddl databind event
Protected Sub DDLPartEquipmentNew_DataBind(sender As Object, e As EventArgs)
Dim ddlPartEquipmentNew As DropDownList = sender
Using con As New SqlConnection(ConfigurationManager.ConnectionStrings("WarrantyConnectionString").ToString)
Using cmd As New SqlCommand("SELECT EquipmentType FROM Equipment WHERE Agreement = #Agreement")
cmd.Parameters.Add("#Agreement", SqlDbType.Int).Value = txtAgreement.Text
cmd.CommandType = CommandType.Text
con.Open()
cmd.Connection = con
ddlPartEquipmentNew.DataSource = cmd.ExecuteReader()
ddlPartEquipmentNew.DataBind()
con.Close()
End Using
End Using
End Sub
As a last note on the situation I am having, the other drop down controls in this gridview are populated using an asp:SqlDataSource control which I have also tried, the issue I run into using a datasource in the aspx page is that my query requires a variable and so far I have not found a way to declare that variable in the code behind to avoid the exception "Must declare Scalar Variable #Agreement". The especially weird part about this exception is that in the stack trace it is popping this exception inside the databind event for a different gridview.
Query in question: SELECT EquipmentType FROM Equipment WHERE Agreement = #Agreement
Relatively simple, or at least I would think so. Any help someone would be able to offer on this problem would be greatly appreciated as I am at a loss as to how to populate this drop down, let alone any other drop down lists I may have to add to the page.

Related

FindControl throwing NullReferenceException

Within my ASP gridview, I have the following (updated to show full gridview):
<asp:GridView ID="TPAnnuity_GridView" AllowSorting="true" AllowPaging="true" Runat="server"
DataSourceID="TPAnnuity_SqlDataSource" DataKeyNames="AnnuityTotalPointsID"
AutoGenerateColumns="False" ShowFooter="true" PageSize="20">
<Columns>
<asp:TemplateField HeaderText="Company" SortExpression="CompanyName" HeaderStyle-VerticalAlign="Bottom">
<ItemTemplate>
<asp:Label ID="Label11" runat="server" Text='<%# Bind("CompanyName") %>'></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:DropDownList ID="EditACompanyID" runat="server" DataSource="<%# ddlCompanyDS %>" DataValueField="CompanyID" DataTextField="CompanyName" selectedValue='<%# Bind("CompanyID") %>'></asp:DropDownList>
</EditItemTemplate>
<FooterTemplate>
<asp:DropDownList ID="NewCompanyID" runat="server" DataSource="<%# ddlCompanyDS %>" DataValueField="CompanyID" DataTextField="CompanyName"></asp:DropDownList>
<asp:RequiredFieldValidator ID="RequiredFieldValidator11" runat="server" ControlToValidate="NewCompanyID" Display="Dynamic" ForeColor="" ErrorMessage="You must enter a value. *" Enabled="false"></asp:RequiredFieldValidator>
</FooterTemplate>
<FooterStyle Wrap="False" />
</asp:TemplateField>
</Columns>
<EmptyDataTemplate>
<br />
<i>No Commission Data to display.</i>
<br />
<br />
</EmptyDataTemplate>
</asp:GridView>
And within my back end, I have the following:
Sub TPAnnuity_RowCommand(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewCommandEventArgs) Handles TPAnnuity_GridView.RowCommand
If e.CommandName = "Cancel" Then
'Reset Footer Row input fields
CType(TPAnnuity_GridView.FooterRow.FindControl("NewCompanyID"), DropDownList).SelectedIndex = 0
ElseIf e.CommandName = "Insert" Then
TPAnnuity_SqlDataSource.InsertParameters.Clear()
Dim test1 As New Parameter("CompanyIDInt", TypeCode.Int32)
test1.DefaultValue = CType(TPAnnuity_GridView.FooterRow.FindControl("NewCompanyID"), DropDownList).SelectedValue
TPAnnuity_SqlDataSource.InsertParameters.Add(test1)
TPAnnuity_SqlDataSource.Insert()
ElseIf e.CommandName = "Update" Then
TPAnnuity_SqlDataSource.UpdateParameters.Clear()
Dim param1 As New Parameter("CompanyIDInt", TypeCode.Int32)
param1.DefaultValue = CType(TPAnnuity_GridView.FooterRow.FindControl("EditACompanyID"), DropDownList).SelectedValue ****THIS IS THE PROBLEM LINE****
TPAnnuity_SqlDataSource.UpdateParameters.Add(param1)
TPAnnuity_SqlDataSource.Update()
End If
End Sub
The Cancel and Insert functions work just fine, operating off of the footer. Every time hit the "Update" button, I get a NullReferenceException on the param1.Default Value = line.
Can anyone help me figure out what's going on here?
Your row should look like this:
param1.DefaultValue = CType(e.CommandSource.FindControl("EditACompanyID"), DropDownList).SelectedValue
Instead of utilizing the FooterRow, you have to use the source row. Since you passed that in with e, you can use this.

Populating fields in an ASP.Net DetailsView when "New" button is clicked from DetailsView

Using an ASP.Net DetailsView with VB.Net in a code-behind file, we would like to make it easier for the user to do data entry when they are inserting data.
We would like to implement a way for the DetailsView to remember the value in particular fields prior to clicking the "New" button. After it remembers the values we would like to populate 2 of the fields which are a DropDownList and a TextBox field with the remembered values after clicking "New".
Currently we tried this in the code-behind file:
Protected Sub DetailsViewDetails_ItemCommand(sender As Object, e As System.Web.UI.WebControls.DetailsViewCommandEventArgs)
Select Case e.CommandName
Case "Add"
Case "Edit"
ButtonAddNewAttendance.Enabled = False
Case "Delete"
Case "Update"
ButtonAddNewAttendance.Enabled = True
Case "Insert"
Case "New"
Dim txtBox As New TextBox
txtBox = DetailsView.FindControl("TextBoxDateAttendanceTakenInsert")
txtBox.Text = DateTime.Now
Dim drpValue As DropDownList
drpValue = DetailsView.FindControl("DropDownListClassInsert")
drpValue.SelectedValue = 1
End Select
End Sub
When the "New" button is clicked this error is displayed:
System.NullReferenceException was unhandled by user code
Message=Object reference not set to an instance of an object.
This error is on txtBox.Text = DateTime.Now
It's almost as if it can't find the field from the markup. Can you tell me what else I need to add to the coding?
If I comment out the coding for the TextBox and leave the coding to run for the DropDownList it produces the same error.
Here is the markup showing 2 of the fields:
<asp:DetailsView
ID="DetailsView"
runat="server"
AutoGenerateRows="False"
Height="50px"
Width="207px"
DataSourceID="SqlDataSourceDetails"
DataKeyNames="ID"
OnItemCommand="DetailsViewDetails_ItemCommand">
<Fields>
<asp:TemplateField HeaderText="Class:" SortExpression="ClassID">
<EditItemTemplate>
<asp:DropDownList
ID="DropDownListClassEdit"
Runat="server"
DataSourceID="SqlDataSourceClasses"
DataTextField = "ClassName"
DataValueField="ID"
SelectedValue='<%# Bind("ClassID") %>'
ForeColor="Blue">
</asp:DropDownList>
<asp:RequiredFieldValidator ID="RequiredFieldValidatorEditClass" runat="server" ControlToValidate="DropDownListClassEdit"
ErrorMessage="Please select a Class here." Font-Bold="True" Font-Italic="True" ForeColor="Red"
SetFocusOnError="True" Display="Dynamic">
</asp:RequiredFieldValidator>
</EditItemTemplate>
<InsertItemTemplate>
<asp:DropDownList
ID="DropDownListClassInsert"
Runat="server"
DataSourceID="SqlDataSourceClasses"
DataTextField = "ClassName"
DataValueField="ID"
SelectedValue='<%# Bind("ClassID") %>'
AppendDataBoundItems="True"
ForeColor="Blue">
</asp:DropDownList>
<asp:RequiredFieldValidator ID="RequiredFieldValidatorInsertClass" runat="server" ControlToValidate="DropDownListClassInsert"
ErrorMessage="Please select a Class here." Font-Bold="True" Font-Italic="True" ForeColor="Red"
SetFocusOnError="True" Display="Dynamic">
</asp:RequiredFieldValidator>
</InsertItemTemplate>
<ItemTemplate>
<asp:DropDownList
ID="DropDownListClass"
Runat="server"
DataSourceID="SqlDataSourceClasses"
DataTextField = "ClassName"
DataValueField="ID"
SelectedValue='<%# Bind("ClassID") %>'
Enabled="false"
ForeColor="Blue"
Font-Bold="true">
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField
HeaderText="Attendance Date:" SortExpression="DateAttendanceTaken">
<EditItemTemplate>
<asp:TextBox
ID="TextBoxDateAttendanceTakenEdit"
runat="server"
Text='<%# Bind("DateAttendanceTaken", "{0:MM/dd/yyyy}") %>'>
</asp:TextBox>
</EditItemTemplate>
<InsertItemTemplate>
<asp:TextBox
ID="TextBoxDateAttendanceTakenInsert"
runat="server"
Text='<%# Bind("DateAttendanceTaken", "{0:MM/dd/yyyy}") %>'>
</asp:TextBox>
</InsertItemTemplate>
<ItemTemplate>
<asp:Label
ID="LabelDateAttendanceTaken"
runat="server"
Text='<%# Bind("DateAttendanceTaken", "{0:MM/dd/yyyy}") %>'>
</asp:Label>
</ItemTemplate>
<ItemStyle ForeColor="Blue" />
</asp:TemplateField>
For now I hard coded a value into:
drpValue.SelectedValue = 1
until we can get the coding to work.
* UPDATE *
ItemCommand is not the correct place to put the coding.
I found out that to get this to work, OnDataBinding needs to be added as shown here plus making sure there is a handler in the code-behind file as shown below.
InsertItemTemplate markup:
<InsertItemTemplate>
<asp:DropDownList
ID="DropDownListClassInsert"
Runat="server"
DataSourceID="SqlDataSourceClasses"
DataTextField = "ClassName"
DataValueField="ID"
SelectedValue='<%# Bind("ClassID") %>'
AppendDataBoundItems="True"
ForeColor="Blue"
OnDataBinding="DropDownListClassInsert_DataBinding">
</asp:DropDownList>
<asp:RequiredFieldValidator ID="RequiredFieldValidatorInsertClass" runat="server" ControlToValidate="DropDownListClassInsert"
ErrorMessage="Please select a Class here." Font-Bold="True" Font-Italic="True" ForeColor="Red"
SetFocusOnError="True" Display="Dynamic">
</asp:RequiredFieldValidator>
</InsertItemTemplate>
Handler in the code-behind file:
Protected Sub DropDownListClassInsert_DataBinding(sender As Object, e As EventArgs)
Dim drpValue As DropDownList
drpValue = DetailsView.FindControl("DropDownListClassInsert")
drpValue.SelectedValue = intCurrentClassID
End Sub
Note: intCurrentClassID is declared as:
Public Shared intCurrentClassID As Integer = Nothing
after:
Public Class
I hope this helps others who had the same issues.

getting datarow vales in gridview error

I have the following aspx code;
<asp:GridView ID="GridView1" runat="server" AllowPaging="True"
AllowSorting="True" AutoGenerateColumns="False" DataKeyNames="ProductId"
DataSourceID="edsinventory" OnRowCommand="GridView1_RowCommand"
ShowFooter="true" CssClass="mGrid">
<Columns>
<asp:TemplateField ShowHeader="False">
<EditItemTemplate>
<asp:LinkButton ID="LinkButton1" runat="server" CausesValidation="True"
CommandName="Update" Text="Update"></asp:LinkButton>
<asp:LinkButton ID="LinkButton2" runat="server" CausesValidation="False"
CommandName="Cancel" Text="Cancel"></asp:LinkButton>
</EditItemTemplate>
<FooterTemplate><asp:LinkButton ID="LinkButton3" runat="server" CommandName="Insert">Insert</asp:LinkButton></FooterTemplate>
<ItemTemplate>
<asp:LinkButton ID="LinkButton1" runat="server" CausesValidation="False"
CommandName="Edit" Text="Edit"></asp:LinkButton>
<asp:LinkButton ID="LinkButton2" runat="server" CausesValidation="False"
CommandName="Delete" Text="Delete"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Id" InsertVisible="False"
SortExpression="Id">
<EditItemTemplate>
<asp:Label ID="lblEditId" runat="server" Text='<%# Eval("Id") %>'></asp:Label>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="lblId" runat="server" Text='<%# Bind("Id")%>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="ProductId" SortExpression="ProductId">
<EditItemTemplate>
<asp:TextBox ID="tbProdId" Width="50" runat="server" Text='<%# Bind("ProductId")%>'></asp:TextBox>
</EditItemTemplate>
<FooterTemplate>
<asp:TextBox ID="tbInsertProdId" Width="50" runat="server"></asp:TextBox>
</FooterTemplate>
<ItemTemplate>
<asp:Label ID="lblProdId" runat="server" Text='<%# Bind("ProductId")%>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
'shortened for brevity
</Columns>
</asp:GridView>
here is the code behind
Protected Sub GridView1_RowCommand(sender As Object, e As GridViewCommandEventArgs)
' This just provides easier access to the Cells in the GridView
Dim cells = GridView1.FooterRow.Cells
Dim ctx As New teckEntities()
Dim addInventory As New inventory()
If e.CommandName = ("Insert") Then
'Create new Inventory object
addInventory.ProductId = Convert.ToInt32(DirectCast(cells(3).FindControl("tbInsertProdId"), TextBox).Text)
addInventory.Quantity = Convert.ToInt32(DirectCast(cells(4).FindControl("tbInsertQuantity"), TextBox).Text)
addInventory.Location = Convert.ToString(DirectCast(cells(1).FindControl("tbInsertLocation"), TextBox).Text)
'attach the fields to the inventory context
' note: Id autoincrements and doesn't need to be set manually
InsertInventoryItem(addInventory)
'need to call a gridview refresh here
GridView1.DataBind()
ElseIf e.CommandName = "Delete" Then
**addInventory.Id = Convert.ToInt32(DirectCast(cells(3).FindControl("lblEditId"), Label).Text)**
DeleteInventoryItem(Convert.ToInt32(addInventory.Id))
GridView1.DataBind()
End If
End Sub
I am getting the following error on the deleting routine where the **, why? The insert function works the same way and works properly.
Object reference not set to an instance of an object.
I think the problem is you're looking the Label lblEditId in Footer controls:
Dim cells = GridView1.FooterRow.Cells
...
addInventory.Id = Convert.ToInt32(DirectCast(cells(3).FindControl("lblEditId"), Label).Text)
Try this instead:
Update your delete linkbutton to (add the ID to the CommandArgument):
<asp:LinkButton ID="LinkButton2" runat="server" CausesValidation="False" CommandName="Delete" CommandArgument='<%#Eval("Id")%>' Text="Delete"></asp:LinkButton>
Then, replace your ** code with this:
Note: Based on the code you provided, it seem like the lblEditId is in column 2 hence the Cell(1) - zero based index, instead of Cell(3).
addInventory.Id = Convert.ToInt32(DirectCast(GridView1.Rows(e.CommandArgument).Cells(1).FindControl("lblEditId"), Label).Text)

Without using SelectedIndexChanged, how to retrieve value of each row from gridview?

I have a GridView,
without using SelectedIndexChanged, how can I retrieve the value of each row from GridView when click on each button in each row?
this is my aspx code
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="ProductID"
DataSourceID="SqlDataSource1" ShowHeader="False" AllowPaging="True" BorderColor="White"
CellPadding="6" GridLines="None" Height="100px" Width="800px">
<Columns>
<asp:TemplateField>
<ItemTemplate>
Card Name:
<asp:Label ID="Label1" runat="server" Text='<%# Bind("Name") %>'></asp:Label>
<br />
Cost :
<asp:Label ID="Label2" runat="server" Text='<%# Bind("Price") %>'></asp:Label>
<br />
<asp:Label ID="Label3" runat="server" Text='<%# Bind("ProductImgID") %>'></asp:Label>
<asp:Image ID="Image3" runat="server" ImageUrl='<%# Eval("ProductImgUrl", "images/{0}") %>' />
<br />
<asp:Button ID="btnAddProduct" runat="server" Text="Add" />
<br />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
One option can be to Bind the CommandArgument of the button to the ProductID
<asp:Button ID="btnAddProduct" runat="server" Text="Add" CommandArgument='<%#Bind("ProductID")%>' />
and then in the RowCommand event retrieve the ProductID and extract the row from database
string prodID=(string)e.CommandArgument()
then using the ID retrieve the row from database.
To get a row value, you have to get the row Reference, After getting the row you can easily get to the specified column and can get the value
Lets Consider you have a "link button control" in a template field column. For the gridview you have to set Row Command Event, and also in the edit template of the column, set a command name for the link button also say "lnkTest"
In RowCommand Event you have to include the following section of code
if(e.CommandName.Equals("lnkTest")) // Checks that link button was clicked
{
GridViewRow grdRow = (((LinkButton)e.CommandSource).Container)
// This Will give you the reference of the Row in which the link button was clicked
int grdRowIndex = grdRow.RowIndex;
//This will give you the index of the row
var uniqueDataKeyValue = GridView1.DataKeys[grdRowIndex].Value;
//This will give you the DataKey Value for the Row in which the link Control was click
Hope the above code will help
Add CommandArgument='<%# Container.DataItemIndex %>' to your Add button
<asp:Button ID="btnAddProduct" runat="server" Text="Add" CommandArgument='<%# Container.DataItemIndex %>'/>
To retrive Name, in gridview row command use this code
Dim gvr As GridViewRow = grvGRNCONs.Rows(e.CommandArgument)
Dim name As String = DirectCast(gvr.FindControl("Label1"), Label).Text
and so on..
<asp:GridView ID="grdResults" CssClass="CommonTable dataTable" AutoGenerateColumns="false" runat="server">
<Columns>
<asp:TemplateField HeaderText="Sl#">
<ItemTemplate>
<asp:Label ID="lblSlno" Text='<%# Container.DataItemIndex+1 %>' runat="server"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="" ControlStyle-Height="15px" ControlStyle-Width="15px">
<HeaderStyle HorizontalAlign="Left" />
<ItemStyle HorizontalAlign="Left" CssClass="PInfoTd" />
<ItemTemplate>
<asp:ImageButton ID="lknassesno" ToolTip="Edit Assessment" Width="50" CssClass="NewButton" ***CommandName="LINK"***
runat="server" ImageUrl="~/img/Edit.png" />
<asp:HiddenField ID="hidassesmentno" Value='<%# EVAL("PAN_CODE")%>' runat="server" />
<asp:HiddenField ID="hidPendStatus" Value='<%# EVAL("Pstatus")%>' runat="server" />
<asp:HiddenField ID="hidIPNO"Value='<%#EVAL("IP_NO")%>' runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
**code behind**
Protected Sub grdResults_RowCommand(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewCommandEventArgs) Handles grdResults.RowCommand
If **e.CommandName = "LINK"** Then
Dim ctrl As Control = e.CommandSource
Dim grrow As GridViewRow = ctrl.Parent.NamingContainer
'Dim i As Integer = Convert.ToInt16(e.CommandArgument)
'Dim lknassesno As HiddenField = DirectCast(e.CommandSource, ImageButton)
Dim hidAssesmentNo As HiddenField = DirectCast(grdResults.Rows(grrow.RowIndex).FindControl("hidassesmentno"), HiddenField)
Dim lblstatus As HiddenField = DirectCast(grdResults.Rows(grrow.RowIndex).FindControl("hidPendStatus"), HiddenField)
Dim hidIpNo As HiddenField = DirectCast(grdResults.Rows(grrow.RowIndex).FindControl("hidIPNO"), HiddenField)
Dim Assno As String = hidAssesmentNo.Value
Dim Ipno As String = hidIpNo.Value
Dim st As String = ""
If lblstatus.Value = "Pending" Then
st = "E"`enter code here`
ElseIf lblstatus.Value = "Completed" Then
st = "V"
End If
Response.Redirect("Assessment.aspx?PAssNo=" & Assno & "&Mode=" & st & "&IPNO=" & Ipno & "")
End If
End Sub

CollapsiblePanelExtender in nested Repeater and Gridview setup doesn't function

I have a setup using three levels of nesting: A Repeater, the items of which utilize CollapsiblePanelExtenders (which work), and each contain a GridView. Each of these then contain another GridView which is controlled by another CollapsiblePanelExtender. These inner CollapsiblePanels will effectively show either an expanded or collapsed state only if I set clientState to True. However, they do not effectively expand or collapse as expected. Everything is bound dynamically.
Here is the markup...
<asp:Repeater ID="cat_repeater" runat="server">
<ItemTemplate>
<asp:CollapsiblePanelExtender id="cat_cpExt" runat="server" TargetControlID="cat_pnl" CollapsedSize="0" Collapsed="false" CollapsedImage="collapsed.png" ExpandedImage="expanded.png" ExpandControlID="cpControl_pnl" CollapseControlID="cpControl_pnl" TextLabelID="cpControl_lbl" ImageControlID="cpControl_img" CollapsedText='<%#configCPText(eval("Title"), False)%>' ExpandedText='<%#configCPText(eval("Title"), True) %>' />
<asp:Panel ID="cpControl_pnl" runat="server" Visible='<%#itemVisible(eval("ID"), "Recipients", "CategoryID") %>' CssClass="CPanelStyle">
<asp:Image ID="cpControl_img" runat="server" ImageUrl="expanded.png" />
<asp:Label ID="cpControl_lbl" runat="server" Text='<%#configCPText(eval("Title"), True) %>' CssClass="CPanelText" />
</asp:Panel>
<asp:Panel ID="cat_pnl" runat="server">
<asp:GridView ID="recipients_gv" runat="server" CssClass="GVStyle" HeaderStyle-CssClass="GVHeaderStyle" RowStyle-CssClass="GVItemStyle" AutoGenerateColumns="false" GridLines="none" AllowPaging="false">
<Columns>
<asp:TemplateField HeaderText="Name" SortExpression="Last Name" ItemStyle-CssClass="GVNameStyle">
<ItemTemplate>
<asp:Literal id="name_lit" runat="server" text='<%#formatNameText(eval("FirstName"), eval("LastName")) %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Gifts" ItemStyle-Width="500px">
<ItemTemplate>
<asp:CollapsiblePanelExtender id="gifts_cpExt" runat="server" TargetControlID="gifts_pnl" CollapsedSize="0" Collapsed="true" CollapsedImage="collapsed.png" ExpandedImage="expanded.png" ExpandControlID="cpControl_pnl2" CollapseControlID="cpControl_pnl2" TextLabelID="cpControl_lbl2" ImageControlID="cpControl_img2" CollapsedText='<%#configGiftsCPText(eval("ID"), True)%>' ExpandedText='<%#configGiftsCPText(eval("ID"), False) %>' />
<asp:Panel ID="cpControl_pnl2" runat="server" Visible='<%#itemVisible(eval("ID"), "Gifts", "RecipientID") %>'>
<asp:Image ID="cpControl_img2" runat="server" ImageUrl="collapsed.png" />
<asp:Label ID="cpControl_lbl2" runat="server" Text='<%#configGiftsCPText(eval("ID"), False) %>' />
</asp:Panel>
<asp:Panel ID="gifts_pnl" runat="server">
<asp:GridView ID="gifts_gv" runat="server" DataKeyNames="ID" RowStyle-CssClass="GVInnerItemStyle" HeaderStyle-CssClass="GVInnerHeaderStyle" Gridlines="None" AutoGenerateColumns="false" AllowPaging="false" Width="475px">
<Columns>
<asp:TemplateField ItemStyle-CssClass="GVInnerButtonItemStyle" HeaderText="Description">
<ItemTemplate>
<asp:LinkButton ID="gift_lBtn" runat="server" Text='<%#eval("Description") %>' CommandName="Select" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Complete" ItemStyle-Width="50px">
<ItemTemplate>
<asp:CheckBox ID="giftComplete_cbx" runat="server" Checked='<%#eval("Complete") %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</asp:Panel>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</asp:Panel>
<br />
</ItemTemplate>
</asp:Repeater>
...And here is the code to bind everything:
Protected Sub bindCategories()
Try
oCmd.Connection = oConn
oCmd.CommandType = CommandType.Text
strSQL = "SELECT * FROM Categories"
oCmd.CommandText = strSQL
oDA.SelectCommand = oCmd
oDA.Fill(oDTbl)
cat_repeater.DataSource = oDTbl
cat_repeater.DataBind()
For i As Integer = 0 To oDTbl.Rows.Count - 1
oCmd.Parameters.Clear()
inner_dTbl.Clear()
strSQL = "SELECT *, Title FROM Recipients INNER JOIN Categories on Recipients.CategoryID = Categories.ID WHERE CategoryID = #CategoryID ORDER BY LastName"
oParam = New SqlParameter
oParam.ParameterName = "CategoryID"
oParam.SqlDbType = SqlDbType.Int
oParam.Value = oDTbl.Rows(i)("ID")
oCmd.Parameters.Add(oParam)
oCmd.CommandText = strSQL
oDA.SelectCommand = oCmd
oDA.Fill(inner_dTbl)
Dim gv As GridView = CType(cat_repeater.Items(i).FindControl("recipients_gv"), GridView)
gv.DataSource = inner_dTbl
gv.DataBind()
For j As Integer = 0 To inner_dTbl.Rows.Count - 1
oCmd.Parameters.Clear()
gifts_dTbl.Clear()
strSQL = "SELECT * FROM Gifts WHERE RecipientID = #RecipientID ORDER BY Description"
oParam = New SqlParameter
oParam.ParameterName = "RecipientID"
oParam.SqlDbType = SqlDbType.Int
oParam.Value = inner_dTbl.Rows(j)("ID")
oCmd.Parameters.Add(oParam)
oCmd.CommandText = strSQL
oDA.SelectCommand = oCmd
oDA.Fill(gifts_dTbl)
Dim inner_gv As GridView = CType(gv.Rows(j).FindControl("gifts_gv"), GridView)
inner_gv.DataSource = gifts_dTbl
inner_gv.DataBind()
Dim cpExt As CollapsiblePanelExtender = CType(gv.Rows(j).FindControl("gifts_cpExt"), CollapsiblePanelExtender)
cpExt.Collapsed = True
cpExt.ClientState = True
Next
Next
Catch ex As Exception
Throw ex
End Try
End Sub
I've successfully used CollapsiblePanelExtenders in a 2-level nested GridView setup that without a problem before, and without having to set clientState. However, I've had to specify clientState when using CollapsiblePanelExtenders with Repeaters before.
Does anyone have any input regarding why these extenders will not function in this 3-level nested setup?
It looks like the reason it's required is because it needs a postback to make all that logic work:
if (this.SupportsClientState) {
ScriptManager.RegisterHiddenField(this, this.ClientStateFieldID, this.SaveClientState());
this.Page.RegisterRequiresPostBack(this);
}
This is from public class ScriptControlBase in the AjaxControlToolkit space.
Are you wrapping this in an UpdatePanel? Does it cause a postback to use the CPE in the repeater? It's been awhile since I've tried to do a CPE in a repeater, and I'm not setup at this point to check the code out and build one.
Is there a reason you can't just use something completely client-side and just expand/collapse these using javascript? Are you loading data dynamically server side when these things get expanded?

Resources