0

I know that GridView can handle sorting and paging if I bind it to an ObjectDataSource that only needs to get the list of items in a SelectMethod. Since apparently all the ODS is doing is get the items I tried to bind the GridView directly to the collection of items.

I tried:

[aspx]

<asp:Button runat="server" OnClick="ItemsSearch" Text="Search" />
<asp:GridView runat="server" ID="ItemsGV"
    AllowPaging="true" AllowSorting="true" PageSize="4" />

[codebehind]

protected void ItemsSearch(object sender, EventArgs e)
{
    DataSet Items = new DataSet();
    Items.ReadXml(MapPath("Items.xml"));
    Session["items"] = Items;
    ItemsGV.DataSource = Session["items"];
    ItemsGV.DataBind();
}

The GridView is loaded with the data but if I click to sort or change page nothing happens.

Any ideea how to make this kind of binding work?

Răzvan Flavius Panda
  • 21,730
  • 17
  • 111
  • 169
  • I personally try to avoid this kind of implementation like the plague. It's a pain in the neck to handle the paging and sorting events. It's *much* easier to introduce a business tier and use ObjectDataSource. See this answer: http://stackoverflow.com/questions/6526843/populate-gridview-via-code-behind-or-markup-datasource/6526967#6526967 – Brett Sep 08 '11 at 14:13
  • @Brett: Yeah, i agree 100% :) it's much more code... and it does the same thing since i didn't customize the sorting at all. I just did this for training purposes. – Răzvan Flavius Panda Sep 08 '11 at 18:41

2 Answers2

0

You have to add Event Handlers for when people click on those buttons.

Imagine this: the first time you load the page, all of the data you want goes into the GridView. ASP.NET realizes that you can only show X items on your first page, so it loads that into the control and sends it down to the client. Now, the user wants to see page 2 items. When they make this request, it gets to the server, but the server has lost all reference to page 2. It doesn't know what it should show.

You need to handle the events and tell it what to show. This will mean rebinding to the data and showing page 2 information.

skaz
  • 21,962
  • 20
  • 69
  • 98
  • Not sure I understand. Why wouldn't it know what data to bind for page 2 if it has the DataSource referenced in a session variable? Sounds very complicated. :) – Răzvan Flavius Panda Sep 01 '11 at 14:06
  • When you post back to the server, are you rebinding the data to the data source? When it gets to the server, you need to rebind whatever is in the session back into the GridView. Otherwise the only thing that is in the GridView is the current page you were on. – skaz Sep 01 '11 at 14:14
0

After studying some tutorials I ended up with this solution:

[Default.aspx]

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="TemplateGridViewNoDataSourcePagingSorting.Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
  <title></title>
</head>
<body>
  <form id="form1" runat="server">
    <asp:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="true" />
    <asp:Button ID="Button1" runat="server" OnClick="ItemsSearch" Text="Search" />
    <asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
      <ContentTemplate>
        <asp:GridView runat="server" ID="ItemsGV" Visible="false" 
          AllowPaging="true" AllowSorting="true" PageSize="4"
          OnPageIndexChanging="ItemsGV_PageIndexChanging" OnSorting="ItemsGV_Sorting">
        </asp:GridView>
      </ContentTemplate>
    </asp:UpdatePanel>
  </form>
</body>
</html>

[Default.aspx.cs]

using System;
using System.Data;
using System.Threading;
using System.Web.UI.WebControls;

