0

我一直在通過谷歌搜索結果尋找實現某種RadioButton列表(VB,MVC3,Razor)的方法。不幸的是,我發現的大多數結果都在C#中。這是我能找到的最有用的參考:Jon Lanceley's MVC3 RadioButton Helper(順便說一下C#),所以我需要將代碼翻譯成VB(謝謝,developerFusion!)。MVC3 VB Razor不識別轉換後的C#HTML擴展方法代碼

我認爲這會相當直接,但我發現編譯器不能識別函數作爲模塊名稱空間的一部分;一些嘗試解決這個問題隨後出現,但失​​敗了。

這裏是我的代碼(你可以看到所有我通過評論試過的嘗試,與Andrew.San簽署,如果你Ctrl + F它):

助手:

Imports System.Collections.Generic 
Imports System.Linq 
Imports System.Web 
Imports System.Web.Mvc 
Imports System.Web.Mvc.Html 
Imports System.Linq.Expressions 
Imports System.Runtime.CompilerServices 
Imports System.Text 

Namespace RadioButtonListForHelperTest 
    Public Module HtmlExtensions 

     Sub New() 

     End Sub 

     <Extension()> _ 
     Public Function RadioButtonForSelectList(Of TModel, TProperty)(_ 
                      htmlHelper As HtmlHelper(Of TModel), _ 
                      expression As Expression(Of Func(Of TModel, TProperty)), _ 
                      listOfValues As IEnumerable(Of SelectListItem)) As MvcHtmlString 
      Dim metaData = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData) 
      Dim stringBuilder = New StringBuilder() 

      If listOfValues IsNot Nothing Then 
       ' Create a radio button for each item in the list 
       For Each item As SelectListItem In listOfValues 
        ' Generate an id to be given to the radio button field 
        Dim id = String.Format("{0}_{1}", metaData.PropertyName, item.Value) 

        ' Create and populate a radio button using the existing html helpers 
        Dim label = htmlHelper.Label(id, HttpUtility.HtmlEncode(item.Text)) 
        Dim radio = htmlHelper.RadioButtonFor(expression, item.Value, New With { _ 
        Key .id = id _ 
        }).ToHtmlString() 

        ' Create the html string that will be returned to the client 
        ' e.g. <input data-val="true" data-val-required="You must select an option" id="TestRadio_1" name="TestRadio" type="radio" value="1" /><label for="TestRadio_1">Line1</label> 
        stringBuilder.AppendFormat("<div class=&quot;RadioButton&quot;>{0}{1}</div>", radio, label) 
       Next 
      End If 

      Return MvcHtmlString.Create(stringBuilder.ToString()) 
     End Function 
    End Module 
End Namespace 

型號:

Imports System.Collections.Generic 
Imports System.Linq 
Imports System.Web 
Imports System.ComponentModel.DataAnnotations 
Imports System.Web.Mvc 

