Wrox Programmer Forums
|
BOOK: ASP.NET 2.0 Instant Results ISBN: 978-0-471-74951-6
This is the forum to discuss the Wrox book ASP.NET 2.0 Instant Results by Imar Spaanjaars, Paul Wilton, Shawn Livermore; ISBN: 9780471749516
Welcome to the p2p.wrox.com Forums.

You are currently viewing the BOOK: ASP.NET 2.0 Instant Results ISBN: 978-0-471-74951-6 section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old August 14th, 2007, 11:11 AM
Authorized User
 
Join Date: Aug 2007
Posts: 30
Thanks: 0
Thanked 0 Times in 0 Posts
Send a message via MSN to Magi
Default A DataList supporting paging

These days I was trying to write a photo album .I want to show all the photos by a some columns and with paging.It is cool
that the DataList support Repeating Columns , but I want it to support paging so that it wound't span too long
if I have many photos in this collection and to also enhance the performance.However I found that the DataList
does't support paging and sorting. Then I turn to the GridView ,only to find that it does't support Repeating Columns.
So I begin to think how can I get a DataControl support both Paging and Repeating columns. And I turn to Imar for help,
he give me some greate suggests. And I begin try it out.

At this time , I finally create a user control that support both of the function.I post it here ,in the hope of helping someone
who want this function too.And also , I have some question to ask Imar and all of you all know the answer.

Here is my UserControl,I call it PagingDataList:
Code:
the ascx file:

<asp:DataList ID="dlstPhotos" runat="server"  >
    <ItemTemplate >
                <table cellpadding ="6" style="width:100%;">
                    <tr>
                        <td style="width: 1px;">
                            <asp:HyperLink ID="lnkPhotoImage" runat="server"  
                                NavigateUrl='<%# "~/ShowPhoto.aspx?ID="+ Eval("ID") %>' >
                            <asp:Image runat ="server" ID="imgPhoto" BorderWidth ="0px"
                                AlternateText ='<%# Eval("Title") %>' ImageUrl ='<%# Eval("ImageUrl") %>' />    
                            </asp:HyperLink></td>
                        <td >
                            <div class ="sectionsubtitle">
                                <asp:HyperLink runat="server" ID="lnkPhotoTitle" Text='<%# Eval("Title") %>'
                                     NavigateUrl ='<%# "~/ShowPhoto.aspx?ID="+Eval("ID") %>' />
                            </div>
                            <br />
                            <asp:Literal ID="lblDescription" runat ="Server" Text ='<%# Eval("Description") %>' />              
                        </td>
                    </tr>
                </table>
                <br />
                <br />
            </ItemTemplate>     

