Zeddy
Zeddy

Reputation: 2089

How to implement htmlAttributes MVC for DropDownListFor using VB

I have the following code in my Register.Aspx View page

<div class="FieldDropDown">
  <%: Html.DropDownListFor(Function(m) m.Question, ViewData("Questions"), New With {.style = "margin-bottom: 24px; font-family: Tahoma; font-size: 12pt; color: #333333;"})%>
  <%: Html.ValidationMessageFor(Function(m) m.Question)%>
</div>

The problem is that it keeps popping up an error and I cannot seem to tie down how EXACTLY to implement the code.

I do not have any custom or extra HTML Helpers defined by myself and assumed that it should just work without having to extend the default inbuilt MVC dropdownlistfor helper(?) methods.

The error that appears is...

Overload resolution failed because no accessible 'DropDownListFor' can be called without a narrowing conversion:
Extension method 'Public Function DropDownListFor(Of String)(expression As System.Linq.Expressions.Expression(Of System.Func(Of MvcApplication1.RegisterModel, String)), selectList As System.Collections.Generic.IEnumerable(Of System.Web.Mvc.SelectListItem), htmlAttributes As System.Collections.Generic.IDictionary(Of String, Object)) As System.Web.Mvc.MvcHtmlString' defined in 'System.Web.Mvc.Html.SelectExtensions': Argument matching parameter 'selectList' narrows from 'Object' to 'System.Collections.Generic.IEnumerable(Of System.Web.Mvc.SelectListItem)'.
Extension method 'Public Function DropDownListFor(Of String)(expression As System.Linq.Expressions.Expression(Of System.Func(Of MvcApplication1.RegisterModel, String)), selectList As System.Collections.Generic.IEnumerable(Of System.Web.Mvc.SelectListItem), htmlAttributes As System.Collections.Generic.IDictionary(Of String, Object)) As System.Web.Mvc.MvcHtmlString' defined in 'System.Web.Mvc.Html.SelectExtensions': Argument matching parameter 'htmlAttributes' narrows from '<anonymous type> (line 149)' to 'System.Collections.Generic.IDictionary(Of String, Object)'.
Extension method 'Public Function DropDownListFor(Of String)(expression As System.Linq.Expressions.Expression(Of System.Func(Of MvcApplication1.RegisterModel, String)), selectList As System.Collections.Generic.IEnumerable(Of System.Web.Mvc.SelectListItem), htmlAttributes As Object) As System.Web.Mvc.MvcHtmlString' defined in 'System.Web.Mvc.Html.SelectExtensions': Argument matching parameter 'selectList' narrows from 'Object' to 'System.Collections.Generic.IEnumerable(Of System.Web.Mvc.SelectListItem)'.

When I remove the HTMLATTRIBUTES to the following code below, then it works fine and no errors appear but then neither is the DropDownList styled and it just looks plain without the CSS formatting that I would like to have on it...

<div class="FieldDropDown">
  <%: Html.DropDownListFor(Function(m) m.Question, ViewData("Questions"))%>
  <%: Html.ValidationMessageFor(Function(m) m.Question)%>
</div>

What i'm trying to understand is...

Do I need to extend the htmlhelper for the dropdownlist? Do I need to add something in my controller code?

My controller code is as follows...

<Required()> _
Public Property Question() As String
  Get
    Return _Question
  End Get
  Set(value As String)
    _Question = value
  End Set
End Property

Any pointers in the right direction or reference links would be helpful. Thank You

Edit

This code below is inside my Reagister ACTION in the ACCOUNT controller.

'-> Okay
Item0 = NewQuestion("0", "Please select an option", True)
Item1 = NewQuestion("1", "What was your mothers maiden name?", False)
Item2 = NewQuestion("2", "Where were you born?", False)
Item3 = NewQuestion("3", "What was the name of your first love?", False)
Item4 = NewQuestion("4", "What was the name of your favourite pet?", False)
Item5 = NewQuestion("5", "What is the name of your favourite song?", False)
Item6 = NewQuestion("6", "What is the name of your idol/mentor?", False)
Item7 = NewQuestion("7", "What model of your first car?", False)
Item8 = NewQuestion("8", "What model was your first motorcycle?", False)
Item9 = NewQuestion("9", "Who is your favourite sports-person?", False)
Item10 = NewQuestion("10", "What was your last ACTIVATION KEY?", False)
SQuestions = Nothing
SQuestions = New SelectList({Item0, Item1, Item2, Item3, Item4, Item5, Item6, Item7, Item8, Item9, Item10}, Item0)
Session("Website_Guest") = ThisGuest
ViewData("VisitorName") = ThisGuest.Username
'ViewData("Questions") = New SelectList(SQuestions.Items) <- TRIED IT LIKE THIS TOO
'ViewData("Questions") = New SelectList(SQuestions) <- TRIED IT LIKE THIS TOO
ViewData("Questions") = sQuestions
ViewData("PasswordLength") = MembershipService.MinPasswordLength
Return View()

And this is the NEWQUESTION Function which outputs a selectlistitem

Private Function NewQuestion(NewValue As String, NewData As String, NewSelected As Boolean) As SelectListItem
Dim Item As SelectListItem = Nothing
  Item = Nothing
  If Trim(NewValue) <> "" Then
    If Trim(NewData) <> "" Then
        Item = New SelectListItem()
        Item.Value = NewValue
        Item.Text = NewData
        Item.Selected = NewSelected
    End If
  End If
  Return Item
  Item = Nothing
End Function

So in essence, I am passing a selectlist in the first instance so thats why i did not cast into another selectlist - although like i said in my comment it DOES fix the styling but leaves me with another issue re: the photo below shows what i get..

enter image description here

Closure

Thank you everyone who helped me figure this out, I've marked one of them as the answer as that persons answer helped me pinpoint the issue, it doesnt neccessarily means the other answer was wrong, its probably my lack of understanding more than anything.

to resolve the issue I looked again at the way i was passing the viewdata and although i DID pass a SELECTLIST, i reverted to passing a SELECTLIST.ITEMS collection and then in the VIEW i re-scoped the passed data to a selectlist, and now the data is visible instead of selectlist objects AND it has the HTMLATTRIBUTES appended in the HTML.DROPDOWNLISTFOR method.

Thanks everyone.

Upvotes: 3

Views: 2946

Answers (2)

mipe34
mipe34

Reputation: 5666

For original question

Html.DropDownListFor needs IEnumerable<SelectListItem> so you need to cast object from ViewData to SelectList.

For edit

Use overloaded constructor of SelectList, where you specify the dataValueField and dataTextField(eventually selectedItem).

new SelectList(collection, "DataValueFieldName", "DataTextFieldName", "SelectedItemValue");

Upvotes: 2

Rhumborl
Rhumborl

Reputation: 16609

I don't know why you are only getting an error when you include the attributes object, but I think the problem is with ViewData("Questions") returning an Object, not an IEnumerable(Of SelectListItem), so try:

<%: Html.DropDownListFor(Function(m) m.Question,
  TryCast(ViewData("Questions"), SelectList),
  New With {.style = "margin-bottom: 24px; font-family: Tahoma; font-size: 12pt; color: #333333;"}) %>

Something similar at http://forums.asp.net/t/1466151.aspx/1

Upvotes: 3

Related Questions