Namespace RadioButtonListForHelperTest.Models 
    Public Class TestModel 
     Public Property TestRadioList() As IEnumerable(Of SelectListItem) 
      Get 
       Return m_TestRadioList 
      End Get 
      Set(value As IEnumerable(Of SelectListItem)) 
       m_TestRadioList = value 
      End Set 
     End Property 
     Private m_TestRadioList As IEnumerable(Of SelectListItem) 
     Public Property TestRadioList2() As IEnumerable(Of SelectListItem) 
      Get 
       Return m_TestRadioList2 
      End Get 
      Set(value As IEnumerable(Of SelectListItem)) 
       m_TestRadioList2 = value 
      End Set 
     End Property 
     Private m_TestRadioList2 As IEnumerable(Of SelectListItem) 

     <Display(_ 
      Name:="Test Radio 1", _ 
      Description:="This is the first list.", _ 
      Prompt:="Some prompt message.", _ 
      Order:=2)> _ 
     <Required(ErrorMessage:="You must select an option for TestRadio")> _ 
     Public Property TestRadio() As String 
      Get 
       Return m_TestRadio 
      End Get 
      Set(value As String) 
       m_TestRadio = value 
      End Set 
     End Property 
     Private m_TestRadio As String 

     <Display(_ 
      Name:="Test Radio 2", _ 
      Description:="This is the second list.", _ 
      Prompt:="Some prompt message.", _ 
      Order:=1)> _ 
     <Required(ErrorMessage:="You must select an option for TestRadio2")> _ 
     Public Property TestRadio2() As String 
      Get 
       Return m_TestRadio2 
      End Get 
      Set(value As String) 
       m_TestRadio2 = value 
      End Set 
     End Property 
     Private m_TestRadio2 As String 

     ' I tried it out, just in case 
     ' (see Index; @Html.RadioButtonForSelectList). 
     ' It didn't help, really. 
     ' - Andrew.San 
     Public Function RadioButtonForSelectList(Of TModel, TProperty)(_ 
                      htmlHelper As HtmlHelper(Of TModel), _ 
                      expression As Expressions.Expression(Of Func(Of TModel, TProperty)), _ 
                      listOfValues As IEnumerable(Of SelectListItem)) As MvcHtmlString 
      Return RadioButtonListForHelperTest.RadioButtonForSelectList(htmlHelper, expression, listOfValues) 
     End Function 
    End Class 

    Public Class aTest 
     Public Property ID() As Integer 
      Get 
       Return m_ID 
      End Get 
      Set(value As Integer) 
       m_ID = value 
      End Set 
     End Property 
     Private m_ID As Integer 
     Public Property Name() As String 
      Get 
       Return m_Name 
      End Get 
      Set(value As String) 
       m_Name = value 
      End Set 
     End Property 
     Private m_Name As String 
    End Class 
End Namespace 

Controlle R:

Imports System.Collections.Generic 
Imports System.Linq 
Imports System.Web 
Imports System.Web.Mvc 
Imports RadioButtonListForHelperTest.RadioButtonListForHelperTest.Models 

Namespace Controllers 
    Public Class TestController 
     Inherits System.Web.Mvc.Controller 

     ' 
     ' GET: /Test 

     Function Index() As ActionResult 
      Dim list As New List(Of aTest)() 
      list.Add(New aTest() With { _ 
      .ID = 1, _ 
      .Name = "Line1" _ 
      }) 
      list.Add(New aTest() With { _ 
      .ID = 2, _ 
      .Name = "Line2" _ 
      }) 
      list.Add(New aTest() With { _ 
      .ID = 3, _ 
      .Name = "Line3" _ 
      }) 
      Dim sl As New SelectList(list, "ID", "Name") 

      Dim list2 As New List(Of aTest)() 
      list2.Add(New aTest() With { _ 
      .ID = 1, _ 
      .Name = "test1" _ 
      }) 
      list2.Add(New aTest() With { _ 
      .ID = 2, _ 
      .Name = "test2" _ 
      }) 
      Dim sl2 As New SelectList(list2, "ID", "Name") 

      Dim model = New TestModel() 
      model.TestRadioList = sl 
      model.TestRadioList2 = sl2 

      model.TestRadio = "2" 
      ' Set a default value for the first radio button helper 
      Return View(model) 
     End Function 

     ' 
     ' POST: /Test 

     <HttpPost()> _ 
     Public Function Index(model As TestModel, returnUrl As String) As ActionResult 
      If ModelState.IsValid Then 
       ModelState.AddModelError("", "Always force an error to be raised so we can test the postback sets the radio buttons to their last values.") 
      End If 

      ' If we got this far, something failed, redisplay form 
      Dim list As New List(Of aTest)() 
      list.Add(New aTest() With { _ 
      .ID = 1, _ 
      .Name = "Line1" _ 
      }) 
      list.Add(New aTest() With { _ 
      .ID = 2, _ 
      .Name = "Line2" _ 
      }) 
      list.Add(New aTest() With { _ 
      .ID = 3, _ 
      .Name = "Line3" _ 
      }) 
      Dim sl As New SelectList(list, "ID", "Name") 

      Dim list2 As New List(Of aTest)() 
      list2.Add(New aTest() With { _ 
      .ID = 1, _ 
      .Name = "test1" _ 
      }) 
      list2.Add(New aTest() With { _ 
      .ID = 2, _ 
      .Name = "test2" _ 
      }) 
      Dim sl2 As New SelectList(list2, "ID", "Name") 

      model.TestRadioList = sl 
      model.TestRadioList2 = sl2 

      Return View(model) 
     End Function 

    End Class 
