0
votes

I am trying to sort the items in a listview I have, the items are populated into the listview from the SelectMethod in the listviews ASPX declaration.

<asp:ListView ID="productList" runat="server" 
            DataKeyNames="ProductID" GroupItemCount="4"
            ItemType="StoreTest.Models.Product" SelectMethod="GetProducts" >

The method simply does a linq query and returns the query back to the Listview, this is the internal workings of the listview class and works fine. The issue is I have a drop down list with the different variables of each item, the user can use this DDL to sort the listview.

I placed a OnSelectedIndexChanged Method on the DDL which performs the same query as the original query, but then further orders it based on the required sorting mechanism. The issue is that I am unable to replace the existing items in the listview with this new query. My code for this is as follows:

        productList.Items.Clear();
        var _db = new StoreTest.Models.SiteContext();
        IQueryable<Product> query = _db.Products;
        switch(sortList.SelectedValue)
        {
            case "Price Asc":
                query = query.OrderBy(o=> o.UnitPrice);
                break;
            case "Price Des":
                query = query.OrderByDescending(o => o.UnitPrice);
                break;
            case "Name Asc":
                query = query.OrderBy(o => o.ProductName);
                break;
            case "Name Des":
                query = query.OrderByDescending(o => o.ProductName);
                break;
            case "Product ID Asc":
                query = query.OrderBy(o => o.ProductID);
                break;
            case "Product ID Des":
                query = query.OrderByDescending(o => o.ProductID);
                break;
        }
            productList.DataSource = query;
            productList.DataBind();

This gives me an error which is "DataSource or DataSourceID cannot be defined on 'productList' when it uses model binding", how could I go about fixing this. I tried to cast each individual Product in query to a ListViewItem but the types were incompatible and casting them to an array would not work.

public IQueryable<Product> GetProducts([QueryString("id")] int? categoryID)
    {
        var _db = new StoreTest.Models.SiteContext();
        IQueryable<Product> query = _db.Products;
        if (categoryID.HasValue && categoryID > 0)
        {
            query = query.Where(p => p.CategoryID == categoryID);
            Session["categoryid"] = categoryID;
        }
        return query;
    }

Thanks.

EDIT Solution: Bind both times pro grammatically, removed the bind in aspx and changed the initial bind to protected void Page_Load(object sender, EventArgs e) { IQueryable itemList = GetProducts(); productList.DataSource = itemList.ToList(); productList.DataBind(); }

    public IQueryable<Product> GetProducts()
    {
        int categoryID = -1;
        if(Request.QueryString["id"]!=null)
        {
            categoryID = Convert.ToInt32(Request.QueryString["id"]);
        }
        var _db = new StoreTest.Models.SiteContext();
        IQueryable<Product> query = _db.Products;
        if (categoryID!=-1 && categoryID > 0)
        {
            query = query.Where(p => p.CategoryID == categoryID);
            Session["categoryid"] = categoryID;
        }
        return query;
    }

Second binding worked fine as :

productList.DataSource = query.ToList();
        productList.DataBind();
1
Do you get the same error when you comment the ordering (switch statement)? - Peter
@Peter Yes I do, as either way I have already bound the data once in the ASPX code. - ObiEff
Can you share the code where you are doing the binding in the ASPX code? - Praveen Paulose
@PraveenPaulose The code for ASPX is at the top of my question, the code for the getProducts method is in the bottom. - ObiEff

1 Answers

0
votes

The issue arises due to the fact that you are trying both declarative binding (SelectMethod in the ASPX) as well as code binding (productList.DataSource = query). When you bind using the SelectMethod you are using a Declarative Binding (which in turn is your Model Binding - the Exception that you have shown indicates the same).

I would suggest you do the initial binding also through code, probably on your Page Load and remove the SelectMethod. This way both your methods would use code binding and that should work.