2013-04-01 2 views
0

Используя образец объяснения найти на MSDN для:Проблема с выбором selcteditem в MVC 2.0 dropdownfor элемента зрения - всегда выбирает первый элемент

SelectList класса (http://msdn.microsoft.com/en-us/library/system.web.mvc.selectlist_members(v=vs.90).aspx)

SelectListItem (http://msdn.microsoft.com/en-us/library/system.web.mvc.multiselectlist.items(v=vs.90).aspx)

И IEnumerable (http://msdn.microsoft.com/en-us/library/system.collections.ienumerable(v=vs.90).aspx)

Я создал следующие классы из образца кода Person/People.

Public Class Choice 
    ' 
    Private _Value As String = Nothing 
    Private _Text As String = Nothing 
    Private _Selected As Boolean = Nothing 
    ' 
    Property ItemValue As String 
    Get 
     Return _Value 
    End Get 
    Set(value As String) 
     _Value = value 
    End Set 
    End Property 
    ' 
    Property ItemText As String 
    Get 
     Return _Text 
    End Get 
    Set(value As String) 
     _Text = value 
    End Set 
    End Property 
    ' 
    Property ItemSelected As Boolean 
    Get 
     Return _Selected 
    End Get 
    Set(value As Boolean) 
     _Selected = value 
    End Set 
    End Property 
    ' 
    Public Sub New(ByVal pValue As String, ByVal pText As String) 
    Me._Value = pValue 
    Me._Text = pText 
    Me._Selected = False 
    End Sub 
    ' 
    Public Sub New(ByVal pValue As String, ByVal pText As String, pSelected As Boolean) 
    Me._Value = pValue 
    Me._Text = pText 
    Me._Selected = pSelected 
    End Sub 
' 
End Class 


Public Class Choices 
    Implements IEnumerable 
    ' 
    Private _Choices() As Choice 
    ' 
    Public ReadOnly Property SelectedValue() As Choice 
    Get 
     Dim i As Integer = Nothing 
     Dim x As Choice = Nothing 
     For i = 0 To _Choices.Length - 1 
     If _Choices(i).ItemSelected Then 
      x = _Choices(i) 
      Exit For 
     End If 
     Next i 
     Return x 
     i = Nothing 
     x = Nothing 
    End Get 
    End Property 
    ' 
    Public Sub New(ByVal pArray() As Choice) 
    _Choices = New Choice(pArray.Length - 1) {} 
    Dim i As Integer 
     For i = 0 To pArray.Length - 1 
     _Choices(i) = pArray(i) 
     Next i 
    End Sub 
    ' 
    Public Function GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator 
    Return New ChoicesEnum(_Choices) 
    End Function 
    ' 
End Class 


Public Class ChoicesEnum 
    Implements IEnumerator 
    ' 
    Public _Choices() As Choice 
    ' 
    Dim position As Integer = -1 
    ' 
    Public Sub New(ByVal list() As Choice) 
    _Choices = list 
    End Sub 
    ' 
    Public Function MoveNext() As Boolean Implements IEnumerator.MoveNext 
    position = position + 1 
    Return (position < _Choices.Length) 
    End Function 
    ' 
    Public Sub Reset() Implements IEnumerator.Reset 
    position = -1 
    End Sub 
    ' 
    Public ReadOnly Property Current() As Object Implements IEnumerator.Current 
    Get 
     Try 
     Return _Choices(position) 
     Catch ex As IndexOutOfRangeException 
     Throw New InvalidOperationException() 
     End Try 
    End Get 
    End Property 
    ' 
End Class 

В моей модели я объявил его следующим образом

Private _Gender As Integer = Nothing 

В моем контроллере я экземпляр SelectList следующим образом:

Friend Function GetGenderList(SelId As Integer) As SelectList 
    ' 
    Dim ChoicesArray() As Choice = { _ 
    New Choice("0", "Please Select Gender", IIf(SelId = 0, True, False)), _ 
    New Choice("1", "Male", IIf(SelId = 1, True, False)), _ 
    New Choice("2", "Female", IIf(SelId = 2, True, False)), _ 
    New Choice("3", "Unspecified", IIf(SelId = 3, True, False))} 
    Dim ChoicesList As New Choices(ChoicesArray) 
    GetGenderList = New SelectList(ChoicesList, ChoicesList(SelId)) 
    ChoicesList = Nothing 
    ChoicesArray = Nothing 
    ' 
End Function 

Тогда я прохожу SelectList в ViewData к вид

<ChildActionOnly()> _ 
Function EditPersonalUserCtrl(ByVal MyPersonal As MemberPersonalModel, FoundErrorInfo As String) As PartialViewResult 
    Dim sxGenderList As SelectList = Nothing 
    sxGenderList = GetGenderList(MyPersonal.Gender) 
    ViewData.Add("Gender", sxGenderList) 
    ViewData.Add("FoundErrorInfo", FoundErrorInfo) 
    Return PartialView(MyPersonal) 
    sxGenderList = Nothing 
End Function 

На мой взгляд HTML выглядит следующим образом

<tr> 
    <td class="FormFieldLabel" style="width: 30%;">Gender</td> 
    <td class="FormFieldLabel" style="width: 70%;"> 
    <%= Html.DropDownListFor(Function(Model) Model.Gender, New SelectList(ViewData("Gender").Items, "ItemValue", "ItemText", "ItemSelected"), New With {.style = "font-family: Tahoma; font-size: 14pt; color: #333333;"})%> 
    <%= Html.ValidationMessageFor(Function(Model) Model.Gender)%> 
    </td> 
</tr> 

Когда я пытаюсь представление в EDIT/обновите SelectList/DropDown всегда показывает первый пункт меню в списке, независимо или Что выбран.

Его сбивало с толку меня в течение двух дней, и я не вижу, где это происходит! Пожалуйста, кто-нибудь может взглянуть на мой код и посмотреть, куда он идет на запад.

Заранее спасибо.

ответ

0

После пробы различных подходов я думал, что лучшим решением было написать собственный SelectListExtension.

Расширение, которое я написал, основано на классах «Выбор», «Выборы» и «ChoicesEnum».

Public Module ChoicesListExtension 

    <Extension()> 
    Public Function DropDownListFor(ByVal ObjSelectList As Choices, ByVal HtmlCtrlId As String) As String 
    ' 
    Dim Buf As String = Nothing 
    Dim Counter1 As Integer = Nothing 
    ' 
    Buf = "" 
    If (ObjSelectList Is Nothing) = False Then 
     If Trim(HtmlCtrlId) <> "" Then 
     Buf = "<select id=" & Chr(34) & Trim(HtmlCtrlId) & Chr(34) & ">" & vbCrLf 
     Else 
     Buf = "<select>" & vbCrLf 
     End If 
     If ObjSelectList.Items.Count > 0 Then 
     For Counter1 = 0 To ObjSelectList.Items.Count - 1 
      Buf = Buf & " <option value=" & Chr(34) & ObjSelectList(Counter1).ItemValue Chr(34) 
      If ObjSelectList(Counter1).ItemSelected Then Buf = Buf & " selected=" & Chr(34) & "selected" & Chr(34) 
      Buf = Buf & ">" & Trim(ObjSelectList(Counter1).ItemText) & "</option>" & vbCrLf 
     Next 
     End If 
     Buf = Buf & "</select>" & vbCrLf 
    End If 
    DropDownListFor = Buf 
    Buf = Nothing 
    Counter1 = Nothing 
    ' 
    End Function 





    <Extension()> 
    Public Function DropDownListFor(ByVal ObjSelectList As Choices, ByVal HtmlCtrlId As String, ByVal HtmlAttribs As RouteValueDictionary) As String 
    ' 
    Dim Buf As String = Nothing 
    Dim Counter1 As Integer = Nothing 
    Dim Counter2 As Integer = Nothing 
    ' 
    Buf = "" 
    If (ObjSelectList Is Nothing) = False Then 
     If Trim(HtmlCtrlId) <> "" Then 
     Buf = "<select id=" & Chr(34) & Trim(HtmlCtrlId) & Chr(34) 
     If HtmlAttribs.Count > 0 Then 
      For Counter1 = 0 To HtmlAttribs.Count - 1 
      Buf = Buf & " " & HtmlAttribs.Keys(Counter1) & "=" & Chr(34) & HtmlAttribs.Values(Counter1) & Chr(34) 
      Next 
     End If 
     Buf = Buf & ">" & vbCrLf 
     Else 
     Buf = "<select>" & vbCrLf 
     End If 
     If ObjSelectList.Items.Count > 0 Then 
     For Counter2 = 0 To ObjSelectList.Items.Count - 1 
      Buf = Buf & " <option value=" & Chr(34) & ObjSelectList(Counter2).ItemValue & Chr(34) 
      If ObjSelectList(Counter2).ItemSelected Then Buf = Buf & " selected=" & Chr(34) & "selected" & Chr(34) 
      Buf = Buf & ">" & Trim(ObjSelectList(Counter2).ItemText) & "</option>" & vbCrLf 
     Next 
     End If 
     Buf = Buf & "</select>" & vbCrLf 
    End If 
    DropDownListFor = Buf 
    Buf = Nothing 
    Counter1 = Nothing 
    Counter2 = Nothing 
    ' 
    End Function 

End Module