views:

1658

answers:

4

Hi, I want to bind my Store class which has multiple Products to Html.Listbox. While in edit Store mode, I want Html.Listbox show all products where products of the Store are selected. I could not manage to bind store.Products to the listbox

My class structure;

public class Store
{
   public virtual int Id { get; set; }  
   public virtual string Name { get; set; }       
   public virtual IList<Product> Products { get; set; }
}
public class Product
{
   public virtual int Id { get; set; }  
   public virtual string Name { get; set; }       
}
public class StoreEditView
{
   public virtual int Id { get; set; }  
   public virtual string Name { get; set; }       
   public virtual IList<Product> Products { get; set; }
   public virtual MultiSelectList ProductList //populated from db, all products in the form of IList<Product>
}

My controller;

  public ViewResult Edit()
  {
    var editstore = new StoreEditView();
    editstore.Products = new List<Product> {new Product() {Id = 1, Name="Example"}};
    return View(editstore);
  }

My View;

 <%=Html.ListBox("Products", Model.ProductList)%>

In this case, I need product.Id=1 to be shown selected in the listbox. So far I couldn't do it. I tried,

<%=Html.ListBox("Product.Id", Model.ProductList)%>
<%=Html.ListBox("Products.Id", Model.ProductList)%>

just didn't work.

A: 

Based on your revision, maybe you need this in the code that populates your select list:

List<int> selectedValues = new List<int>();
foreach (Product p in store.Products)
    selectedValues.Add(p.Id);
var allProductList = new MultiSelectList(allProducts, "Id", "Title", selectedValues);

I'll leave my original answer below because it would solve the problem in a cleaner fashion.

The Html.ListBox() helper wants an IEnumerable passed to it so you need to convert your list to that in order to populate the list box.

You can accomplish this with an extension method like this:

using System.Collections.Generic;
using System.Web.Mvc;

namespace MvcMockups.Extensions
{
    public static class Extensions
    {
        public static SelectList ToSelectList<T>(this IEnumerable<T> items, string dataValueField, string dataTextField, string selectedValue)
        {
            return new SelectList(items, dataValueField, dataTextField, selectedValue);
        }
    }
}

Your view will need to know about your extension method:

<%@ Import Namespace="MvcMockups.Extensions"%>

Then your view would contain:

<%= Html.ListBox("Product", Model.Products.ToSelectList("Id", "Name", "1"))%>
grenade
Model.Productlist already populates the dropdown. My problem is, ListBox("Products") have no relation with Store.Products list.
dasmod
I'm not sure I understand the problem. How are you populating Model.ProductList? If it needs to match Model.Products and it doesn't, then I can only assume you need to change the routine that populates it.
grenade
ok, Model.ProductList is;public MultiSelectList ProductList { get; set; }I populate ProductList from database (all products in database)I have a StoreProduct table (store_id,product_id)If in editview for Store.Id=1, Store.Products List has many-to-many products.What i am trying to do here is, List all products into the Listbox and model bind this Listbox to Store.Products
dasmod
I rephrased the question.
dasmod
+2  A: 

Assuming that Store is your Model:

<%= Html.ListBox("ProductList",
        new SelectList(Model.Products, "Id", "Name", 1)) %>

The key is that the ListBox must be named differently than the SelectList! I don't know if this is a bug in ASP.NET MVC 1.0 (it looks so) but I also spent some time figuring it out before. The symptom is that no value is ever selected. I hope that this solves the issue for you and you can get rid of that StoreEditView class, which I think is unnecessary.

Pawel Krakowiak
StoreEditView.ProductList = new SelectList(_storeRepository.Stores.ToList(), "Id", "Name",1);did not work.
dasmod
Of course it doesn't work, as it expects a MultiSelectList now. You edited your question after I posted this answer. Let me change my answer then. :)
Pawel Krakowiak
+1  A: 

Thanks for your inputs. Both methods work, but when you submit the page - mvc can't model bind Product listbox to Store object by default.

I managed to solve this problem by using AutoMapper (A convention-based object-object mapper.)

dasmod
+1  A: 

Please refer the article which describes how to bind MVC listbox: http://www.altafkhatri.com/Technical/How%5Fto%5Fbind%5FIList%5Fwith%5FMVC%5FDropdownlist%5Fbox