ASP.NET - Keep DropDownList selection on repeater DataBound - asp.net

I have two DropDownLists per item on a Repeater.
I am binding both lists to two different lists on the repeater DataBound.
Both lists have an OnSelectedIndexChanged event handler which does some calculations based on the selections in both DropDownLists. Both lists also have AutoPostBack="True".
I need the calculation to be updated immediately. So I added another data binding for the repeater - on the lists' event handler.
This is the problem however - the repeater "resets" the selections to -1 and eventually the first items in both DropDownLists are displayed.
How can I make sure the selections remain after the data binding?
Here is the repeater structure:
<asp:Repeater runat="server" ID="rptCart">
<ItemTemplate>
<tr>
<td class="size"><div><asp:DropDownList runat="server" ID="_selectSize" AutoPostBack="true" OnSelectedIndexChanged="selectChange" EnableViewState="true" TabIndex="<%#Container.ItemIndex%>"></asp:DropDownList></div></td>
<td class="material"><div><asp:DropDownList runat="server" ID="_selectMaterial" AutoPostBack="true" OnSelectedIndexChanged="selectChange" EnableViewState="true" TabIndex="<%#Container.ItemIndex%>"></asp:DropDownList></div></td>
</tr>
</ItemTemplate>
</asp:Repeater>
And the repeater DataBound:
Protected Sub rptCart_ItemDataBound(sender As Object, e As System.Web.UI.WebControls.RepeaterItemEventArgs) Handles rptCart.ItemDataBound
If e.Item.ItemType = ListItemType.AlternatingItem OrElse e.Item.ItemType = ListItemType.Item Then
Dim sizeSelect As DropDownList = CType(e.Item.FindControl("_selectSize"), DropDownList)
Dim materialSelect As DropDownList = CType(e.Item.FindControl("_selectMaterial"), DropDownList)
sizeSelect.DataSource = sizeList
sizeSelect.DataBind()
materialSelect.DataSource = materialList
materialSelect.DataBind()
End If
End Sub
And finally the DropDownLists event handler:
Protected Sub selectChange(ByVal sender As DropDownList, ByVal e As System.EventArgs)
Dim listing As New PriceListing
Dim ddl As DropDownList
Dim selectedIndex As Integer
If sender.ID = "_selectSize" Then
For Each rptrItem As RepeaterItem In rptCart.Items
ddl = CType(rptrItem.FindControl("_selectMaterial"), DropDownList)
If ddl.TabIndex = sender.TabIndex Then Exit For
Next
For Each listing In artDecoPricing
If listing.Size = sender.SelectedValue Then Exit For
Next
selectedIndex = ddl.SelectedIndex
ElseIf sender.ID = "_selectMaterial" Then
For Each rptrItem As RepeaterItem In rptCart.Items
ddl = CType(rptrItem.FindControl("_selectSize"), DropDownList)
If ddl.TabIndex = sender.TabIndex Then Exit For
Next
For Each listing In artDecoPricing
If listing.Size = ddl.SelectedValue Then Exit For
Next
selectedIndex = sender.SelectedIndex
End If
Select Case selectedIndex
Case 0
Cart.Order.Items(sender.TabIndex).PriceUnit = listing.Canvas
Case 1
Cart.Order.Items(sender.TabIndex).PriceUnit = listing.Acrylic
Case 2
Cart.Order.Items(sender.TabIndex).PriceUnit = listing.Framed
Case 3
Cart.Order.Items(sender.TabIndex).PriceUnit = listing.Framed
End Select
Cart.SaveOrder()
rptCart.DataSource = Cart.Order.Items
rptCart.DataBind()
End Sub
Thank you very much in advance!

You could store the old selection:
Dim sizeSelect As DropDownList = CType(e.Item.FindControl("_selectSize"), DropDownList)
Dim materialSelect As DropDownList = CType(e.Item.FindControl("_selectMaterial"), DropDownList)
Dim sizeSelectedIndex = sizeSelect.SelectedIndex
Dim materialSelectedIndex = materialSelect.SelectedIndex
' do the databinding ... '
sizeSelect.SelectedIndex = If(sizeSelectedIndex < sizeSelect.Items.Count -1, sizeSelectedIndex, -1)
materialSelect.SelectedIndex = If(materialSelectedIndex < materialSelect.Items.Count -1, materialSelectedIndex, -1)

Related

dropdownlist does not show any values after postback

