2013-03-04 10 views
5

Questo è un progetto mvc3 Razor in vb.net. Ho bisogno di creare una tabella dinamica che 1) possa contenere 1 colonna in 3 colonne e 1 in molte righe ... Gli elementi nella tabella sono caselle di controllo. Ho già metodi di supporto operativi nella classe sottostante, tuttavia il metodo qui sotto è sollevato sul ritorno poiché restituisce semplicemente la stringa insieme alla stringa effettiva della funzione Ntd, questo è lì semplicemente per un'idea di cosa dovrebbe accadere a quel punto ... Sono perso per generare queste check-in in che può essere vincolato in modo che il metodo di post del controller salverà ... Se metto semplicemente tutte le caselle di controllo sulla pagina, verranno tutte salvate e aggiornate correttamente. Il layout è solo un occhio dolente ..Mvc3 Metodo HtmlHelper per generare la tabella Checkbox formattata

Questa è la vista corrente

@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 

Questo è il metodo di supporto

<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 

Per chiamare il metodo di supporto ho solo intenzione di sostituire il per ogni loop e il suo contenuto con

@Html.CreateCheckBoxTable(Model.Bodies) 

Questo metodo genera la tabella appropriata con il correc t righe e colonne ma sono persi sul checkboxfor ..

Di seguito si riporta la corrente di uscita che viene generato ..

<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

Cosa succede quando si rimuove i segni di discorso da questa linea? Ntd ("@ Html.CheckBoxFor (modello Function (model). Bodies (i) .certSelected) @ Html.DisplayFor (Function (f) f.Bodies (i) .certName) @ Html.HiddenFor (modello di funzione (modello). Corpi (i) .certBodyId) ") – Zeddy

+0

@ZafKhan Ho modificato la riga da leggere:' htmlDisplayer = htmlDisplayer + Ntd (Html.CheckBoxFor (modello di funzione (modello). Body (i) .certSelected) Html.DisplayFor (Funzione (f) f.Bodies (i) .certName) Html.HiddenFor (Function (model) model.Bodies (i) .certBodyId)) 'e sta dicendo che' CheckBoxFor' non è un membro di Html. – Skindeep2366

+0

@ Skindeep2366, prova la mia risposta funzionerà ... –

risposta

4

Il codice non funziona. Dovrai ricomporre le espressioni lambda nel tuo helper. Inoltre vi consiglio di fare questa CreateCheckBoxTable aiutante prendere un'espressione lambda invece di solo un elenco di CertBodyVM in modo che la casella (o qualsiasi altro elemento di input) si potrebbe desiderare di utilizzare in questa tabella avrà nomi propri:

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 

E allora si potrebbe utilizzare in questo modo:

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

Grazie mille per l'aiuto .. Sì, non l'avrei mai immaginato nella mia avventura di codifica noob. Sono certo che ne userò uno più di una volta. – Skindeep2366

1

Prova questa linea

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

Questo potrebbe funzionare e ti ringrazio per il suggerimento. Tuttavia ho assegnato il premio a Darin a causa della robustezza della soluzione che ha fornito. Con la sua soluzione, ne posso uno per aggiungere una varietà di funzioni da cui mi sono allontanato per semplice mancanza di conoscenza su come farlo. – Skindeep2366

Problemi correlati