</asp:DataList>
<asp:LinkButton ID="lnkBtnPrePage" runat="server"  OnCommand="lnkBtnPrePage_Command" >Previous Page</asp:LinkButton>&nbsp;
&nbsp;<asp:LinkButton ID="lnkBtnNxtPage" runat="server" OnCommand="lnkBtnNxtPage_Command">Next Page</asp:LinkButton>
and the code behind file:
Code:
public partial class PagingDataList : UserControl
    {
        private int _catID = 0;
        public int CatID
        {
            get { return _catID; }
            set { _catID = value; }
        }

        public int RepeatColumns
        {
            get { return dlstPhotos.RepeatColumns; }
            set { dlstPhotos.RepeatColumns = value; }
        }

        private int _rowPerPage = 8;
        public int RowsPerPage
        {
            get { return _rowPerPage; }
            set { _rowPerPage = value; }
        }

        public RepeatDirection RepeatDirection
        {
            get { return dlstPhotos.RepeatDirection; }
            set { dlstPhotos.RepeatDirection = value; }
        }

        private int _pageSize;  //how many records in one page (= RowsPerPage * RepeatColumns)
        public int PageSize
        {
            get { return _pageSize; }
            set { _pageSize = value; }
        }


        private int _totalPageNum; //the total page number 
        public int TotalPageNum
        {
            get { return _totalPageNum; }
            set { _totalPageNum = value; }
        }



        private int _currPageIndex; 
        public int CurrPageIndex
        {
            get { return _currPageIndex; }
            set { _currPageIndex = value; }
        }

        private int _startRowIndex; // (= (_currPageIndex-1) * _pageSize +1 )

        protected override void LoadControlState(object savedState)
        {
            object[] ctlState = (object[])savedState;

            base.LoadControlState(ctlState[0]);
            CatID = (int)ctlState[1];
            PageSize = (int)ctlState[2];
            TotalPageNum = (int)ctlState[3];
            CurrPageIndex = (int)ctlState[4];

        }

        protected override object SaveControlState()
        {
            object[] ctlState = new object[5];

            ctlState[0] = base.SaveControlState();
            ctlState[1] = CatID;
            ctlState[2] = PageSize;
            ctlState[3] = TotalPageNum;
            ctlState[4] = CurrPageIndex;

            return ctlState;
        }

        protected void Page_Init(object sender, EventArgs e)
        {
            this.Page.RegisterRequiresControlState(this);

            if (!IsPostBack)
            {
                if (string.IsNullOrEmpty(this.Request.QueryString["CatID"]))
                    throw new ApplicationException("miss parameter in the querystring!");

                CatID = int.Parse(this.Request.QueryString["CatID"]);

                PageSize = RowsPerPage * RepeatColumns;
                TotalPageNum = (Photo.GetPhotoCount(CatID) % PageSize) == 0 ? 
                    (Photo.GetPhotoCount(CatID) / PageSize) : ((Photo.GetPhotoCount(CatID) / PageSize) + 1);

                CurrPageIndex = 1;

                if (TotalPageNum == 1)
                {
                    lnkBtnPrePage.Visible = false;
                    lnkBtnNxtPage.Visible = false;
                }
                lnkBtnPrePage.Enabled = false;

                _startRowIndex = (CurrPageIndex - 1) * PageSize + 1;

                List<Photo> photos = Photo.GetPhotos(CatID, _startRowIndex, PageSize);

                dlstPhotos.DataSource = photos;

                dlstPhotos.DataBind();
            }
        }


        protected void Page_Load(object sender, EventArgs e)
        {

        }


        protected void lnkBtnPrePage_Command(object sender, CommandEventArgs e)
        {
            CurrPageIndex = CurrPageIndex == 1 ? 1 : (CurrPageIndex - 1);
            if (CurrPageIndex == 1)
            {
                lnkBtnPrePage.Enabled = false;   
            } 
            lnkBtnNxtPage.Enabled = true;
            _startRowIndex = (CurrPageIndex - 1) * PageSize + 1;

            List<Photo> photos = Photo.GetPhotos(CatID, _startRowIndex, PageSize);

            dlstPhotos.DataSource = photos;

            dlstPhotos.DataBind();
        }

        protected void lnkBtnNxtPage_Command(object sender, CommandEventArgs e)
        {
            CurrPageIndex = CurrPageIndex == TotalPageNum ? TotalPageNum : (CurrPageIndex + 1);
            if (CurrPageIndex == TotalPageNum)
            {
                lnkBtnNxtPage.Enabled = false; 
            }
            lnkBtnPrePage.Enabled = true ;

            _startRowIndex = (CurrPageIndex - 1) * PageSize + 1;

            List<Photo> photos = Photo.GetPhotos(CatID, _startRowIndex, PageSize);

            dlstPhotos.DataSource = photos;

            dlstPhotos.DataBind();
        }
}
I have test this user control , and it works fine.

But still I have some questions.That is ,I original want to support random jump.that is the user can jump to any page
listed from 1 to the total number of page.But that will need dynamic creating LinkButton.And I have try this code:
Code:
for(int i=0;i<TotalPageNum;i++){
       LinkButton lnkBtnPager=new LinkButton();
       lnkBtnPager.Text=i.ToString();
       lnkBtnPager .Command +=new CommandEventHandler(lnkBtnPager_Command);
       lnkBtnPager.CommandName = "Paging";
       lnkBtnPager. CommandArgument=i.ToString();
}

Then in the lnkBtnPager_Command event handler:
        protected void lnkBtnPager_Command(object sender, CommandEventArgs e)
        {
            if (e.CommandName == "Paging")
            {
                _currPageIndex = Convert.ToInt32(e.CommandArgument);

                _startRowIndex = (_currPageIndex - 1) * _pageSize + 1;

                List<Photo> photos = Photo.GetPhotos(CatID, _startRowIndex, PageSize);

                dlstPhotos.DataSource = photos;

                dlstPhotos.DataBind();
            }
        }

But when I click the LinkButton,this event did not fire at all!

If I draw a LinkButton to design window ,and set its lnkBtn.OnCommand="lnkBtn_Command",
then it works well. I was rather confuse about that .
Hope some one can help me.
Thanks.

------------------------------------------------------------------------
We learn from the history that we do not learn from the history
__________________
------------------------------------------------------------------------
We learn from the history that we do not learn from the history
 
Old August 14th, 2007, 11:17 AM
Authorized User
 
Join Date: Aug 2007
Posts: 30
Thanks: 0
Thanked 0 Times in 0 Posts
Send a message via MSN to Magi
Default

Forgot to add my Customer paging code in the DataBase:
Code:
ALTER PROCEDURE dbo.rfa_Photos_GetPhotosByCategory
(
    @CategoryID        int,
    @PageIndex        int,
    @PageSize        int
)
AS
SET NOCOUNT ON

