1. 程式人生 > >ASP.NET MVC分頁庫(二)【使用示例】

ASP.NET MVC分頁庫(二)【使用示例】

昨天,我的人生朝一個方向前進;而今天卻朝著另一個方向。昨天,我相信我不可能做的事;今天,我卻做了。

專案結構:

這裡寫圖片描述

實體類:

    public class Product
    {
        public string Name { get; set; }
        public string Category { get; set; }
    }
 public class SearchModel
    {
        public SearchModel()
        {
            page = 1;
        }

        public
int? page { get; set; } }
 public class ViewByCategoriesViewModel
    {
        public IPagedList<Product> Products { get; set; }
        public string[] AvailableCategories { get; set; }
        public string[] Categories { get; set; }
    }
   public class ViewSourceViewModel
    {
        public
string RazorCode { get; set; } public string ControllerCode { get; set; } }

Controllers資料夾中控制器類

  [HandleError]
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        public ActionResult About
() { return View(); } }
  public class PagingController : Controller
    {
        private const int DefaultPageSize = 10;
        private readonly string[] allCategories = new string[3] {"Shoes", "Electronics", "Food"};
        private readonly IList<Product> allProducts = new List<Product>();

        public PagingController()
        {
            InitializeProducts();
        }

        private void InitializeProducts()
        {
            // 建立產品列表。 其中50%屬於鞋類,電子類佔25%,食品類佔25%。
            for (int i = 0; i < 527; i++)
            {
                var product = new Product();
                product.Name = "Product " + (i + 1);
                int categoryIndex = i%4;
                if (categoryIndex > 2)
                {
                    categoryIndex = categoryIndex - 3;
                }
                product.Category = allCategories[categoryIndex];
                allProducts.Add(product);
            }
        }

        public ActionResult Index(int? page)
        {
            int currentPageIndex = page.HasValue ? page.Value - 1 : 0;
            return View(allProducts.ToPagedList(currentPageIndex, DefaultPageSize));
        }

        public ActionResult CustomPageRouteValueKey(SearchModel search)
        {
            int currentPageIndex = search.page.HasValue ? search.page.Value - 1 : 0;
            return View(allProducts.ToPagedList(currentPageIndex, DefaultPageSize));
        }

        public ActionResult ViewByCategory(string categoryName, int? page)
        {
            categoryName = categoryName ?? allCategories[0];
            int currentPageIndex = page.HasValue ? page.Value - 1 : 0;

            IPagedList<Product> productsByCategory =
                allProducts.Where(p => p.Category.Equals(categoryName)).ToPagedList(currentPageIndex,
                    DefaultPageSize);
            ViewBag.CategoryName = new SelectList(allCategories, categoryName);
            ViewBag.CategoryDisplayName = categoryName;
            return View("ProductsByCategory", productsByCategory);
        }

        public ActionResult ViewByCategories(string[] categories, int? page)
        {
            var model = new ViewByCategoriesViewModel();
            model.Categories = categories ?? new string[0];
            int currentPageIndex = page.HasValue ? page.Value - 1 : 0;

            model.Products = allProducts.Where(p => model.Categories.Contains(p.Category))
                .ToPagedList(currentPageIndex, DefaultPageSize);
            model.AvailableCategories = allCategories;
            return View("ProductsByCategories", model);
        }

        public ActionResult IndexAjax()
        {
            int currentPageIndex = 0;
            IPagedList<Product> products = allProducts.ToPagedList(currentPageIndex, DefaultPageSize);
            return View(products);
        }

        public ActionResult AjaxPage(int? page)
        {
            ViewBag.Title = "Browse all products";
            int currentPageIndex = page.HasValue ? page.Value - 1 : 0;
            IPagedList<Product> products = allProducts.ToPagedList(currentPageIndex, DefaultPageSize);
            return PartialView("_ProductGrid", products);
        }

        public ActionResult Bootstrap(int? page)
        {
            int currentPageIndex = page.HasValue ? page.Value - 1 : 0;
            return View(allProducts.ToPagedList(currentPageIndex, DefaultPageSize));
        }

        public ActionResult Bootstrap3(int? page)
        {
            int currentPageIndex = page.HasValue ? page.Value - 1 : 0;
            return View(allProducts.ToPagedList(currentPageIndex, DefaultPageSize));
        }
    }

