2010-08-15 7 views
3

J'ai une page sur mon site ASP.NET qui a un contrôle Repeater pour afficher les messages des membres du site.Pagination dans ASP.NET sans base de données

Actuellement, je stocke les données pour les publications dans un fichier XML, puis je le cache dans le site à l'intérieur des objets personnalisés.

J'ai donc:

public class MemberPost 
{ 
    public string Title { get; set; } 
    public string Text { get; set; } 
    public string Name { get; set; } 
    public DateTime Date { get; set; } 
    public List<string> Pictures { get; set; } 
} 

Et:

public class MemberPosts : List<MemberPost> 
{ 

} 

Je suis en mesure de définir la source de données du répéteur à une instance de MemberPosts et tout fonctionne comme prévu, mais je Je souhaite ajouter une pagination lorsque d'autres posts sont ajoutés. Tous les exemples que je trouve semblent impliquer d'avoir les données à pager dans une base de données - est-il possible de lier le répéteur ou un autre contrôle similaire à ma collection MemberPosts en mémoire et de l'implémenter pour moi? Je suis en train d'utiliser VS2010/.NET 3.5, mais je peux passer à 4.0 si nécessaire car je l'ai sur mon serveur.

Merci.

+1

+1 pour souligner que chaque exemple ASP .NET sur Internet lie directement l'interface utilisateur à la base de données. Je souhaiterais vraiment qu'ils cessent de promouvoir une telle pratique :) – David

+0

C'est une pratique courante pour les usages CQRS –

Répondre

4

http://msdn.microsoft.com/en-us/library/bb358985.aspx

http://msdn.microsoft.com/en-us/library/bb503062.aspx

ce sont les 2 méthodes IEnumerable dont vous avez besoin.

Vous avez obtenu

yourList.Skip(5).Take(5)

pour afficher la deuxième page de 5 articles.

+0

Je devrais ajouter tout le support puis pour afficher une nouvelle page etc. en utilisant des chaînes de requête et des numéros de page etc? Je veux juste laisser ASP.NET gérer toutes les paginations pour moi et simplement mettre mes données dans un format qui me permettra de les paginer. Je vais descendre cette route si j'ai besoin de ... – Michael

+0

ASP.NET n'a probablement aucun contrôle de pagination. ASP.NET MVC ne fait pas. Quand je l'étudiais, un des exemples de méthodes d'extension était une méthode qui produisait du HTML de pages, et tous les contrôleurs avaient une pagination implicite. – AlexanderMP

+0

Merci, a sorti mon doigt et a fait le code ci-dessous ... – Michael

3

utilisant l'idée de Skip et de prendre, je mets ensemble ce qui suit et il était assez facile et fonctionne un régal merci :-)

protected void Page_Load(object sender, EventArgs e) 
{ 
    IEnumerable<MemberPost> posts = from post in MemberPostCacher.Instance.Posts 
            orderby post.Date descending 
            select post; 

    memberPostsRepeater.DataSource = GetPageMemberPosts(posts); 
    memberPostsRepeater.DataBind(); 
} 

private IEnumerable<MemberPost> GetPageMemberPosts(IEnumerable<MemberPost> posts) 
{ 
    int totalNumberOfPosts = posts.Count(); 
    int pageSize = int.Parse(ConfigurationManager.AppSettings["MemberPostsPageSize"]); 
    int totalPages = GetTotalPages(totalNumberOfPosts, pageSize); 
    int currentPage = 1; 

    if (Request.QueryString["page"] != null) 
    { 
     int.TryParse(Request.QueryString["page"], out currentPage); 
     if (currentPage < 1 || currentPage > totalPages) 
     { 
      currentPage = 1; 
     } 
    } 

    SetIntroVisibility(currentPage); 
    SetLinks(currentPage, totalPages); 
    SetPageNumberText(currentPage, totalPages); 

    return posts.Skip((currentPage - 1) * pageSize).Take(pageSize); 
} 

private int GetTotalPages(int numberOfPosts, int pageSize) 
{ 
    return numberOfPosts % pageSize == 0 
       ? numberOfPosts/pageSize 
       : numberOfPosts/pageSize + 1; 
} 

private void SetIntroVisibility(int currentPage) 
{ 
    membersIntro.Visible = currentPage == 1; 
} 

private void SetLinks(int currentPage, int totalPages) 
{ 
    linkPrevious.Visible = currentPage != 1; 
    linkNext.Visible = currentPage != totalPages; 

    linkPrevious.NavigateUrl = FormatPageLink(currentPage - 1); 
    linkNext.NavigateUrl = FormatPageLink(currentPage + 1); 
} 

private string FormatPageLink(int pageNumber) 
{ 
    return string.Format("{0}{1}{2}", 
          Request.CurrentExecutionFilePath, 
          "?page=", 
          pageNumber); 
} 

private void SetPageNumberText(int currentPage, int totalPages) 
{ 
    lblNumRecords.Text = string.Format("&nbsp;&nbsp;Page {0} of {1}&nbsp;&nbsp;", currentPage, totalPages); 
    if(totalPages == 1) 
    { 
     lblNumRecords.Visible = false; 
    } 
} 
0

vous pouvez lier l'aide d'un ObjectDataSource et implémenter la pagination très facilement là-bas! De cette façon, vous pouvez réutiliser complètement la logique des contrôles liables ...

+0

Des liens s'il vous plaît sur la façon de le faire avec un répéteur et une collection d'objets en mémoire? – Michael

+0

répéteur est de bas niveau et n'a pas de support intégré pour la pagination, si vous voulez pagination out-of-the-box, vous devrez utiliser un contrôle de niveau plus élevé ... –

+0

Tels que? Quelque chose de léger idéalement. – Michael