I've been battling with this issue for a couple of days now and would really appreciate if someone would shed some light for me.
I am populating a dropdownlist based on the selection from another dorpdownlist. As long as there is no postback happening, I see the list getting populated correctly but after a postback, my dropdownlist is empty.
At first, I was trying to manually set the Text property of the ddl but it kept giving me the following error:
System.ArgumentOutOfRangeException: ..ddl has a SelectedValue which is invalid because it does not exist in the list
Then I read somewhere that I need to set the DataValueField property instead so I did that which got rid of the error but now I see the empty dll after a postback.
The ViewStateMode for the ddl is set to Enabled.
The two ddls I'm referring to are defined in a Formview in my .aspx file as ddlCompanyBuyerNVListInsert and ddlCompanyNameListInsert(I'm listing the Insert mode only).
Based on the selections made in ddlCompanyBuyerNVList, I'm populating ddlCompanyNameList.
Here's the code behind for Page_Load and the functions that populate ddlCompanyNameList.
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
If NavHelper.User.UserName = "" Then
Dim UserIP As String
Dim UserLogin As String
Dim UserEmail As String
UserIP = HttpContext.Current.Request.UserHostAddress
UserLogin = HttpContext.Current.Session("Username")
UserEmail = HttpContext.Current.Session("Email")
GetUserInfo()
CurrentRFQ = Nothing
If NavHelper.RFQ.ID = -1 Then
formview_RFQ.ChangeMode(FormViewMode.Insert)
tabpanelCustomerParts.Visible = False
tabpanelDocuments.Visible = False
tabpanelReviews.Visible = False
tabpanelRFQReviewHistory.Visible = False
listview_CustomerParts.Dispose()
Else
formview_RFQ.ChangeMode(FormViewMode.Edit)
listview_ReviewContracts_Initial.EditIndex = 0
SessionHelper.CurrentObject = TAA.Library.RFQ.GetObject(NavHelper.RFQ.ID)
mRFQ = DirectCast(SessionHelper.CurrentObject, TAA.Library.RFQ)
Dim UserdeptTotal As Long
UserdeptTotal = HttpContext.Current.Session("DepartmentTotal")
If formview_RFQ.FindControl("ddlCompanyBuyerNVList") IsNot Nothing Then
Dim ddl As DropDownList = DirectCast(formview_RFQ.FindControl("ddlCompanyBuyerNVList"), DropDownList)
FillCompanyNameDropDownList(ddl)
End If
tabpanelCustomerParts.Visible = True
tabpanelDocuments.Visible = True
tabpanelReviews.Visible = True
tabpanelRFQReviewHistory.Visible = True
If NavHelper.RFQ.Copy = True Then
SetModifyCopy()
End If
End If
Else 'IsPostBack
datasource_BuyerNVList.Dispose()
datasource_RFQ.DataBind()
datasource_RFQNote.DataBind()
Dim ddl As DropDownList
If (formview_RFQ.CurrentMode = FormViewMode.Insert) Then
ddl = DirectCast(formview_RFQ.FindControl("ddlCompanyBuyerNVListInsert"), DropDownList)
ElseIf formview_RFQ.FindControl("ddlCompanyBuyerNVList") IsNot Nothing Then
ddl = DirectCast(formview_RFQ.FindControl("ddlCompanyBuyerNVList"), DropDownList)
End If
FillCompanyNameDropDownList(ddl)
End If
End If
End Sub
Protected Sub FillCompanyNameDropDownList(ddlCompanyBuyerNamesList As DropDownList)
Try
Using cn As New SqlClient.SqlConnection(DB.RFQconnection)
cn.Open()
Using cm As SqlClient.SqlCommand = cn.CreateCommand
cm.CommandType = CommandType.StoredProcedure
cm.CommandText = "GetCompanyNamesForThisBuyer"
cm.Parameters.AddWithValue("#BuyerName", (ddlCompanyBuyerNamesList.SelectedItem.Text))
Dim ddlCompanyNamesList As DropDownList
If (formview_RFQ.CurrentMode = FormViewMode.Insert) Then
ddlCompanyNamesList = DirectCast(formview_RFQ.FindControl("ddlCompanyNameListInsert"), DropDownList)
Else
ddlCompanyNamesList = DirectCast(formview_RFQ.FindControl("ddlCompanyNameList"), DropDownList)
End If
Using r As New SCF.Data.SafeDataReader(cm.ExecuteReader)
ddlCompanyNamesList.Items.Clear()
ddlCompanyNamesList.Items.Add(New ListItem("Select Company"))
While r.Read
Dim li As ListItem = New ListItem()
li.Value = SCF.Data.SafeData.SafeInteger(r("CompanyBuyerId"))
li.Text = SCF.Data.SafeData.SafeString(r("CompanyName"))
ddlCompanyNamesList.Items.Add(li)
End While
End Using
cm.Dispose()
cn.Close()
' if more than one entry found, clear the company info fields until a selection is made
If ddlCompanyNamesList.Items.Count > 2 Then 'because we've added a "Select Company" as the first item
ClearCompanyInfoFields() ' company fields are text boxes that get cleared here
ddlCompanyNamesList.SelectedIndex = 0
End If
ddlCompanyNamesList.Enabled = True
If ddlCompanyNamesList.Items.Count = 2 Then ' if only one entry found populate the compny info with that one entry's selection
ddlCompanyNamesList.SelectedIndex = 1
FillCompanyInfoFields(ddlCompanyNamesList)
ElseIf ddlCompanyNamesList.Items.Count = 0 Then ' if nothing found use the buyer list to populate company info fields
ddlCompanyNamesList.Items.Clear()
FillCompanyInfoFields(ddlCompanyBuyerNamesList)
ddlCompanyNamesList.Enabled = False
End If
End Using
End Using
Catch ex As System.Exception
SetErrorPanel("An error occured during FillCompanyNameDropDownList.")
Dim err As New HealthMonitoringCustomEvents.ErrorEvent("An error occured during FillCompanyNameDropDownList", Me, ex)
err.Raise()
End Try
End Sub
Protected Sub FillCompanyInfoFields(ddl As DropDownList)
Try
Dim buyerTitle As TextBox
Dim buyerEmail As TextBox
Dim buyerPhone As TextBox
Dim buyerExt As TextBox
Dim buyerMobile As TextBox
Dim buyerFax As TextBox
Dim CoAddr As TextBox
Dim CoCity As TextBox
Dim CoState As TextBox
Dim CoZip As TextBox
If (formview_RFQ.CurrentMode = FormViewMode.Insert) Then
buyerTitle = DirectCast(formview_RFQ.FindControl("txtBuyerTitleInsert"), TextBox)
buyerEmail = DirectCast(formview_RFQ.FindControl("txtBuyerEmailInsert"), TextBox)
buyerPhone = DirectCast(formview_RFQ.FindControl("txtBuyerPhoneNumberInsert"), TextBox)
buyerExt = DirectCast(formview_RFQ.FindControl("txtExtInsert"), TextBox)
buyerMobile = DirectCast(formview_RFQ.FindControl("txtBuyerMobileNumberInsert"), TextBox)
buyerFax = DirectCast(formview_RFQ.FindControl("txtBuyerFaxNumberInsert"), TextBox)
CoAddr = DirectCast(formview_RFQ.FindControl("txtCompanyAddressInsert"), TextBox)
CoCity = DirectCast(formview_RFQ.FindControl("txtCompanyCityInsert"), TextBox)
CoState = DirectCast(formview_RFQ.FindControl("txtCompanyStateCodeInsert"), TextBox)
CoZip = DirectCast(formview_RFQ.FindControl("txtCompanyZipCodeInsert"), TextBox)
Else
buyerTitle = DirectCast(formview_RFQ.FindControl("txtBuyerTitle"), TextBox)
buyerEmail = DirectCast(formview_RFQ.FindControl("txtBuyerEmail"), TextBox)
buyerPhone = DirectCast(formview_RFQ.FindControl("txtBuyerPhoneNumber"), TextBox)
buyerExt = DirectCast(formview_RFQ.FindControl("txtExt"), TextBox)
buyerMobile = DirectCast(formview_RFQ.FindControl("txtBuyerMobileNumber"), TextBox)
buyerFax = DirectCast(formview_RFQ.FindControl("txtBuyerFaxNumber"), TextBox)
CoAddr = DirectCast(formview_RFQ.FindControl("txtCompanyAddress"), TextBox)
CoCity = DirectCast(formview_RFQ.FindControl("txtCompanyCity"), TextBox)
CoState = DirectCast(formview_RFQ.FindControl("txtCompanyStateCode"), TextBox)
CoZip = DirectCast(formview_RFQ.FindControl("txtCompanyZipCode"), TextBox)
End If
Using cn As New SqlClient.SqlConnection(DB.RFQconnection)
cn.Open()
Using cm As SqlClient.SqlCommand = cn.CreateCommand
cm.CommandType = CommandType.StoredProcedure
cm.CommandText = "GetBuyerCompanyInfo"
cm.Parameters.AddWithValue("#companyBuyerId", (ddl.SelectedValue))
Using r As New SCF.Data.SafeDataReader(cm.ExecuteReader)
' populate company information fields in CurrentRFQ
While r.Read
CurrentRFQ.CompanyID = SCF.Data.SafeData.SafeString(r(0))
CurrentRFQ.CompanyBuyerId = SCF.Data.SafeData.SafeString(r(7))
ddl.DataValueField = SCF.Data.SafeData.SafeString(r(1))
CoAddr.Text = SCF.Data.SafeData.SafeString(r(2))
CoCity.Text = SCF.Data.SafeData.SafeString(r(4))
CoState.Text = SCF.Data.SafeData.SafeString(r(5))
CoZip.Text = SCF.Data.SafeData.SafeString(r(6))
buyerTitle.Text = SCF.Data.SafeData.SafeString(r(9))
buyerEmail.Text = SCF.Data.SafeData.SafeString(r(10))
buyerPhone.Text = SCF.Data.SafeData.SafeString(r(11))
buyerExt.Text = SCF.Data.SafeData.SafeString(r(12))
buyerMobile.Text = SCF.Data.SafeData.SafeString(r(13))
buyerFax.Text = SCF.Data.SafeData.SafeString(r(14))
End While
End Using
cm.Dispose()
cn.Close()
End Using
End Using
Catch ex As System.Exception
SetErrorPanel("An error occured during FillCompanyInfoFields.")
Dim err As New HealthMonitoringCustomEvents.ErrorEvent("An error occured during FillCompanyInfoFields", Me, ex)
err.Raise()
End Try
End Sub
And here's how the two ddls are defined in the .aspx file.
<td> <asp:DropDownList ID="ddlCompanyBuyerNVListInsert" runat="server"
AppendDataBoundItems="true" AutoPostBack="true" CssClass="Input"
DataSourceID="datasource_BuyerNVlist" DataTextField="Key" DataValueField="Value"
OnSelectedIndexChanged="ddlCompanyBuyerNVListInsert_SelectedIndexChanged"
ViewStateMode="Enabled" Width="205px"> <asp:ListItem Selected="True" Text="Select
Buyer" Value="0" /> </asp:DropDownList> </td> <td></td> <td class="style4"> Company:
</td> <td>
<asp:DropDownList ID="ddlCompanyNameListInsert" runat="server"
AppendDataBoundItems="True" AutoPostBack="True" CssClass="Input"onselectedindexchanged="ddlCompanyNameListInsert_SelectedIndexChanged"
ViewStateMode="Enabled" Enabled="False"> </asp:DropDownList> </td>
Thank you so much for your response.

