0

I have something like this

public class ViewModel1
{
   // some properties here
   public List<ViewModel2> ViewModel2 {get; set;}
}

public class ViewModel2
{
   public string A {get; set;}
   public string B {get; set;}
}

// view

<table>
  <thead>
     <tr> a </tr>
     <tr> b </tr>
  </thead>
   <tbody>
      // want to use a display template to render table row and cells so I don't need to use for loop 
   </tbody>
</table>

I tried to use "@Html.DisplayForModel()" but that I seems to take the viewModel of the view(so in my case ViewModel1)

I need to make it take ViewModel2 but I don't see any option to pass in ViewModel2(a model object).

I then tried

 @Html.DisplayFor(x => x.ViewModel2)

That did not work to well it just printed out like the first properties value and never even made any cells.

Here is basically my display template

@model ViewModel2

  <tr>
        <td>@Model.A</td>
        <td>@Model.B</td>
 </tr>   

So how can I make this work?

chobo2
  • 83,322
  • 195
  • 530
  • 832

2 Answers2

1

Try like this:

<table>
    <thead>
        <tr>
            <th>a</th>
            <th>b</th>
        </tr>
    </thead>
    <tbody>
        @Html.DisplayFor(x => x.ViewModel2)
    </tbody>
</table>

and then inside ~/Views/Shared/DisplayTemplates/ViewModel2.cshtml:

@model ViewModel2
<tr>
    <td>@Model.A</td>
    <td>@Model.B</td>
</tr> 

Notice the name and location of the display template. It is important to respect this convention if you want this to work.

Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
0

If you REALLY don't want the foreach in your "main" template, you can tag your property with UIHint

public class ViewModel1
{
   // some properties here
   [UIHint("ListOfViewModel2")]
   public List<ViewModel2> ViewModel2 {get; set;}
}

Then, in DisplayTemplates\ListOfViewModel2.ascx, you put your foreach

@model IList<ViewModel2>

foreach( var m in Model )
{
    <tr>@Html.DisplayFor(x => m)</tr>
}

Dont change your DisplayModel for ViewModel2, and in you view, you can call

@Html.DisplayFor(x => x.ViewModel2)
mathieu
  • 30,974
  • 4
  • 64
  • 90
  • @mathieu - well it's not that I really don't want to put a foreach loop in my main(if I don't have to thats great if I do that is ok). It more the fact that doing it this way solves the problem with the "name" attribute otherwise I got to make a counter to make sure the names are different. So you know a way around that looks good then I might go that way. I will look into what you have but I don't get what "ListOfViewModel2" is. – chobo2 Apr 03 '11 at 19:48
  • Its the name of the template file. By default, property type name is used. When you have properties of type like "IList", you can't name a file "IList.ascx". So you put an UIHint on the property to tell ASP.NET MVC which displaytemplate to use. – mathieu Apr 03 '11 at 19:51
  • @mathieu - Ok I put my UiHint with my template file name. I put @Html.DisplayForModel() and changed my template to have a foreach loop. However it still is using the wrong viewModel. It still is using ViewModel1 for the DisplayForModel template. It's not using my ViweModel2 template – chobo2 Apr 03 '11 at 19:55
  • @Html.DisplayFor(x => x.ViewModel2) – mathieu Apr 03 '11 at 20:00
  • @mathieu - Tried that too but all id's and names have same names what is not valid html. – chobo2 Apr 03 '11 at 20:11
  • @chobo2 - So you absolutely need valid html? why? – John Farrell Apr 03 '11 at 22:16
  • I don't see any id generated in your display template ? – mathieu Apr 04 '11 at 07:10
  • @jfar - I like to keep standards.@mathieu - Yes in my code it would not. In my real code I am using checkboxfor() that generates a name and id. – chobo2 Apr 04 '11 at 17:36