2013-03-04 1 views
5

Это проект mvc3 Razor в vb.net. Мне нужно создать динамическую таблицу, в которой 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) 

Этот метод генерирует соответствующую таблицу с помощью коррекции т строк и столбцов, но я потерял на 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 (функция (модель) model.Bodies (i) .certSelected) @ Html.DisplayFor (функция (f) f.Bodies (i) .certName) @ Html.HiddenFor (модель (модель). Bodies (i) .certBodyId) ") – Zeddy

+0

@ ZafKhan Я изменил эту строку следующим образом:' htmlDisplayer = htmlDisplayer + Ntd (Html.CheckBoxFor (функция (model) model.Bodies (i) .certSelected) Html.DisplayFor (Функция (f) f.Bodies (i) .certName) Html.HiddenFor (функция (модель) model.Bodies (i) .certBodyId)) 'и это говорит, что' CheckBoxFor' не является членом Html. – Skindeep2366

+0

@ Skindeep2366, попробуйте мой ответ, это сработает ... –

ответ

4

Ваш код не будет работать. Вам придется перестроить лямбда-выражения в вашем помощнике. Кроме того, я бы порекомендовал вам сделать это CreateCheckBoxTable помощник принимают лямбда-выражения вместо только список CertBodyVM так, чтобы CheckBox (или любые другие элементы ввода), вы можете использовать в этой таблице будут иметь собственные имена:

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

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

Это может сработать, и я благодарю вас за предложение. Однако я наградил Дарина благодарностью из-за надежности решения, которое он предоставил. С его решением я могу сделать это, чтобы добавить множество функций, от которых я хромал, из-за простого незнания того, как это сделать. – Skindeep2366