ASP.NET: Wrong event is fired when I click a LinkButton

I have a "cart" Repeater, where every item has a couple of controls in it. The ones we're focusing on are two DropDownLists, a LinkButton and a TextBox. The lists are on one validation group and the button & textbox are on another.
Both lists have an OnSelectedIndexChanged event handler which does some calculations based on the selections in both DropDownLists. Both lists also have AutoPostBack="True".
The button has an OnClick handler which also does some calculations according to the number in the textbox.
I need the calculations to be updated immediately - so I added another data binding for the Repeater - on each event handler
The problem is - I can't get the value from the TextBox after I click on one of the DropDownLists. It always comes off as 1. In the background, the OnSelectedIndexChanged event handler fires first, and the buttons' OnClick will fires after it. That only happens after I change one of the lists - and it happens every time I click that button from that moment on. Before that - everything is normal on all controls.
What do you think? Below is some code (I hope it's not too much, I included everything that's taking part) - Thank you very much!
Here's the repeater template:
<ItemTemplate>
<tr>
<td class="size"><div><asp:DropDownList runat="server" ID="_selectSize" AutoPostBack="true" OnSelectedIndexChanged="selectChange" EnableViewState="true" TabIndex="<%#Container.ItemIndex%>" ValidationGroup="doNotValidate"></asp:DropDownList></div></td>
<td class="material"><div><asp:DropDownList runat="server" ID="_selectMaterial" AutoPostBack="true" OnSelectedIndexChanged="selectChange" EnableViewState="true" TabIndex="<%#Container.ItemIndex%>" ValidationGroup="doNotValidate"></asp:DropDownList></div></td>
<td class="quantity">
<div>
<div class="quantity_container"><asp:TextBox runat="server" ID="_txtAmount" name="quantity_<%#Container.ItemIndex%>" ValidationGroup="vCart"></asp:TextBox></div>
<div><asp:LinkButton runat="server" CssClass="refresh" id="_refreshCart" ValidationGroup="vCart"></asp:LinkButton></div>
</div>
</td>
</tr>
</ItemTemplate>
The Repeater.DataBound():
Protected Sub rptCart_ItemDataBound(sender As Object, e As System.Web.UI.WebControls.RepeaterItemEventArgs) Handles rptCart.ItemDataBound
If e.Item.ItemType = ListItemType.AlternatingItem OrElse e.Item.ItemType = ListItemType.Item Then
Dim OrderItem As ProxyMarket.Item = CType(e.Item.DataItem, ProxyMarket.Item)
Dim btnRemoveProduct As LinkButton = CType(e.Item.FindControl("_removeProduct"), LinkButton)
Dim btnRefreshCart As LinkButton = CType(e.Item.FindControl("_refreshCart"), LinkButton)
Dim txtAmount As TextBox = CType(e.Item.FindControl("_txtAmount"), TextBox)
Dim sizeSelect As DropDownList = CType(e.Item.FindControl("_selectSize"), DropDownList)
Dim materialSelect As DropDownList = CType(e.Item.FindControl("_selectMaterial"), DropDownList)
btnRemoveProduct.CommandName = OrderItem.ID
btnRefreshCart.CommandName = OrderItem.ID
txtAmount.Text = OrderItem.Units
AddHandler btnRemoveProduct.Click, AddressOf removeProduct
AddHandler btnRefreshCart.Click, AddressOf refreshCart
sizeSelect.DataSource = sizeList
sizeSelect.DataBind()
sizeSelect.SelectedIndex = s
materialSelect.DataSource = materialList
materialSelect.DataBind()
materialSelect.SelectedIndex = m
End If
End Sub
Here is the DropDownLists event handler:
Protected Sub selectChange(ByVal sender As DropDownList, ByVal e As System.EventArgs)
Dim listing As New PriceListing
Dim ddl As DropDownList
Dim selectedIndex As Integer
If sender.ID = "_selectSize" Then
For Each rptrItem As RepeaterItem In rptCart.Items
ddl = CType(rptrItem.FindControl("_selectMaterial"), DropDownList)
If ddl.TabIndex = sender.TabIndex Then Exit For
Next
For Each listing In artDecoPricing
If listing.Size = sender.SelectedValue Then Exit For
Next
selectedIndex = ddl.SelectedIndex
s = sender.SelectedIndex
ElseIf sender.ID = "_selectMaterial" Then
For Each rptrItem As RepeaterItem In rptCart.Items
ddl = CType(rptrItem.FindControl("_selectSize"), DropDownList)
If ddl.TabIndex = sender.TabIndex Then Exit For
Next
For Each listing In artDecoPricing
If listing.Size = ddl.SelectedValue Then Exit For
Next
selectedIndex = sender.SelectedIndex
s = ddl.SelectedIndex
End If
Select Case selectedIndex
Case 0
Cart.Order.Items(sender.TabIndex).PriceUnit = listing.Canvas
Case 1
Cart.Order.Items(sender.TabIndex).PriceUnit = listing.Acrylic
Case 2
Cart.Order.Items(sender.TabIndex).PriceUnit = listing.Framed
Case 3
Cart.Order.Items(sender.TabIndex).PriceUnit = listing.Alucobond
End Select
Cart.SaveOrder()
s = sender.SelectedIndex
m = selectedIndex
rptCart.DataSource = Cart.Order.Items
rptCart.DataBind()
End Sub
And finally, the LinkButton OnClick handler:
Protected Sub refreshCart(ByVal sender As Object, ByVal e As System.EventArgs)
Dim btnRefreshCart As LinkButton = CType(sender, LinkButton)
Dim amountStr As String
Dim amount As Integer
amountStr = CType(btnRefreshCart.Parent.FindControl("_txtAmount"), TextBox).Text
If IsNumeric(amountStr) Then
amount = CDbl(amountStr)
Else
amount = -1
End If
amount = IIf(amount > 0, amount, -30)
For Each Item As ProxyMarket.Item In Cart.Order.Items
If Item.ID = btnRefreshCart.CommandName Then
Item.Units = amount
Cart.Edit_Product(btnRefreshCart.CommandName, amount)
Exit For
End If
Next
rptCart.DataSource = Cart.Order.Items
rptCart.DataBind()
End Sub
Thank you :)
I found a solution!
Apparently this is happening because of a viewstate limitation in ASP.NET which causes the OnSelectedIndexChanged to fire on Page_Load regardless if the user actually selected a different value.
So when the event handler fires, I am checking whether it is the DropDownLists which called me or a different control - that prevents the event from firing when it doesn't need to - and keeps all event handling on the page intact:
Protected Sub selectChange(ByVal sender As DropDownList, ByVal e As System.EventArgs)
Dim senderClientID = Page.Request.Params.Get("__EVENTTARGET")
' Run ONLY if the relevant select control was clicked,
' otherwise this is only fired because of ASP.NET limitations,
' and will screw up the original event:
If senderClientID.IndexOf("_selectSize") <> -1 Or senderClientID.IndexOf("_selectMaterial") <> -1 Then
'do stuff
I know this has already been answered but I was having a very similar problem, with a completely different solution and as this is the first post that appeared in google I thought I would add it here.
I had a link button and when clicking it, but only in IE9, it appeared to activate another button on the page and call it's event rather than it's own.
After much messing about and googling, I realised that it wasn't just my button that was activating the other button it was if I clicked anywhere in a particular section of my page.
I eventually found the problem after completely stripping down my page. It was this:
<label style="width: 100%" />
an empty label tag. Once deleted all was fine.

