2013-03-04 11 views
5

這是vb.net中的mvc3 Razor項目。我需要創建一個動態表,1)可以包含1列到3列和1到多行...表中的項目是複選框..我已經在下面的類中有工作助手方法,但下面的方法因爲它只是返回字符串以及Ntd函數的實際字符串,所以只是想知道在那個時候應該發生什麼......我迷失了在遠處生成這些複選框這可以綁定,所以控制器後的方法將保存...如果我只是轉儲頁面上的所有複選框,他們將全部保存並正確更新。佈局只是一個眼睛紅腫..Mvc3 HtmlHelper方法生成格式化的Checkbox表

這是當前視圖

@ModelType xxxxxx.CourseModel 

@Code 
    ViewData("Title") = "Edit Courses" 
End Code 

<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(Nothing, Nothing, FormMethod.Post, New With {.enctype = "multipart/form-data"}) 
    @Html.ValidationSummary(True) 

    @<fieldset> 
     <legend>Edit Courses</legend> 
     @Html.HiddenFor(Function(model) model.cId) 
     <table style="float: left"> 
      <tr> 
       <th>Certification Bodies</th> 
      </tr> 
      <tr> 
       @For _i As Integer = 0 To Model.Bodies.Count - 1 
        Dim i = _i 
        @<td> 
         @Html.CheckBoxFor(Function(model) model.Bodies(i).certSelected) 
         @Html.DisplayFor(Function(f) f.Bodies(i).certName) 
         @Html.HiddenFor(Function(model) model.Bodies(i).certBodyId) 
        </td> 
       Next 
      </tr> 
      <tr> 
       <th><input type="submit" value="Save" /></th> 
      </tr> 
     </table> 
    </fieldset> 
end using 

這是輔助方法

<Extension()> _ 
Public Function CreateCheckBoxTable(ByVal helper As HtmlHelper, ByVal d As List(Of CertBodyVM)) As MvcHtmlString 
    Dim htmlDisplayer As String = Table() 
    Dim counter As Integer = 0 
    For Each item In d 
     If counter = 0 Then 
      htmlDisplayer = htmlDisplayer + NRow() 
     End If 
     counter += 1 
     If Not counter >= 3 Then 
      htmlDisplayer = htmlDisplayer + Ntd("@Html.CheckBoxFor(Function(model) model.Bodies(i).certSelected)@Html.DisplayFor(Function(f) f.Bodies(i).certName)@Html.HiddenFor(Function(model) model.Bodies(i).certBodyId)") 
     Else 
      counter = 0 
      htmlDisplayer = htmlDisplayer + CRow() 
     End If 
    Next 
    htmlDisplayer = htmlDisplayer + CTable() 
    Dim x As MvcHtmlString = MvcHtmlString.Create(htmlDisplayer) 
    Return x 
End Function 

Public Function Table() As String 
    Return String.Format("<table>") 
End Function 
Public Function CTable() As String 
    Return String.Format("</table>") 
End Function 
Public Function NRow() As String 
    Return String.Format("<tr>") 
End Function 

Public Function TdEnd() As String 
    Return String.Format("</td>") 
End Function 

Public Function CRow() As String 
    Return String.Format("</tr>") 
End Function 

Public Function Ntd(ByVal text As String) As String 
    Return String.Format("<td>{0}</td>", text) 
End Function 

要調用的輔助方法,我只是打算更換每個循環及其內容與

@Html.CreateCheckBoxTable(Model.Bodies) 

此方法正在生成適當的表與correc牛逼的行和列,但我失去了對checkboxfor ..

下面是正在產生的電流輸出..

<tr><td><table><tr><td>@Html.CheckBoxFor(Function(model) model.Bodies(i).certSelected)@Html.DisplayFor(Function(f) f.Bodies(i).certName)@Html.HiddenFor(Function(model) model.Bodies(i).certBodyId)</td></table></td></tr> 
+0

當你從該行刪除語音標記,會發生什麼? Ntd(「@ Html.CheckBoxFor(Function(model)model.Bodies(i).certSelected)@ Html.DisplayFor(Function(f)f.Bodies(i).certName)@ Html.HiddenFor(Function(model)model。 (我).certBodyId)「) – Zeddy 2013-03-07 14:47:54

+0