namespace TemplateGridViewNoDataSourcePagingSorting
{
    public partial class Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                Thread.Sleep(3000); // simulate long response time
                var ItemsDataSet = new DataSet();
                ItemsDataSet.ReadXml(MapPath("Items.xml"));
                Session["items"] = ItemsDataSet.Tables[0];
                ViewState["sortingOrder"] = string.Empty;
            }
        }

        protected void ItemsGV_PageIndexChanging(object sender, GridViewPageEventArgs e)
        {
            ItemsGV.PageIndex = e.NewPageIndex;
            ItemsGV.DataSource = Session["items"];
            ItemsGV.DataBind();
        }

        protected void ItemsSearch(object sender, EventArgs e)
        {
            ItemsGV.Visible = true;
            DataBindGrid("", "");
        }

        private void DataBindGrid(string sortExpr, string sortOrder)
        {
            // if sorting expression had changed
            // set sort order to ascending
            if (sortExpr != (string)ViewState["sortingExpression"])
            {
                sortOrder = "asc";
                ViewState["sortingOrder"] = "asc";
            }
            ViewState["sortingExpression"] = sortExpr;

            var dt = Session["items"] as DataTable;
            if (dt != null)
            {
                DataView dv = dt.DefaultView;
                if (sortExpr != string.Empty)
                    dv.Sort = sortExpr + " " + sortOrder;
                ItemsGV.DataSource = dv;
                ItemsGV.DataBind();
            }
            else
            {
                ItemsGV.DataSource = null;
                ItemsGV.DataBind();
            }
        }

        protected void ItemsGV_Sorting(object sender, GridViewSortEventArgs e)
        {
            DataBindGrid(e.SortExpression, sortingOrder);
        }

        public string sortingOrder
        {
            get
            {
                if (ViewState["sortingOrder"].ToString() == "desc")
                    ViewState["sortingOrder"] = "asc";
                else
                    ViewState["sortingOrder"] = "desc";
                return ViewState["sortingOrder"].ToString();
            }
            set
            {
                ViewState["sortingOrder"] = value;
            }
        }
    }
}

[Items.xml]

<?xml version="1.0" encoding="utf-8" ?>
<Items>
  <Item>
    <ItemName>Item01</ItemName>
    <ItemDescription>Item01 Description</ItemDescription>
    <ItemPrice>2.50</ItemPrice>
    <ItemInStock>Y</ItemInStock>
  </Item>
  <Item>
    <ItemName>Item02</ItemName>
    <ItemDescription>Item02 Description</ItemDescription>
    <ItemPrice>1.50</ItemPrice>
    <ItemInStock>Y</ItemInStock>
  </Item>
  <Item>
    <ItemName>Item03</ItemName>
    <ItemDescription>Item03 Description</ItemDescription>
    <ItemPrice>3.50</ItemPrice>
    <ItemInStock>N</ItemInStock>
  </Item>
  <Item>
    <ItemName>Item04</ItemName>
    <ItemDescription>Item04 Description</ItemDescription>
    <ItemPrice>5.00</ItemPrice>
    <ItemInStock>Y</ItemInStock>
  </Item>
  <Item>
    <ItemName>Item05</ItemName>
    <ItemDescription>Item05 Description</ItemDescription>
    <ItemPrice>5.50</ItemPrice>
    <ItemInStock>N</ItemInStock>
  </Item>
  <Item>
    <ItemName>Item06</ItemName>
    <ItemDescription>Item06 Description</ItemDescription>
    <ItemPrice>4.50</ItemPrice>
    <ItemInStock>N</ItemInStock>
  </Item>
  <Item>
    <ItemName>Item07</ItemName>
    <ItemDescription>Item07 Description</ItemDescription>
    <ItemPrice>1.50</ItemPrice>
    <ItemInStock>Y</ItemInStock>
  </Item>
  <Item>
    <ItemName>Item08</ItemName>
    <ItemDescription>Item08 Description</ItemDescription>
    <ItemPrice>7.50</ItemPrice>
    <ItemInStock>Y</ItemInStock>
  </Item>
  <Item>
    <ItemName>Item09</ItemName>
    <ItemDescription>Item09 Description</ItemDescription>
    <ItemPrice>0.50</ItemPrice>
    <ItemInStock>N</ItemInStock>
  </Item>
  <Item>
    <ItemName>Item10</ItemName>
    <ItemDescription>Item10 Description</ItemDescription>
    <ItemPrice>3.50</ItemPrice>
    <ItemInStock>Y</ItemInStock>
  </Item>
</Items>
Răzvan Flavius Panda
  • 21,730
  • 17
  • 111
  • 169