Radiobuttonlist results not working when rbl's dynamically created

I have 20 radiobuttonlists which are dynamically created - then declared when a form is submitted.
I also have some code which totals the number of answered questions and the total value of the answered questions. - this code used to work when the radiobuttonlists were hard coded into the page, but it now does not. - I am writing the number of questions answered and the total value of all answers to the page but they come back as 0.
Can anyone see why this might not work now that the radiobuttonlists are dynamically created.?
Code behind:
Sub Page_Load(ByVal Sender as Object, ByVal E as EventArgs)
For i As Integer = 1 To 20
Dim TableRow As New TableRow()
Dim TableRowCell_1 As New TableCell()
TableRow.Cells.Add(TableRowCell_1)
holidayQuestionnaireTable.Rows.Add(TableRow)
Dim question As New RadioButtonList
question.ID = "question" & i
question.Items.Insert(0, new listitem("", "1"))
question.Items.Insert(1, new listitem("", "2"))
TableRowCell_1.Controls.Add(question)
Next
End Sub
...
Sub btnSendFeedback_Click(sender as Object, e as EventArgs)
Dim question1 As RadioButtonList = DirectCast(Page.FindControl("question1"), RadioButtonList)
Dim question2 As RadioButtonList = DirectCast(Page.FindControl("question2"), RadioButtonList)
Dim question3 ...
...
Dim question19 As RadioButtonList = DirectCast(Page.FindControl("question19"), RadioButtonList)
Dim question20 As RadioButtonList = DirectCast(Page.FindControl("question20"), RadioButtonList)
Dim rblCount As Double
Dim total As Double
Dim avg As Double
For Each ctrl As UI.Control In Me.myPanel.Controls
If TypeOf ctrl Is RadioButtonList Then
Dim rbl As RadioButtonList = DirectCast(ctrl, RadioButtonList)
If rbl.SelectedIndex > -1 And not rbl.ID = "question18" Then
Dim value As Double = Double.Parse(rbl.SelectedValue)
total += value
rblCount += 1
End If
End If
Next
Response.Write(rblCount & " - " & total & " - " & (total / rblCount))
End Sub
Body:
<asp:Placeholder ID="myPanel" runat="server">
<asp:Table runat="server" CellPadding="0" CellSpacing="0" GridLines="None" HorizontalAlign="Center" CssClass="ratingtable" ID="holidayQuestionnaireTable" />
<asp:Button OnClick="btnSendFeedback_Click" runat="server" Text="Submit..." ID="submitbutton" />
</asp:Placeholder>
You have changed the content of your panel and added a Table instead of using the Panel to add the RadioButtonLists directly. FindControl will only look into the NamingContainer of the Panel and not of its child controls' NamingContainer. Searching through the control-collection of the Panel does also not work because the RBL's are inside of the Table that is inside of the Panel. Therefore you have to loop the TableRows to get the RBL's. Have a look:
For Each row As TableRow In Me.holidayQuestionnaireTable.Rows
For Each cell As TableCell In row.Cells
For Each ctrl As Control In cell.Controls
If TypeOf ctrl Is RadioButtonList Then
Dim rbl As RadioButtonList = DirectCast(ctrl, RadioButtonList)
If rbl.SelectedIndex <> -1 AndAlso rbl.ID <> "question18" Then
Dim value As Int32 = Int32.Parse(rbl.SelectedValue)
total += value
rblCount += 1 'count only the selected RadiobuttonLists'
End If
End If
Next
Next
Next
If you want to use the FindControl-approach, you have to use the NamingContainer of each radioButtonList and that is the TableRow. So this would also work, but is very static and error-prone:
Dim question1 As RadioButtonList = DirectCast(Me.holidayQuestionnaireTable.Rows(0).FindControl("question1"), RadioButtonList)
Dim question2 As RadioButtonList = DirectCast(Me.holidayQuestionnaireTable.Rows(1).FindControl("question2"), RadioButtonList)
Dim question3 As RadioButtonList = DirectCast(Me.holidayQuestionnaireTable.Rows(2).FindControl("question3"), RadioButtonList)