SELECT * FROM
(
    SELECT rfa_Photos.PhotoID,rfa_Photos.AddedDate,rfa_Photos.AddedBy,rfa_Photos.CategoryID,
    rfa_Photos.Title,rfa_Photos.ImageUrl,rfa_Photos.Description,rfa_Photos.CommentsEnabled,
    rfa_Photos.OnlyForMembers,rfa_Photos.IsCurrent,rfa_Photos.ViewCount,rfa_Photos.Votes,
    rfa_Photos.TotalRating,
    rfa_PhotoCategories.Title AS CategoryTitle,
    ROW_NUMBER() OVER ( ORDER BY rfa_Photos.AddedDate DESC ) AS RowNum
    FROM rfa_Photos INNER JOIN rfa_PhotoCategories
        ON rfa_Photos.CategoryID=rfa_PhotoCategories.CategoryID
    WHERE rfa_Photos.CategoryID=@CategoryID
)Photos
    WHERE Photos.RowNum BETWEEN (@PageIndex*@PageSize+1) AND ((@PageIndex+1)*@PageSize)
    ORDER BY Photos.AddedDate    DESC
It uses the SQL Server's ROW_NUMBER() for paging.


------------------------------------------------------------------------
We learn from the history that we do not learn from the history
 
Old August 14th, 2007, 11:42 AM
Authorized User
 
Join Date: Aug 2007
Posts: 30
Thanks: 0
Thanked 0 Times in 0 Posts
Send a message via MSN to Magi
Default

 
Quote:
quote:
Quote:
for(int i=0;i<TotalPageNum;i++){
       LinkButton lnkBtnPager=new LinkButton();
       lnkBtnPager.Text=i.ToString();
       lnkBtnPager .Command +=new CommandEventHandler(lnkBtnPager_Command);
       lnkBtnPager.CommandName = "Paging";
       lnkBtnPager. CommandArgument=i.ToString();
}
Sorry,missing one line :
this.Controls.Add(lnkBtnPager);

------------------------------------------------------------------------
We learn from the history that we do not learn from the history
 
Old August 14th, 2007, 12:22 PM
Imar's Avatar
Wrox Author
 
Join Date: Jun 2003
Posts: 17,089
Thanks: 80
Thanked 1,576 Times in 1,552 Posts
Default

Hi Magi,

To improve your chances on an answer, I think you're better off posting this in one of the general ASP.NET categories here at p2p.wrox.com as it isn't really related anymore to the ASP.NET book. That is, even people who didn't read (or write) the book should be able to help you out.
That said, make sure you recreate the controls on PostBack as well, not just on the initial load. Here's a quick example:
Code:
protected void Page_Load(object sender, EventArgs e)
{
    Button myButton;
    for (int i = 1; i <= 10; i++)
    {
        myButton = new Button();
        myButton.Text = "Button" + i.ToString();
        myButton.ID = "Button" + i.ToString();
        myButton.CommandArgument = i.ToString();
        myButton.Click += new System.EventHandler(this.Button1_Click);
        Panel1.Controls.Add(myButton);
    }
}

protected void Button1_Click(object sender, EventArgs e)
{
    Button myButton = (Button)sender;
    Label1.Text = "You clicked a button with command argument " + myButton.CommandArgument;
}
For the code to work, you need a Panel and a Label in your markup.

I also noticed you don't have a DataSource property on your control, tying it to the photo list. To improve reusability, you could a property called DataSource of type IEnumerable and use that to bind the list to. That allows you to reuse the control with other data sources.

Cheers,

Imar

---------------------------------------
Imar Spaanjaars
http://Imar.Spaanjaars.Com
Everyone is unique, except for me.
Author of ASP.NET 2.0 Instant Results and Beginning Dreamweaver MX / MX 2004
 
Old August 14th, 2007, 10:21 PM
Authorized User
 
Join Date: Aug 2007
Posts: 30
Thanks: 0
Thanked 0 Times in 0 Posts
Send a message via MSN to Magi
Default

Thanks Imar.It works now.
You are always my best teacher and brother.

Best regards

Magi

------------------------------------------------------------------------
We learn from the history that we do not learn from the history





Similar Threads
Thread Thread Starter Forum Replies Last Post
Datalist with paging venkatu2005 ASP.NET 1.0 and 1.1 Professional 1 July 17th, 2008 01:10 AM
paging datalist shanwaj ASP.NET 2.0 Basics 1 March 25th, 2008 12:03 AM
Datalist Paging webnathan ASP.NET 1.0 and 1.1 Basics 3 November 19th, 2007 11:11 AM
Datalist Paging nedo_786 ASP.NET 2.0 Professional 9 September 20th, 2007 04:32 AM
Datalist Paging in C# caitydev ASP.NET 2.0 Basics 0 March 29th, 2006 06:53 AM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.