I think it might be easier to explain by showing some code and explaining as I go along:
Create Product ViewModel:
[UIHint("Prices")]
public IList<CreatePricesViewModel> Prices { get; set; }
With this, I want the ability to use an ajax call to add another set of prices for a different currency to the product.
Create Prices ViewModel:
[DataType(DataType.Currency)]
[DisplayName("Wholesale Price: ")]
public decimal Wholesale { get; set; }
[DataType(DataType.Currency)]
[Required]
[DisplayName("Retail Price: ")]
public decimal Retail { get; set; }
[DataType(DataType.Currency)]
[DisplayName("Discounted Price: ")]
public decimal Discount { get; set; }
In my controller I create a single CreatePricesViewModel and add it to the CreateProductViewModels list of CreatePricesViewModel’s so there is at least one available instance to render in the view.
Create Product View:
@model CumbriaMD.Infrastructure.ViewModels.ProductViewModels.CreateProductViewModel
......
<div class="editor-field">
@Html.EditorFor(model => model.Prices)
@Html.ValidationMessageFor(model => model.Prices)
</div>
Prices EditorFor Templates:
This is where I’m struggling really. When I strongly-type to the CreatePricesViewModel I get a complaint because I’m passing in an IEnumerable of type CreatePricesViewModel instead of a single instance – but when I use a foreach loop my id and names are messed up so the model-binding fails? Can using @inherits here help?
@model CumbriaMD.Infrastructure.ViewModels.PriceViewModels.CreatePricesViewModel
<div class="editor-label">
@Html.LabelFor(model => model.Wholesale)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Wholesale)
@Html.ValidationMessageFor(model => model.Wholesale)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Retail)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Retail)
@Html.ValidationMessageFor(model => model.Retail)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Discount)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Discount)
@Html.ValidationMessageFor(model => model.Discount)
</div>
No,
@inheritscannot solve your headaches.When using
UIHint, the entire enumerable is passed, so you need to make your template strongly typed to the list:and then define
_SomePrice.cshtmlpartial:This is not necessary when you don’t use the UIHint attribute => the editor template is automatically invoked for each element of the Prices collection. It sucks but it’s how it is.