ListView controls display wrong data the 3rd time

I have a ListView that populates and displays a user's data (via a profile system in VWD 2008) during Page_Load and also when I go from the EditItemTemplate to the ItemTemplate.
When I go to the edit screen again, my DropDownList and RadioButtonList controls display the first items in the corresponding tables instead of the correct profile values.
I don't understand why the controls populate correctly the first and second times but not on the third time (that's right, the third time is NOT a charm).
Can someone can help me understand how to solve this problem?
ItemTemplate:
<asp:DropDownList ID="ddlTState" AppendDataBoundItems="True"
DataSourceID="srcState" DataTextField="StateName" DataValueField="StateName"
Enabled="False" TabIndex="125" runat="server" />
EditItemTemplate:
<asp:DropDownList ID="ddlEState" AppendDataBoundItems="true"
DataSourceID="srcState" DataTextField="StateName"
DataValueField="StateName" TabIndex="125" runat="server">
<asp:ListItem Text="--State--" Value="" />
VB code behind
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
lsv = Util.FindChild(Me, "lsvProfile")
'If Not IsPostBack Then
ddl = Util.FindChild(lsv, "ddlEState") 'Util.FindChild = my version of FindControl
If ddl IsNot Nothing Then ddl.SelectedValue = Profile.State
ddl = Util.FindChild(lsv, "ddlTState")
If ddl IsNot Nothing Then ddl.SelectedValue = Profile.State
'End If
End Sub
It could be it's hitting the null condition and not writing; a better way to handle items/edit template is to tap into the ItemDataBound event or ItemCreated event handlers. This features at the time it creates the row, and you will have better success there. I believe you could also leverage ItemEditing, which fires when a row switches to edit mode, as another way to process an edit action.
EDIT: Try to do this:
protected void lsvProfile_ItemDataBound(..)
{
if (e.Item.ItemTYpe == ListViewItemType.DataItem)
{
DropDownList d = e.Item.FindControl("ddlTState") as DropDownList;
}
}
And debug to see if that is null or not null. The only time that should be null is if its rendering the header/footer or the edit item... That should work though, I do that all the time.
HTH.
Thanks, Brian. I resolved it with this code before I read your latest post:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
lsv = Util.FindChild(Page, "lsvProfile")
If Not IsPostBack Then
Try
lsv.EditIndex = 0
rbl = Util.FindChild(lsv, "rblEGender")
If rbl IsNot Nothing Then rbl.SelectedValue = Profile.Gender
ddl = Util.FindChild(lsv, "ddlEState")
If ddl IsNot Nothing Then ddl.SelectedValue = Profile.State
ddl = Util.FindChild(lsv, "ddlEBirthDay")
If ddl IsNot Nothing Then ddl.SelectedValue = Profile.BirthDay
ddl = Util.FindChild(lsv, "ddlEBirthMo")
If ddl IsNot Nothing Then ddl.SelectedValue = Profile.BirthMo
Catch ex As Exception
End Try
End If
End Sub
Protected Sub lsvProfile_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.ListViewItemEventArgs) Handles lsvProfile.ItemDataBound
ddl = Util.FindChild(Me, "ddlEState")
If ddl IsNot Nothing Then ddl.SelectedValue = Profile.State
ddl = Util.FindChild(Me, "ddlEBirthMo")
If ddl IsNot Nothing Then ddl.SelectedValue = Profile.BirthMo
ddl = Util.FindChild(Me, "ddlEBirthDay")
If ddl IsNot Nothing Then ddl.SelectedValue = Profile.BirthDay
rbl = Util.FindChild(Me, "rblEGender")
If rbl IsNot Nothing Then rbl.SelectedValue = Profile.Gender
End Sub