Home資料夾裡檢視:

Index.cshtml

@{
    ViewBag.Title = "ASP.NET MVC分頁示例 - 首頁";
}

@section featured {
    <section class="featured">
        <div class="content-wrapper">
            <hgroup class="title">
                <h2>@ViewBag.Title</h2>
            </hgroup>
            <p>

            </p>
        </div>
    </section>
}
<dl>
    <dt>@Html.ActionLink("簡單的分頁", "Index", "Paging")</dt>
    <dd>產品列表的分頁示例</dd>
</dl>
<dl>
    <dt>@Html.ActionLink("分頁過濾 #1", "ViewByCategory", "Paging")</dt>
    <dd>按類別過濾的產品列表</dd>
</dl>
<dl>
    <dt>@Html.ActionLink("分頁過濾 #2", "ViewByCategories", "Paging")</dt>
    <dd>
        由多個類別過濾的產品列表<br />
        此演示還使用強型別的viewmodel,它結合了結果和類別.
    </dd>
</dl>
<dl>
    <dt>@Html.ActionLink("一個區域的簡單分頁", "Index", "Paging", new {Area = "Area51"}, null)</dt>
    <dd>分頁還支援區域</dd>
</dl>
<dl>
    <dt>@Html.ActionLink("使用AJAX進行分頁", "IndexAjax", "Paging")</dt>
    <dd>分頁通過jquery支援unobtrusive AJAX。</dd>
</dl>
<dl>
    <dt>@Html.ActionLink("可選擇的分頁顯示模板", "Bootstrap", "Paging")</dt>
    <dd>分頁結合Twitter Bootstrap</dd>
</dl>
<dl>
    <dt>@Html.ActionLink("另一個可選的分頁顯示模板", "Bootstrap3", "Paging")</dt>
    <dd>
        分頁與Bootstrap 3組合。此示例還僅顯示頁碼,而不包含上一個和下一個連結。
    </dd>
</dl>

<dl>
    <dt>@Html.ActionLink("使用自定義頁面路由值鍵的分頁", "CustomPageRouteValueKey", "Paging")</dt>
    <dd>分頁支援在生成分頁連結時指定用於“page”的路由值鍵</dd>
</dl>

Paging資料夾裡檢視:

Bootstrap.cshtml

