1

//Product

public class Product
{
    [Key]
    public int ID {get; set;}
    public string PK {get; set;}

    [Required(ErrorMessage="Category is required field.")]
    public int CategoryID { get; set; }

    [Required]
    public string Title {get; set;}

    public virtual ICollection<Pricing> Pricing { get; set; }
}

// Pricing

public class Pricing
{
    [Key]
    public int ID {get; set;}
    public int ProductID {get; set;}
    public decimal Price {get; set;}
    public int OrderQty {get; set;}
    public string PK { get; set; }
}

I have like above entities table, and I want to draw 5 textbox for the ICollection in update product page. But I have no idea, how should I do.

@model BrownieDAL.Entities.Product


<th> Price / Order Qty</th>
<td>
    @{int priceCnt = 0;}
    @foreach(var price in Model.Pricing){
        priceCnt++;
        @Html.TextBoxFor(model => price.Price)
        @Html.TextBoxFor(model => price.OrderQty)
        <br />
    }
    @if (priceCnt < 5)
    {
        // ??? 
        @Html.TextBoxFor(Model.Pricing => Model.Pricing.Price)
        priceCnt++;
    }
</td>

When I tried with '@Html.TextBoxFor(Model.Pricing => Model.Pricing.Price)', I got an error that say:

Error   1   'System.Collections.Generic.ICollection<PJ.Entities.Pricing>' does not contain a definition for 'Price' and no extension method 'Price' accepting a first argument of type 'System.Collections.Generic.ICollection<PJ.Entities.Pricing>' could be found (are you missing a using directive or an assembly reference?)   

Anybody know, how should I do for drawing textbox for the ICollection<> property?

Richard Dalton
  • 35,513
  • 6
  • 73
  • 91
Expert wanna be
  • 10,218
  • 26
  • 105
  • 158

1 Answers1

4

I'd recommend you using editor templates.

So simply initialize the Pricing collection in your controller and then complete it to 5 elements:

model.Pricing = ... go get the pricing collection from wherever you were getting it previously
int count = model.Pricing.Count();
if (count < 5)
{
    // we have less than 5 elements in the collection => let's complete it
    // with empty Pricing elements:
    var emptyItems = Enumerable.Range(1, 5 - count).Select(x => new Pricing());
    model.Pricing = model.Pricing.Concat(emptyItems).ToList();
}
return View(model);

and then inside your view simply:

@model BrownieDAL.Entities.Product
<table>
    <thead>
        <tr>
            <th>Price / Order Qty</th>
        </tr>
    </thead>
    <tbody>
        @Html.EditorFor(model => model.Pricing)
    </tbody>
</table>

and then simply define a custom editor template for the Pricing model (~/Views/Shared/EditorTemplates/Pricing.cshtml):

@model BrownieDAL.Entities.Pricing
<tr>
    <td>
        @Html.TextBoxFor(model => model.Price)
        @Html.TextBoxFor(model => model.OrderQty)
    </td>
</tr>

Simply simple. No need to worry about loops, no need to worry about indexes, the ASP.NET MVC framework will take care for everything. All you need to do is to simply follow the conventions that are built in.

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