@ZafKhan我已經改變了這一行閱讀:'htmlDisplayer = htmlDisplayer + Ntd(Html.CheckBoxFor(Function(model)model.Bodies(i).certSelected)Html.DisplayFor(Function( f)body(i).certName)Html.HiddenFor(Function(model)model.Body(i).certBodyId))'它表示'CheckBoxFor'不是Html的成員。 – Skindeep2366 2013-03-10 17:25:11

+0

@ Skindeep2366,試試我的答案,它會工作... – 2013-03-12 06:04:07

回答

4

您的代碼將無法正常工作。你將不得不在你的助手中重構lambda表達式。此外,我建議你做這個CreateCheckBoxTable幫手採取lambda表達式,而不是隻有一個CertBodyVM的列表,所以該複選框(或任何其他輸入元素),你可能想在這個表來使用將有適當的名稱:

Public Module MyModule 
    Private indexerMethod As MethodInfo = GetType(IList(Of CertBodyVM)).GetMethod("get_Item") 
    Private certSelectedProperty As PropertyInfo = GetType(CertBodyVM).GetProperty("CertSelected") 
    Private certNameProperty As PropertyInfo = GetType(CertBodyVM).GetProperty("CertName") 
    Private certBodyIdProperty As PropertyInfo = GetType(CertBodyVM).GetProperty("CertBodyId") 

    <Extension()> _ 
    Public Function CreateCheckBoxTable(Of TModel)(ByVal helper As HtmlHelper(Of TModel), ByVal ex As Expression(Of Func(Of TModel, IList(Of CertBodyVM)))) As IHtmlString 
     Dim table = New TagBuilder("table") 
     Dim metadata = ModelMetadata.FromLambdaExpression(ex, helper.ViewData) 
     Dim bodies = CType(metadata.Model, List(Of CertBodyVM)) 
     Dim tableBody = New StringBuilder() 
     For i = 0 To bodies.Count - 1 
      Dim ex1 = MakePropertyExpression(Of TModel, Boolean)(ex, certSelectedProperty, i) 
      Dim ex2 = MakePropertyExpression(Of TModel, String)(ex, certNameProperty, i) 
      Dim ex3 = MakePropertyExpression(Of TModel, Integer)(ex, certBodyIdProperty, i) 

      Dim tr = New TagBuilder("tr") 
      Dim td = New TagBuilder("td") 
      td.InnerHtml = String.Concat(
       helper.CheckBoxFor(ex1), 
       helper.DisplayFor(ex2), 
       helper.HiddenFor(ex3) 
      ) 

      tr.InnerHtml = td.ToString() 
      tableBody.Append(tr.ToString()) 
     Next 
     table.InnerHtml = tableBody.ToString() 

     Return New HtmlString(table.ToString()) 
    End Function 

    Private Function MakePropertyExpression(Of TModel, TProperty)(ByRef ex As Expression(Of Func(Of TModel, IList(Of CertBodyVM))), ByRef pi As PropertyInfo, ByVal i As Integer) As Expression(Of Func(Of TModel, TProperty)) 
     Return Expression.Lambda(Of Func(Of TModel, TProperty))(
      Expression.Property(
       Expression.Call(ex.Body, indexerMethod, Expression.Constant(i)), 
       pi 
      ), 
      ex.Parameters() 
     ) 
    End Function 
End Module 

然後你可以使用這樣的:

@ModelType xxxxxx.CourseModel 
... 
@Html.CreateCheckBoxTable(Function(x) x.Bodies) 
+0

非常感謝您的幫助..是的,我從來沒有想過我的noob編碼冒險中有一個。我確信我會不止一次地使用這一點。 – Skindeep2366 2013-03-14 14:00:31

1

試試這條線

htmlDisplayer = htmlDisplayer + Ntd(helper.CheckBoxFor(Function(model) model.Bodies(i).certSelected)helper.DisplayFor(Function(f) f.Bodies(i).certName)helper.HiddenFor(Function(model) model.Bodies(i).certBodyId)) 
+0

這可能工作,我感謝你的建議。不過,由於他提供的解決方案的穩健性,我將Darling的獎金授予了Darin。通過他的解決方案,我可以添加一些功能,但由於缺乏關於如何操作的知識,所以我一直在徘徊。 – Skindeep2366 2013-03-14 14:02:28