Wednesday, March 28, 2012

Trouble binding a dropdown list in a detailsview.

Ok, I'm lost. I'm writing a webpage in VB/Dot Net 2.0 and I'm trying to put
a
dropdown list in a detailsview. The dropdownlist is supposed to display a
simple enum.
From what little I've seen so far, the place in VB code to bind a ddl is in
the detailview's databound event. Any earlier and you can't get a handle on
the ddl. The detailsview is essentially alone on it's page and is called in
either edit or insert mode only. (In the page lode, I examine a querystring
parameter and based on that, set the detailsview to either edit or insert
mode.) I have created template ddls in the column corresponding to this
variable. All existing records have valid values in this field (a smallint)
.
The code itself is routine:
ddlClassType = DetailsView1.FindControl("ddlClassType")
Dim names() As String = System.Enum.GetNames(GetType(ClassType))
Dim values() As Integer = System.Enum.GetValues(GetType(ClassType))
Dim i As Integer
For i = 0 To names.Length - 1
Dim item As New ListItem(names(i), values(i).ToString)
ddlClassType.Items.Add(item)
Next
This works fine for Inserts but the code never gets to this point for
updates. It crashes with the error: 'ddlClassType' has a SelectedValue whic
h
is invalid because it does not exist in the list of items. Parameter name:
value
Any suggestions?Howdy,
Moving population code into detail's DataBinding event should resolve the
problem. Take a look at your aspx code and notice, there's Bind or Eval
statement inside SelectedValue: SelectedValue='<%# Eval("WhatEver") %>' whic
h
expects items have already been populated. Unfortunatelly, you're populating
items afterwards, hence the exception.
hope this helps
--
Milosz
"B. Chernick" wrote:

> Ok, I'm lost. I'm writing a webpage in VB/Dot Net 2.0 and I'm trying to pu
t a
> dropdown list in a detailsview. The dropdownlist is supposed to display a
> simple enum.
> From what little I've seen so far, the place in VB code to bind a ddl is i
n
> the detailview's databound event. Any earlier and you can't get a handle
on
> the ddl. The detailsview is essentially alone on it's page and is called
in
> either edit or insert mode only. (In the page lode, I examine a querystrin
g
> parameter and based on that, set the detailsview to either edit or insert
> mode.) I have created template ddls in the column corresponding to this
> variable. All existing records have valid values in this field (a smallin
t).
>
> The code itself is routine:
> ddlClassType = DetailsView1.FindControl("ddlClassType")
> Dim names() As String = System.Enum.GetNames(GetType(ClassType))
> Dim values() As Integer = System.Enum.GetValues(GetType(ClassType))
> Dim i As Integer
> For i = 0 To names.Length - 1
> Dim item As New ListItem(names(i), values(i).ToString)
> ddlClassType.Items.Add(item)
> Next
> This works fine for Inserts but the code never gets to this point for
> updates. It crashes with the error: 'ddlClassType' has a SelectedValue wh
ich
> is invalid because it does not exist in the list of items. Parameter name:
> value
> Any suggestions?
>
Sorry, actually no. If I move the code into the DetailView's DataBinding
event (or the screen's), the code fails entirely because it can't find the
ddl. Hasn't been rendered yet.
I have a vague memory of populating a dropdown in my last job using
javascript and those <%# %> brackets, but I'm still digging through my notes
for that one. Have you ever done that?
"Milosz Skalecki [MCAD]" wrote:
> Howdy,
> Moving population code into detail's DataBinding event should resolve the
> problem. Take a look at your aspx code and notice, there's Bind or Eval
> statement inside SelectedValue: SelectedValue='<%# Eval("WhatEver") %>' wh
ich
> expects items have already been populated. Unfortunatelly, you're populati
ng
> items afterwards, hence the exception.
> hope this helps
> --
> Milosz
>
> "B. Chernick" wrote:
>
Many times. Paste the code.
--
Milosz
"B. Chernick" wrote:
> Sorry, actually no. If I move the code into the DetailView's DataBinding
> event (or the screen's), the code fails entirely because it can't find the
> ddl. Hasn't been rendered yet.
> I have a vague memory of populating a dropdown in my last job using
> javascript and those <%# %> brackets, but I'm still digging through my not
es
> for that one. Have you ever done that?
> "Milosz Skalecki [MCAD]" wrote:
>
Hi
On 17 Nov, 01:37, B. Chernick wrote:
> Sorry, actually no. If I move the code into the DetailView's DataBinding
> event (or the screen's), the code fails entirely because it can't find the
> ddl. Hasn't been rendered yet.
Milosz is right about the timing of the code causing the exception. In
insert mode, there is no attempt to automatically bind the selected
value of the ddl control to a field value because it's a new record,
whereas in Edit mode it tries to bind the selected value to the
current value of the field.
To get round this you'll have to delete the databinding between the
ddl and the datasource (in the edit mode template) and set the
selected value manually in code immediately after the code you have
already written. In the DataBound event, you can differentiate
betweeen the two modes using DetailsView1.CurrentMode() and make the
code for setting the ddl selected value conditonal upon that.
You'll also need to handle the update manually for the respective
datafield as well in the Updating event.
HTH
Thank you Milosz and Phil.
Out of town for the holiday but I continue this as soon as I get home Friday
.
"Phil H" wrote:

> Hi
> On 17 Nov, 01:37, B. Chernick wrote:
> Milosz is right about the timing of the code causing the exception. In
> insert mode, there is no attempt to automatically bind the selected
> value of the ddl control to a field value because it's a new record,
> whereas in Edit mode it tries to bind the selected value to the
> current value of the field.
> To get round this you'll have to delete the databinding between the
> ddl and the datasource (in the edit mode template) and set the
> selected value manually in code immediately after the code you have
> already written. In the DataBound event, you can differentiate
> betweeen the two modes using DetailsView1.CurrentMode() and make the
> code for setting the ddl selected value conditonal upon that.
> You'll also need to handle the update manually for the respective
> datafield as well in the Updating event.
> HTH
>
After some trial and error, I finally got it to work. Is this roughly what
you had in mind? (I first replaced the ddl in the edit template with a new
unbound dropdownlist.)
Private Sub DetailsView1_DataBound(ByVal sender As Object, ByVal e As
System.EventArgs) Handles DetailsView1.DataBound
Dim names() As String = System.Enum.GetNames(GetType(ClassType))
Dim values() As Integer = System.Enum.GetValues(GetType(ClassType))
If DetailsView1.CurrentMode = DetailsViewMode.Edit Then
ddlClassType = DetailsView1.FindControl("ddlClassType")
Dim i As Integer
For i = 0 To names.Length - 1
Dim item As New ListItem(names(i), values(i).ToString)
ddlClassType.Items.Add(item)
Next
' Set incoming value
Dim dr As DataRowView
dr = DetailsView1.DataItem
ddlClassType.SelectedValue = dr.Item("ClassType").ToString
End If
End Sub
Private Sub ObjectDataSource1_Updating(ByVal sender As Object, ByVal e
As System.Web.UI.WebControls.ObjectDataSourceMethodEventArgs) Handles
ObjectDataSource1.Updating
' manually update values here
ddlClassType = DetailsView1.FindControl("ddlClassType")
e.InputParameters.Item("ClassType") = ddlClassType.SelectedValue
End Sub
"Phil H" wrote:

> Hi
> On 17 Nov, 01:37, B. Chernick wrote:
> Milosz is right about the timing of the code causing the exception. In
> insert mode, there is no attempt to automatically bind the selected
> value of the ddl control to a field value because it's a new record,
> whereas in Edit mode it tries to bind the selected value to the
> current value of the field.
> To get round this you'll have to delete the databinding between the
> ddl and the datasource (in the edit mode template) and set the
> selected value manually in code immediately after the code you have
> already written. In the DataBound event, you can differentiate
> betweeen the two modes using DetailsView1.CurrentMode() and make the
> code for setting the ddl selected value conditonal upon that.
> You'll also need to handle the update manually for the respective
> datafield as well in the Updating event.
> HTH
>

0 comments:

Post a Comment