ASP.Net dropdownlist within a detailsview not being set in codebehind

I have the following code in my codebehind Page_Load function that sets the default selected value of a dropdownlist in detailsview based on the name of a record returned from a sql data query.
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Me.Page.Title = "Editing record"
'Perform dropdown list population operations
Dim myDDL As DropDownList = DetailsView1.FindControl("reqCategoryDropDown")
If Page.IsPostBack = False Then
Dim ticket_ID As String = getDataKey(DetailsView1)
'Fetch Category ID
Dim sqlText As String = "SELECT TS_REQCATEGORY FROM USR_ITFAC WHERE (TS_ID = " + ticket_ID + ") "
Dim reqDataReader As SqlDataReader = GetDataReader(sqlText)
reqDataReader.Read()
Dim category_ID As String = reqDataReader(0)
'Fetch Category name and set as selected value in dropdown list
sqlText = "SELECT TS_NAME FROM TS_SELECTIONS WHERE (TS_ID = " + category_ID + ") "
reqDataReader = GetDataReader(sqlText)
reqDataReader.Read()
category_Name = reqDataReader(0)
'myDDL.DataBind()
myDDL.SelectedValue = category_Name
End If
End Sub
My problem is that when the page loads for the first time, even though I set the selected value for the dropdownlist it will not display and instead simply displays the default first name in my dropdownlist. I tried Binding my dropdownlist before and after I set the selectedvalue, it is commented out in the sample code above, but that didn't seem to do anything.
UPDATE:
I'm setting the data source in the webform as follows:
Dropdownlist:
<asp:DropDownList DataSourceID="ReqCategoryData" DataTextField="ReqCategory" DataValueField="ReqCategory"
ID="reqCategoryDropDown" runat="server" AppendDataBoundItems="true" AutoPostBack="true">
</asp:DropDownList>
Connects to data source a few lines down:
<asp:SqlDataSource ID="ReqCategoryData" runat="server" ConnectionString="<%$ ConnectionStrings:TTPRODReportsQuery %>"
SelectCommand="SELECT TS_NAME AS ReqCategory FROM dbo.TS_SELECTIONS WHERE (TS_FLDID = 5299 AND TS_STATUS = 0) ORDER BY TS_NAME">
</asp:SqlDataSource>
UPDATE_2:
Ok, so I implemented he SQLDataSource programmatically in the code-behind under the Page_Init function as follows:
Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
DetailsView1.DefaultMode = DetailsViewMode.Edit
''Setup DropDownList SqlDataSource
ddlDataSource.ID = "ReqCategoryData"
Page.Controls.Add(ddlDataSource)
ddlDataSource.ConnectionString = ConfigurationManager.ConnectionStrings("TTPRODReportsQuery").ConnectionString
ddlDataSource.SelectCommand = "SELECT TS_NAME AS ReqCategory FROM dbo.TS_SELECTIONS WHERE (TS_FLDID = 5299 AND TS_STATUS = 0) ORDER BY TS_NAME"
Dim args As New DataSourceSelectArguments
ddlDataSource.Select(args)
ddlDataSource.DataBind()
End Sub
After which I set attempt to set the selected value of the dropdownlist as above. The page is still not setting the selected value.
Perhaps check these items:
ensure you're calling myDDL.DataSource = reqDataReader or some other form of setting the DataSource of your dropdownlist.
ensure the dropdownlist has its DataTextField and DataTextField set properly. This could be in code-behind or in markup.
The 0'th index of reqDataReader -- are you sure that's the intended ordinal for the DataValueField?
Perhaps something like this:
With myDDL
.DataTextField = "CategoryName"
.DataValueField = "CategoryID" ' or perhaps CategoryName as your value.
.DataSource = reqDataReader
.DataBind()
.SelectedValue = category_Name ' Name or ID; depends on what was set as DataValueField
End With
DataBinding - Code-Behind vs. Markup DataSources
Consider choosing one style of binding your dropdownlist - in code-behind or with a markup SqlDataSource. Having both generates confusion on which bind wins - the code-behind or the datasource. I think it's the SqlDataSource in this case.
Consider removing the SqlDataSource from out of the markup, and create a method in code-behind whose sole purpose is to create the data binding. This is the only place where the binding should happen. If you ever need to track down a defect or enhance your logic, it's the only one place to visit.
Private Sub BindMyDropDown(Optional ByVal selectedValue as String)
With myDDL
.DataTextField = "CategoryName"
.DataValueField = "CategoryID" ' or perhaps CategoryName as your value.
.DataSource = LoadTicketReqCategory(TicketID)
.DataBind()
.SelectedValue = selectedValue ' Name or ID; depends on what was set as DataValueField
End With
End Sub
From your Page_Load(), check for IsPostBack() and call this method when you aren't posting back.
myDDL.ClearSelection
item = myDDL.Items.FindByValue(category_Name)
item.selected = true
--
You could also try setting the SelectedIndex to 2, for example, to check it that way.
The problem might be that you are assigning the myDDL variable outside of the postback check.
Dim myDDL As DropDownList = DetailsView1.FindControl("reqCategoryDropDown")
If Page.IsPostBack = False Then
Should be
If Page.IsPostBack = False Then
Dim myDDL As DropDownList = DetailsView1.FindControl("reqCategoryDropDown")

Resources