Question

I have an array of double in my View Model and I'd like to apply a data format string like shown below:

class MyVM 
{
    [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:F2}")]
    public double Currents[] { get; set; }
}

In my View, I am using EditorFor on the array like shown below, which is properly working except its not applying the data format string.

@Html.EditorFor(model => model.Currents)

I learned that I can use custom templates, but was wondering is there is a simpler way than creating a custom template. If custom template is the only solution, what is the simplest custom template that should take care of the formatting? I tried creating one but was not successful in applying the data format string properly.

I can create a CurrentsTemplate.cshtml in the ~Views\Shared folder with the below content

@model double[]

@foreach (double x in Model) {
<div class="editor-field">
    @Html.TextBoxFor(m=>x, "{0:F2}")
</div>
}

and use that by calling @Html.EditorFor(m => m.Currents,"CurrentsTemplate"), it will work but the form data is not persisting after its POSTed. Guess I need hidden fields in the for loop along with the TextBox.

Was it helpful?

Solution 2

The solution is to use the actual member name along with the desired data format string in the @Html.TextBoxFor helper. Since the data is an IEnumerable simply place it in a for loop. The generated HTML will contain appropriate name field that matches the View Model's member name which is important for data persistence across POST backs. No hidden HTML form fields needed.

@for (int k = 0; k < Model.Currents.Count(); k++ ) {
    @Html.TextBoxFor(model => model.Currents[k], "{0:F2}")                                                           
}

The above will work with proper data formatting. It generates

 <input name="Currents[0]" id="Currents_0_" type="text" data-val-number="The field Double must be a number." data-val="true" value="0.8"/>

and works with proper persistence across POST backs.

The following three cases don't work:

case 1:

@foreach (double x in Model) {
    @Html.TextBoxFor(m=>x, "{0:F2}")
}
  • Does not persist across POST backs as it generates HTML with name="x".
  • This one applies proper data formatting though.

case 2:

@Html.EditorFor(m => m.Currents)
  • Does not data format as needed
  • But persists across POST backs since actual view data member name is used in the generated HTML.

case 3:

@Html.EditorFor(m => m.Currents, "TemplateName")

Same as case 1.

OTHER TIPS

Create a custom template that will format your double as needed. That way when MVC sees double it will use your template rather than it's internal logic for displaying it.

For example, create a EditorTemplates folder in your Views\Shared folder, then create strongly partial view of type double named double.cshtml.

This piece of code

@model double

@Html.TextBoxFor(m => m, "{0:F2}")

Hope this helps.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top