End Namespace 

查看:

@Imports RadioButtonListForHelperTest <!-- Andrew.San - Looked up Google on how to import a namespace in VB --> 
@ModelType RadioButtonListForHelperTest.RadioButtonListForHelperTest.Models.TestModel 

@Code 
    Dim obj1 As System.Web.Mvc.HtmlHelper(Of RadioButtonListForHelperTest.RadioButtonListForHelperTest.Models.TestModel) 
    Dim obj2 As System.Web.Mvc.HtmlHelper(Of RadioButtonListForHelperTest.RadioButtonListForHelperTest.Models.TestModel) 
    ViewData("Title") = "Index" 
End Code 

<h2>Index</h2> 

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script> 
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script> 

@Using Html.BeginForm() 
    @Html.ValidationSummary(True) 
    @<fieldset> 
     <legend>TestModel</legend> 

     <div class="editor-label"> 
      @Html.LabelFor(Function(model) model.TestRadio) 
     </div> 
     <div class="editor-field"> 
      @Html.RadioButtonForSelectList(Function(model) model.TestRadio, Model.TestRadioList) 
      <!-- Andrew.San 
       Apparently, the method isn't a member of 
       System.Web.Mvc.HtmlHelper(Of RadioButtonListForHelperTest.RadioButtonListForHelperTest.Models.TestModel), 
       which is odd; I don't see the need for a Model to have this method. 
      --> 

      @RadioButtonListForHelperTest.RadioButtonListForHelperTest.RadioButtonForSelectList(obj1, Function(model) model.TestRadio, Model.TestRadioList) 
      <!-- Andrew.San 
       The compiler needs me to send an htmlHelper argument to the 
       HtmlExtension RadioButtonForSelectList method, 
       which Jon Lanceley didn't need to do. 

       @Html.RadioButtonForSelectList(m => m.TestRadio, Model.TestRadioList) 
      --> 

      @Html.ValidationMessageFor(Function(model) model.TestRadio) 
     </div> 

     <div class="editor-label"> 
      @Html.LabelFor(Function(model) model.TestRadio2) 
     </div> 
     <div class="editor-field"> 
      <!-- Andrew.San 
       As per the first radio button list. 
      --> 
      @Html.RadioButtonForSelectList(Function(model) model.TestRadio2, Model.TestRadioList2) 
      @RadioButtonListForHelperTest.RadioButtonListForHelperTest.RadioButtonForSelectList(obj2, Function(model) model.TestRadio2, Model.TestRadioList2) 
      @Html.ValidationMessageFor(Function(model) model.TestRadio2) 
     </div> 

     <p> 
      <input type="submit" value="Save" /> 
     </p> 
    </fieldset> 
End Using 

<div> 
    @Html.ActionLink("Back to List", "Index") 
</div> 

權。這就是我所擁有的。

回答

0

問題是您的擴展方法位於RadioButtonListForHelperTest名稱空間中,但在您的視圖中,您嘗試訪問它以查看System.Web.Mvc.Html名稱空間。 @HtmlSystem.Web.Mvc

要在相同的命名空間中訪問您的擴展方法,您需要執行以下操作。

將您當前的命名空間更改爲System.Web.Mvc.Html。然後創建一個名爲你喜歡的靜態類,MyExtensions,然後在這個類中包含你的擴展方法。它必須是靜態的。

+0

謝謝您推薦的解決方案。不幸的是,您建議的'公共靜態類MyExtensions'的可訪問性不符合每個VB標準; '公共模塊MyExtensions'將被接受。此外,''只適用於'Module'。引用鏈接** [這裏](http://stackoverflow.com/questions/881570/classes-vs-modules-in-vb-net)**。雖然,不知何故,我找到了解決問題的方法......無論它是否完全萬無一失。我會發布它。 –

+0

我給了你足夠的指引,讓你走向正確的方向。我不認爲我需要握住你的手,並給你完全你需要的代碼。這只是一個命名空間問題。我很抱歉提供C#代碼,但只有真正的程序員使用C#。 –