When should I use Html.Displayfor in MVC
The DisplayFor
helper renders the corresponding display template for the given type. For example, you should use it with collection properties or if you wanted to somehow personalize this template. When used with a collection property, the corresponding template will automatically be rendered for each element of the collection.
Here's how it works:
@Html.DisplayFor(x => x.SomeProperty)
will render the default template for the given type. For example, if you have decorated your view model property with some formatting options, it will respect those options:
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}")]
public DateTime SomeProperty { get; set; }
In your view, when you use the DisplayFor
helper, it will render the property by taking into account this format whereas if you used simply @Model.SomeProperty
, it wouldn't respect this custom format.
but don't know when to use it?
Always use it when you want to display a value from your view model. Always use:
@Html.DisplayFor(x => x.SomeProperty)
instead of:
@Model.SomeProperty
What is the @Html.DisplayFor syntax for?
Html.DisplayFor()
will render the DisplayTemplate that matches the property's type.
If it can't find any, I suppose it invokes .ToString()
.
If you don't know about display templates, they're partial views that can be put in a DisplayTemplates
folder inside the view folder associated to a controller.
Example:
If you create a view named String.cshtml
inside the DisplayTemplates
folder of your views folder (e.g Home
, or Shared
) with the following code:
@model string
@if (string.IsNullOrEmpty(Model)) {
<strong>Null string</strong>
}
else {
@Model
}
Then @Html.DisplayFor(model => model.Title)
(assuming that Title
is a string) will use the template and display <strong>Null string</strong>
if the string is null, or empty.
What's the difference between using @Html.DisplayFor and just use @Model?
When you display a value using @Model.PartnerName
it places the plain value into your HTML without any surrounding markup. When you use @Html.DisplayFor(m => m.PartnerName)
you are invoking a DisplayTemplate to render the object.
These DisplayTemplates usually contain markup to make sure the value is displayed in a certain way. You can also create custom DisplayTemplates so you can always, for example, display your strings inside fancy boxes with borders and colors.
Check out this article for creating custom DisplayTemplates. http://www.codeguru.com/csharp/.net/net_asp/mvc/using-display-templates-and-editor-templates-in-asp.net-mvc.htm
Why does Html.DisplayFor work when not in an IF statement?
In the first example, Html.DisplayFor(...)
is prefixed by @
which tells the Razor view engine to render the result as HTML. In the second example, you're calling the same function, but doing nothing with the result. (Imagine what output you'd get if you said Math.Sqrt(4)
instead... nothing).
What you probably wanted was to force the Razor view engine to render your result by switching back into "HTML" context - perhaps like this:
{
<text>@Html.DisplayFor(...)</text>
}
<text>
is a special pseudo-tag recognized by the Razor view engine, and doesn't appear in the output HTML.
How to use @Html.DisplayFor instead of @Html.TextBoxFor
If you want values to be included in the form submission, they have to be bound to a form input. This is true of any form submission, not just ASP.NET MVC.
To include values that are not editable, you would use
@Html.HiddenFor(m => m.YourPropertyHere)
which generates a <input type="hidden" />
element for that property.
So, your example would look something like this:
@for (int counter = 0; counter <= Model.Employees.Count - 1; counter++)
{
<tr>
<td>
@Html.DisplayFor(m => m.Employees[counter].Name, null, new { @class = "form-control" })
@Html.HiddenFor(m => m.Employees[counter].Name)
</td>
</tr>
}
Applying CSS class to Html.DisplayFor (ASP.NET MVC)
Html.DisplayFor
does not support passing HTML attributes, including class/style. At it's most basic it merely renders the value, without any HTML, and with editor/display templates, it just renders whatever's in the template.
First, if you have EditorTemplates\Contacts.cshtml
, that will actually never be used by DisplayFor
. For DisplayFor
you need a separate template in Views\Shared\DisplayTemplates
. As its name implies EditorTemplates
is used by EditorFor
.
Either DisplayFor
or EditorFor
are basically the same as calling Html.Partial
. There's just some additional logic to deal with a specific model property and look by default in DisplayTemplates
/EditorTemplates
for the view. That said, you can pass additional data to them the same as you would with a partial, via ViewData
.
For example, if you were to call @Html.DisplayFor(m => m.FirstName, new { @class = "myclass" })
, then nothing would happen by default, but you would have a value of "myclass"
in ViewData["class"]
. You could then use that to modify a part of your template. For example:
Views\Shared\DisplayTemplates\Contacts.cshtml
<span @(ViewData["class"] != null ? "class='" + ViewData["class"] + "'" : string.Empty)>
@ViewData.TemplateInfo.FormattedModelValue
</span>
That checks to see if ViewData["class"]
has a value, and if so, adds a class attribute with that value to the span.
Can ASP.NET Core MVC simultaneously use @Html.DisplayFor and @Html.EditorFor?
I suggest you to use ViewModel.
In your situation,change List<Staff_To_Show>
into Staff_To_Show
.
In Staff_To_Show ,you can change the code like below to add another two model
public class Staff_To_Show
{
public List<Department> Departments { get; set; }
public List<Staff> Staffs { get; set; }
public StaffPermission StaffPermissions { get; set;}
}
In StaffPermission.cshtml:
@using Voyager.Models.Department
@model Staff_To_Show
@{
ViewBag.Title = "new";
}
<h2>new</h2>
<form method="post" action="/Home/StaffPermission">
@Html.AntiForgeryToken()
<div class="form-horizontal">
<select id="DepartmentNumber" name="DepartmentNumber"class="form-control">
<option value="">select</option>
@foreach (var item in Model.Departments)
{
<option value="@item.DepartmentNumber"> @Html.DisplayFor(modelItem => item.DepartmentNumber)</option>
}
</select>
<br/>
<select id="DepartmentNumber" name="DepartmentNumber"class="form-control">
<option value="">select</option>
@foreach (var item in Model.Staffs)
{
<option value="@item.StaffNumber"> @Html.DisplayFor(modelItem => item.StaffNumber)</option>
}
</select>
<hr />
<div class="form-group">
@Html.LabelFor(model => model.StaffPermissions, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.StaffPermissions, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.StaffPermissions, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="add" class="btn btn-success" />
</div>
</div>
</div>
</form>
Related Topics
How to Get Urls of Open Pages from Chrome and Firefox
Use of SQLparameter in SQL Like Clause Not Working
Hashset That Preserves Ordering
Explicitly Cast Generic Type Parameters to Any Interface
Convert Datetime for MySQL Using C#
Xmlwriter to Write to a String Instead of to a File
Waiting for Async/Await Inside a Task
How to Hide "Chrome Is Being Controlled by Automated Software" Infobar Within Chrome V76
ASP.NET 2012 Unobtrusive Validation with Jquery
Selecting a Textbox Item in a Listbox Does Not Change the Selected Item of the Listbox
Why Enums Require an Explicit Cast to Int Type
How to Deserialize a JSON Array into an Object Using JSON.Net