views:

466

answers:

3

Hello, I am new to ASP.net MVC and I am having trouble getting dropdown lists to work correctly.

I have a strongly typed view that is attempting to use a Html.DropDownListFor as follows:

<%=Html.DropDownListFor(Function(model) model.Arrdep, Model.ArrdepOptions)%>

I am populating the list with a property in my model as follows:

Public ReadOnly Property ArrdepOptions() As List(Of SelectListItem)
    Get
        Dim list As New List(Of SelectListItem)
        Dim arriveListItem As New SelectListItem()
        Dim departListItem As New SelectListItem()
        arriveListItem.Text = "Arrive At"
        arriveListItem.Value = ArriveDepart.Arrive
        departListItem.Text = "Depart At"
        departListItem.Value = ArriveDepart.Depart
        Select Case Me.Arrdep
            Case ArriveDepart.Arrive : arriveListItem.Selected = True
            Case Else : departListItem.Selected = True
        End Select
        list.Add(departListItem)
        list.Add(arriveListItem)
        Return list
    End Get
End Property

The Select Case works find and it sets the right SelectListItem as Selected, but when my view renders the dropdown list no matter what is marked as selected the generated HTML does not have anything selected.

I am obviously doing something wrong or missing something, but I can't for the life of me figure out what.

+1  A: 

Try this:

Public ReadOnly Property ArrdepOptions() As SelectList
    Get
        Dim list As New List(Of SelectListItem)()
        Dim arriveListItem As New SelectListItem()
        Dim departListItem As New SelectListItem()
        arriveListItem.Text = "Arrive At"
        arriveListItem.Value = ArriveDepart.Arrive
        departListItem.Text = "Depart At"
        departListItem.Value = ArriveDepart.Depart
        list.Add(departListItem)
        list.Add(arriveListItem)
        Return New SelectList(list, Me.Arrdep)
    End Get
End Property
Johannes Setiabudi
This did not work. The dropdown list was populated with two options containing System.Web.Mvc.SelectListItem (ie. <option>System.Web.Mvc.SelectListItem</option>) Neither had a value associated with it. I appreciate the help by the way.
rybl
Change this line: Return New SelectList(list, Me.Arrdep)to this:Return New SelectList(list, "Text", "Value", Me.Arrdep)
Johannes Setiabudi
This fixed the problem with it showing <option>System.Web.Mvc.SelectListItem</option>, but it still does not select the proper field by default. Thanks again for the help.
rybl
I figured it out. It turns out you have to write a custom dropdown helper if you were interested.
rybl
A: 

The SelectList constructor's 4-th parameter type is Object, but it probably wants an object of the same type as the objects in the list (1-st param). Therefore, the correct syntax should be this:

Public ReadOnly Property ArrdepOptions() As SelectList
  Get
    Dim list As New List(Of SelectListItem)
    Dim arriveListItem As New SelectListItem()
    Dim departListItem As New SelectListItem()
    arriveListItem.Text = "Arrive At"
    arriveListItem.Value = ArriveDepart.Arrive
    departListItem.Text = "Depart At"
    departListItem.Value = ArriveDepart.Depart
    list.Add(departListItem)
    list.Add(arriveListItem)

    Select Case Me.Arrdep
        Case ArriveDepart.Arrive : Return New SelectList(list, "Text", "Value", arriveListItem)
        Case Else : Return New SelectList(list, "Text", "Value", departListItem)
    End Select

  End Get
End Property
Yakimych
I really appreciate the help, but this still has the same behavior. If I select something it sets the value correctly and when I step through the ArrdepOptions property everything works as expected, but when it actually renders the view nothing is still selected in the generated HTML.
rybl
Just before I do more checking - quick guess:change 'Case ArriveDepart.Arrive : Return New SelectList(list, "Text", "Value", arriveListItem)' to 'Case ArriveDepart.Arrive : Return New SelectList(list, "Text", "Value", arriveListItem.Value)' and 'Case Else : Return New SelectList(list, "Text", "Value", departListItem)' to 'Case Else : Return New SelectList(list, "Text", "Value", departListItem.Value)'
Yakimych
Still the same behavior...
rybl
I figured it out. It turns out you have to write a custom dropdown helper if you were interested.
rybl
+1  A: 

It turns out I had to write a dropdown list helper. I found the article here. Here is my code in case someone else needs it. It is roughly translated to VB from the C# example in the article.

Imports System.Linq.Expressions
Imports System.Runtime.CompilerServices

Namespace Helpers

    Public Module HtmlDropDownExtensions

        <Extension()> _
        Public Function EnumDropDownList(Of TEnum)(ByVal htmlHelper As HtmlHelper, ByVal name As String, ByVal selectedValue As TEnum) As MvcHtmlString

            Dim values As IEnumerable(Of TEnum) = [Enum].GetValues(GetType(TEnum))

            Dim list As New List(Of SelectListItem)
            For Each value As TEnum In values
                Dim selectListItem As New SelectListItem()
                selectListItem.Text = value.ToString()
                selectListItem.Value = value.ToString()
                selectListItem.Selected = (value.Equals(selectedValue))
                list.Add(selectListItem)
            Next
            Dim items As IEnumerable(Of SelectListItem) = list

            Return htmlHelper.DropDownList(name, items)

        End Function

        <Extension()> _
        Public Function EnumDropDownListFor(Of TModel, TEnum)(ByVal htmlHelper As HtmlHelper(Of TModel), ByVal expression As Expression(Of Func(Of TModel, TEnum))) As MvcHtmlString

            Dim metadata As ModelMetadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData)

            Dim values As IEnumerable(Of TEnum) = [Enum].GetValues(GetType(TEnum))

            Dim list As New List(Of SelectListItem)
            For Each value As TEnum In values
                Dim selectListItem As New SelectListItem()
                selectListItem.Text = value.ToString()
                selectListItem.Value = value.ToString()
                selectListItem.Selected = (value.Equals(metadata.Model))
                list.Add(selectListItem)
            Next
            Dim items As IEnumerable(Of SelectListItem) = list

            Return htmlHelper.DropDownListFor(expression, items)

        End Function

    End Module

End Namespace
rybl