Reputation: 5670
I've got a view that displays a list of items. Rather than display items in a grid, I'd like to display 4 items per page, each with an image and multiple properties, displayed in a unique layout.
So, I'd like a foreach to iterate through the items, and each item to get displayed in a div. I could put all the code in the loop, but I'd like to have a custom html helper extension to do this.
I came up with this,
public static MvcHtmlString DisplayViewerFor(this HtmlHelper helper, TestModel model, bool rightAligned = true) {
if (model == null) {
model = new TestModel();
}
var outterDiv = new TagBuilder("div");
outterDiv.AddCssClass(rightAligned ? "item-display-right" : "item-display");
var image = new TagBuilder("image");
image.Attributes.Add("src", "Item/GetImage/" + model.ItemName);
image.Attributes.Add("height", "150");
var editorLabel = new TagBuilder("div");
editorLabel.AddCssClass("editor-label");
//LOOKING TO ADD CODE LIKE THIS HERE
var labelContent= html.LabelFor({my model property here})
editorLabel.InnerHtml += labelContent;
//END OF ADD
return new MvcHtmlString(outterDiv.ToString(TagRenderMode.EndTag));
}
In my method above, I need to display a few more values, and I would like to use the Html.LabelFor and Html.DisplayFor helpers, but the methods aren't available and I'm not sure what to pass to them if they were.
I'm not sure if this is possible or not, but I thought I would ask.
EDIT I'm trying to use the html.LabelFor. See my code where I have updated it above, adding to it these two lines.
var labelContent= html.LabelFor({my model property here})
editorLabel.InnerHtml += labelContent;
You can see the code above.
EDIT 2
Here is the planned use for this Helper with dummied down view.
@model TestItemDisplayList
@{ ViewBag.Title = "Items"; Layout = "~/Views/Shared/_Layout.cshtml"; }
@foreach(var item in @model.Items){ @Html.DisplayViewerFor(item) }
Upvotes: 1
Views: 4715
Reputation: 4841
You can use the Html.DisplayFor method to render a DisplayTemplate. One of the over loads for the method is to specify a template to use. You can modify your page code to read:
Page:
@model TestItemDisplayList
@{ ViewBag.Title = "Items"; Layout = "~/Views/Shared/_Layout.cshtml"; }
@Html.DisplayFor(model => Model,"TestItemDisplayList")
Display Template for TestItemDisplayList
@model TestItemDisplayList
@* You could limit this loop to the first 4 items *@
@foreach(var item in model.Items){ @Html.DisplayFor(item => item) }
Display Template for TestModel
@model TestModel
<div class="item-display">
<img src="@Url.Action("GetImage", "Image", new { id = Model.ItemName})" height="150"/>
<div class="editor-label">@Html.LabelFor(model => model.PropertyHere)</div>
</div>
I assume that your URL for the image used the default route of {controller}/{action}/{id} so I used the Url.Action and specified your ID.
You could also get away witout using a DisplayTemplate for "TestItemDisplayList" and moving that code in to your page but I wasn't clear if you wanted to add logic in that to limit the number of pages.
Upvotes: 4