【问题标题】:Issue with selecting the selcteditem in mvc 2.0 dropdownfor element in view - Always selects first element在 mvc 2.0 dropdownfor element in view 中选择所选项目的问题 - 始终选择第一个元素
【发布时间】:2013-04-01 08:47:35
【问题描述】:

使用 MSDN 上的示例解释:

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

选择列表项 (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

在我的控制器中,我按如下方式实例化一个选择列表:

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

然后我将viewdata中的selectlist传递给视图

<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/UPDATE 中尝试查看时,SelectList/DropDown 始终显示列表中的第一个选项项,无论选择了什么。

它让我困惑了两天,我看不出它哪里出了问题! 请有人看看我的代码,看看它往西走去哪里。

提前致谢。

【问题讨论】:

    标签: asp.net-mvc-2 asp.net-3.5 selecteditem selectlist


    【解决方案1】:

    在尝试了各种方法后,我认为最好的解决方案是编写自己的 SelectListExtension。

    我编写的扩展基于“Choice”、“Choices”和“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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-11-16
      • 1970-01-01
      • 2014-04-20
      • 2018-11-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多