@using MvcPaging.Demo.Models
@model IPagedList<MvcPaging.Demo.Models.Product>
@{
    Layout = null;
    ViewBag.Title = "Twitter Bootstrap佈局的分頁";
}
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>@ViewBag.Title</title>
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <!-- Le styles -->
        <link href="@Url.Content("~/Content/Css/bootstrap.min.css")" rel="stylesheet">
        <style>
            body {
                padding-top: 60px; /* 60px to make the container go all the way to the bottom of the topbar */
            }
        </style>
        <!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
        <!--[if lt IE 9]>
            <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
        <![endif]-->

        <link href="@Url.Content("~/Content/SyntaxHighlighter/shCore.css")" rel="stylesheet" type="text/css" />
        <link href="@Url.Content("~/Content/SyntaxHighlighter/shThemeDefault.css")" rel="stylesheet" type="text/css" />
        <script type="text/javascript" src="@Url.Content("~/Scripts/SyntaxHighlighter/shCore.js")"></script>
        <script type="text/javascript" src="@Url.Content("~/Scripts/SyntaxHighlighter/shBrushCSharp.js")"></script>
        <script type="text/javascript" src="@Url.Content("~/Scripts/SyntaxHighlighter/shBrushXml.js")"></script>

    </head>
    <body>
        <div class="navbar navbar-fixed-top">
            <div class="navbar-inner">
                <div class="container">
                    <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
                        <span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span>
                    </a><a class="brand" href="#">ASP.NET MVC Paging sample</a>
                    <div class="nav-collapse">
                        <ul class="nav">
                            <li>@Html.ActionLink("首頁", "Index", "Home", new {area = String.Empty}, null)</li>
                            <li>@Html.ActionLink("About", "About", "Home", new {area = String.Empty}, null)</li>
                        </ul>
                    </div>
                    <!--/.nav-collapse -->
                </div>
            </div>
        </div>
        <div class="container">
            <h1>@ViewBag.Title</h1>

            <table class="table table-striped">
                <thead>
                    <tr>
                        <th>Product name</th>
                        <th>Category</th>
                    </tr>
                </thead>
                <tbody>
                    @foreach (Product product in Model)
                    {
                        <tr>
                            <td>@product.Name</td>
                            <td>@product.Category</td>
                        </tr>
                    }
                </tbody>
            </table>
            @Html.Pager(Model.PageSize, Model.PageNumber, Model.TotalItemCount).Options(o => o
                .DisplayTemplate("BootstrapPagination")
                .MaxNrOfPages(14)
                .AlwaysAddFirstPageNumber()
                .SetPreviousPageText("←")
                .SetNextPageText("→")
                )

            @{
                var sourceModel = new ViewSourceViewModel();
                sourceModel.RazorCode = @"
<!-- Bootstrap.cshtml view -->

@using MvcPaging.Demo.Models
@model IPagedList<Product>
@{
    Layout = null;
    ViewBag.Title = ""Pager with Twitter Bootstrap layout"";
}
<!DOCTYPE html>
<html lang=""en"">
<head>
    <meta charset=""utf-8"">
    <title>@ViewBag.Title</title>
    <meta name=""viewport"" content=""width=device-width, initial-scale=1.0"">
    <!-- Le styles -->
    <link href=""@Url.Content(""~/Content/Css/bootstrap.min.css"")"" rel=""stylesheet"">
    <style>
        body
        {
            padding-top: 60px; /* 60px to make the container go all the way to the bottom of the topbar */
        }
    </style>
    <!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
    <!--[if lt IE 9]>
      <script src=""http://html5shim.googlecode.com/svn/trunk/html5.js""></script>
    <![endif]-->

</head>
<body>
    <div class=""navbar navbar-fixed-top"">
        <div class=""navbar-inner"">
            <div class=""container"">
                <a class=""btn btn-navbar"" data-toggle=""collapse"" data-target="".nav-collapse""><span
                    class=""icon-bar""></span><span class=""icon-bar""></span><span class=""icon-bar""></span>
                </a><a class=""brand"" href=""#"">ASP.NET MVC Paging sample</a>
                <div class=""nav-collapse"">
                    <ul class=""nav"">
                        <li>@Html.ActionLink(""首頁"", ""Index"", ""Home"", new { area = String.Empty }, null)</li>
                        <li>@Html.ActionLink(""About"", ""About"", ""Home"", new { area = String.Empty }, null)</li>
                    </ul>
                </div>
                <!--/.nav-collapse -->
            </div>
        </div>
    </div>
    <div class=""container"">
        <h1>@ViewBag.Title</h1>

        <table class=""table table-striped"">
            <thead>
                <tr>
                    <th>Product name</th>
                    <th>Category</th>
                </tr>
            </thead>
            <tbody>
                @foreach (var product in Model)
                {
                    <tr>
                        <td>@product.Name</td>
                        <td>@product.Category</td>
                    </tr>
                }
            </tbody>
        </table>
        @Html.Pager(Model.PageSize, Model.PageNumber, Model.TotalItemCount).Options(o => o
            .DisplayTemplate(""BootstrapPagination"")
            .MaxNrOfPages(14)
            .AlwaysAddFirstPageNumber()
            .SetPreviousPageText(""←"")
            .SetNextPageText(""→"")
        )
    </div>
</body>

<!-- BootstrapPagination.cshtml DisplayTemplate -->

@model PaginationModel
<div class=""pagination"">
    <ul>
        @foreach (var link in Model.PaginationLinks)
        {
            @BuildLink(link)
        }
    </ul>
</div>

@helper BuildLink(PaginationLink link)
{
    var liBuilder = new TagBuilder(""li"");
    if (link.IsCurrent)
    {
        liBuilder.MergeAttribute(""class"", ""active"");
    }
    if (! link.Active)
    {
        liBuilder.MergeAttribute(""class"", ""disabled"");
    }

    var aBuilder = new TagBuilder(""a"");
    if (link.Url == null)
    {
        aBuilder.MergeAttribute(""href"", ""#"");
    }
    else
    {
        aBuilder.MergeAttribute(""href"", link.Url);
    }

    // Ajax support
    if (Model.AjaxOptions != null)
        {
            foreach (var ajaxOption in Model.AjaxOptions.ToUnobtrusiveHtmlAttributes())
            {
                aBuilder.MergeAttribute(ajaxOption.Key, ajaxOption.Value.ToString(), true);
            }
        }

    aBuilder.SetInnerText(link.DisplayText);

    liBuilder.InnerHtml = aBuilder.ToString();

    @Html.Raw(liBuilder.ToString())
}
";

                sourceModel.ControllerCode = @"
public ActionResult Bootstrap(int? page)
{
    int currentPageIndex = page.HasValue ? page.Value - 1 : 0;
    return View(this.allProducts.ToPagedList(currentPageIndex, DefaultPageSize));
}";
            }

            @Html.Partial("ViewSource", sourceModel)


        </div>
        <!-- /container -->

    </body>
</html>

Bootstrap3.cshtml

@using MvcPaging.Demo.Models
@model IPagedList<MvcPaging.Demo.Models.Product>
@{
    Layout = null;
    ViewBag.Title = "Twitter Bootstrap 3佈局的分頁";
}
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>@ViewBag.Title</title>
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <!-- Le styles -->
        <link href="@Url.Content("~/Content/Css/bootstrap3.min.css")" rel="stylesheet">
        <style>
            body {
                padding-top: 60px; /* 60px to make the container go all the way to the bottom of the topbar */
            }
        </style>

        <link href="@Url.Content("~/Content/SyntaxHighlighter/shCore.css")" rel="stylesheet" type="text/css" />
        <link href="@Url.Content("~/Content/SyntaxHighlighter/shThemeDefault.css")" rel="stylesheet" type="text/css" />
        <script type="text/javascript" src="@Url.Content("~/Scripts/SyntaxHighlighter/shCore.js")"></script>
        <script type="text/javascript" src="@Url.Content("~/Scripts/SyntaxHighlighter/shBrushCSharp.js")"></script>
        <script type="text/javascript" src="@Url.Content("~/Scripts/SyntaxHighlighter/shBrushXml.js")"></script>

    </head>
    <body>
        <a class="sr-only" href="#content">Skip navigation</a>

        <!-- Docs master nav -->
        <header class="navbar navbar-inverse navbar-fixed-top bs-docs-nav" role="banner">
            <div class="container">
                <div class="navbar-header">
                    <button class="navbar-toggle" type="button" data-toggle="collapse" data-target=".bs-navbar-collapse">
                        <span class="sr-only">Toggle navigation</span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                    </button>
                </div>
                <nav class="collapse navbar-collapse bs-navbar-collapse" role="navigation">
                    <ul class="nav navbar-nav">
                        <li>@Html.ActionLink("首頁", "Index", "Home", new {area = String.Empty}, null)</li>
                        <li>@Html.ActionLink("About", "About", "Home", new {area = String.Empty}, null)</li>
                    </ul>
                </nav>
            </div>
        </header>
        <div class="container">
            <h1>@ViewBag.Title</h1>

            <table class="table table-striped">
                <thead>
                    <tr>
                        <th>Product name</th>
                        <th>Category</th>
                    </tr>
                </thead>
                <tbody>
                    @foreach (Product product in Model)
                    {
                        <tr>
                            <td>@product.Name</td>
                            <td>@product.Category</td>
                        </tr>
                    }
                </tbody>
            </table>
            @Html.Pager(Model.PageSize, Model.PageNumber, Model.TotalItemCount).Options(o => o
                .DisplayTemplate("Bootstrap3Pagination")
                .MaxNrOfPages(14)
                .AlwaysAddFirstPageNumber()
                .HidePreviousAndNextPage()
                )

            @{
                var sourceModel = new ViewSourceViewModel();
                sourceModel.RazorCode = @"
<!-- Bootstrap3.cshtml view -->

@using MvcPaging.Demo.Models
@model IPagedList<Product>
@{
    Layout = null;
    ViewBag.Title = ""Pager with Bootstrap 3 layout"";
}
<!DOCTYPE html>
<html lang=""en"">
    <head>
        <meta charset=""utf-8"">
        <title>@ViewBag.Title</title>
        <meta name=""viewport"" content=""width=device-width, initial-scale=1.0"">
        <!-- Le styles -->
        <link href=""@Url.Content(""~/Content/Css/bootstrap3.min.css"")"" rel=""stylesheet"">
        <style>
            body {
                padding-top: 60px; /* 60px to make the container go all the way to the bottom of the topbar */
            }
        </style>
    </head>
<body>
    <a class=""sr-only"" href=""#content"">Skip navigation</a>

    <!-- Docs master nav -->
    <header class=""navbar navbar-inverse navbar-fixed-top bs-docs-nav"" role=""banner"">
        <div class=""container"">
            <div class=""navbar-header"">
                <button class=""navbar-toggle"" type=""button"" data-toggle=""collapse"" data-target="".bs-navbar-collapse"">
                    <span class=""sr-only"">Toggle navigation</span>
                    <span class=""icon-bar""></span>
                    <span class=""icon-bar""></span>
                    <span class=""icon-bar""></span>
                </button>
            </div>
            <nav class=""collapse navbar-collapse bs-navbar-collapse"" role=""navigation"">
                <ul class=""nav navbar-nav"">
                    <li>@Html.ActionLink(""首頁"", ""Index"", ""Home"", new { area = String.Empty }, null)</li>
                    <li>@Html.ActionLink(""About"", ""About"", ""Home"", new { area = String.Empty }, null)</li>s
                </ul>
            </nav>
        </div>
    </header>
    <div class=""container"">
        <h1>@ViewBag.Title</h1>

        <table class=""table table-striped"">
            <thead>
                <tr>
                    <th>Product name</th>
                    <th>Category</th>
                </tr>
            </thead>
            <tbody>
                @foreach (var product in Model)
                {
                    <tr>
                        <td>@product.Name</td>
                        <td>@product.Category</td>
                    </tr>
                }
            </tbody>
        </table>
        @Html.Pager(Model.PageSize, Model.PageNumber, Model.TotalItemCount).Options(o => o
            .DisplayTemplate(""Bootstrap3Pagination"")
            .MaxNrOfPages(14)
            .AlwaysAddFirstPageNumber()
            .HidePreviousAndNextPage()
        )
    </div>
</body>

<!-- Bootstrap3Pagination.cshtml DisplayTemplate -->

@model PaginationModel
<ul class=""pagination"">
    @foreach (var link in Model.PaginationLinks)
    {
        @BuildLink(link)
    }
</ul>

@helper BuildLink(PaginationLink link)
{
    var liBuilder = new TagBuilder(""li"");
    if (link.IsCurrent)
    {
        liBuilder.MergeAttribute(""class"", ""active"");
    }
    if (! link.Active)
    {
        liBuilder.MergeAttribute(""class"", ""disabled"");
    }

    var aBuilder = new TagBuilder(""a"");
    if (link.Url == null)
    {
        aBuilder.MergeAttribute(""href"", ""#"");
    }
    else
    {
        aBuilder.MergeAttribute(""href"", link.Url);
    }

    // Ajax support
    if (Model.AjaxOptions != null)
    {
        foreach (var ajaxOption in Model.AjaxOptions.ToUnobtrusiveHtmlAttributes())
        {
            aBuilder.MergeAttribute(ajaxOption.Key, ajaxOption.Value.ToString(), true);
        }
    }

    if (link.DisplayText == ""«"")
    {
        aBuilder.InnerHtml = ""&laquo;"";
    }
    else if (link.DisplayText == ""»"")
    {
        aBuilder.InnerHtml = ""&raquo;"";
    }
    else
    {
        aBuilder.SetInnerText(link.DisplayText);
    }
    liBuilder.InnerHtml = aBuilder.ToString();

    @Html.Raw(liBuilder.ToString())
}";

                sourceModel.ControllerCode = @"
public ActionResult Bootstrap(int? page)
{
    int currentPageIndex = page.HasValue ? page.Value - 1 : 0;
    return View(this.allProducts.ToPagedList(currentPageIndex, DefaultPageSize));
}";
            }

            @Html.Partial("ViewSource", sourceModel)


        </div>
        <!-- /container -->
    </body>
</html>

CustomPageRouteValueKey.cshtml

@using MvcPaging.Demo.Models
@model IPagedList<MvcPaging.Demo.Models.Product>
@{
    ViewBag.Title = "瀏覽所有產品(自定義頁面路由值鍵)";
}
<h2>@ViewBag.Title</h2>
<table class="grid">
    <thead>
        <tr>
            <th>Product name</th>
            <th>Category</