14
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ASP.NET Core MVCでページング機能を実装する

Last updated at Posted at 2019-09-10

ページング機能の実装方法を探していたら、一からコードを書いて実装する方法と、パッケージを利用して実装する方法があったので紹介します。

環境

  • ASP.NET Core2.2
  • ASP.NET Core MVC
  • Bootstrap4
  • Visual Studio 2019
  • X.PagedList.Mvc.Core7.9.0(NuGetパッケージ)

店舗管理機能で、登録店舗の一覧ページにページング機能を実装することを想定しています。

1からコードを書いて実装する

参考サイト

Students/Index にページングを追加する(Microsoft)

1.ページング用のクラスを新規作成

PaginatedList.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;

namespace ContosoUniversity
{
    public class PaginatedList<T> : List<T>
    {
        public int PageIndex { get; private set; }
        public int TotalPages { get; private set; }

        public PaginatedList(List<T> items, int count, int pageIndex, int pageSize)
        {
            PageIndex = pageIndex;
            TotalPages = (int)Math.Ceiling(count / (double)pageSize);

            this.AddRange(items);
        }

        public bool HasPreviousPage
        {
            get
            {
                return (PageIndex > 1);
            }
        }

        public bool HasNextPage
        {
            get
            {
                return (PageIndex < TotalPages);
            }
        }

        public static async Task<PaginatedList<T>> CreateAsync(IQueryable<T> source, int pageIndex, int pageSize)
        {
            var count = await source.CountAsync();
            var items = await source.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToListAsync();
            return new PaginatedList<T>(items, count, pageIndex, pageSize);
        }
    }
}

2.Indexアクションメソッドを変更

Controllers/ShopController.cs
        public async Task<IActionResult> Index(int? pageNumber)
        {
            // 「編集」「詳細」ページから戻ってくる際のページ番号保持
            ViewData["pageNumber"] = pageNumber ?? 1;

            // ソートデータ取得用のクエリ発行
            var shops = _context.Shop.Select(m => m);

            // 1ページ内の項目レコード表示数
            int pageSize = 5;

            return View(await PaginatedList<Shop>.CreateAsync(shops.AsNoTracking(), pageNumber ?? 1, pageSize));
        }

3.ページングリンクの追加

先頭のmodelステートメントでPaginatedList< T >を使用する

View/Shop/Index.cshtml
	@model PaginatedList<Models.Shop>

	----------------------
		一覧表示処理(tableとか)
	----------------------



//ページャーを表示したい箇所に下記を挿入
	@{
		var prevDisabled = !Model.HasPreviousPage ? "disabled" : "";
		var nextDisabled = !Model.HasNextPage ? "disabled" : "";
		var active = "";
	} 

	<nav aria-label="">
		<ul class="pagination">
			<li class="page-item @prevDisabled">
				<a asp-action="Index"  asp-route-pageNumber="@(Model.PageNumber - 1)" class="page-link">Previous</a>
			</li>
			@for (int i = 1; i < Model.TotalPages + 1; i++)
			{
				active = Model.PageNumber == i ? "active" : "";
				<li class="page-item @active">
					<a asp-action="Index"  asp-route-pageNumber="@i" class="page-link ">@i</a>
				</li>
			}
			<li class="page-item @nextDisabled">
				<a asp-action="Index"  asp-route-pageNumber="@(Model.PageNumber + 1)" class="page-link">Next</a>
			</li>
		</ul>
	</nav>
        

表示内容

pager1.PNG

X.PagedList.Mvc.Coreパッケージを利用する

参考サイト

X.PagedList

1.パッケージの追加

追加方法は割愛。画像は下記のやつ。
キャプチャ.PNG
バージョンは7.9.0

2.Indexアクションメソッドを変更

Controllers/ShopController.cs
        public async Task<IActionResult> Index(int? page)
        {
            var pageNumber = page ?? 1;
            IQueryable<Shop> query = _context.Shop;
            return View(query.ToPagedList(pageNumber, 3));
        }

3.ページングリンクの追加

先頭のmodelステートメントでPaginatedList< T >を使用する

View/Shop/Index.cshtml
@using X.PagedList.Mvc.Core;
@using X.PagedList;

	----------------------
		一覧表示処理(tableとか)
	----------------------

//ページャーを表示したい箇所に下記を挿入
@Html.PagedListPager(
    (IPagedList)Model,
    page => Url.Action("Index", new { page }),
    new X.PagedList.Mvc.Common.PagedListRenderOptionsBase    //Bootstrap4を利用する場合はオプションを利用してタグにクラスを追加しないとデザインが反映されない
    {
        LiElementClasses = new string[] { "page-item" },
        PageClasses = new string[] { "page-link" },
        MaximumPageNumbersToDisplay = 5,                                                 //表示するページャーの数
        DisplayLinkToNextPage = X.PagedList.Mvc.Common.PagedListDisplayMode.Never,       //「次へ」の非表示設定
        DisplayLinkToPreviousPage = X.PagedList.Mvc.Common.PagedListDisplayMode.Never,   //「前へ」の非表示設定
        DisplayLinkToFirstPage = X.PagedList.Mvc.Common.PagedListDisplayMode.Never,      //「最初へ」の非表示設定
        DisplayLinkToLastPage = X.PagedList.Mvc.Common.PagedListDisplayMode.Never,       //「最後へ」の表示設定
    }
)
        

表示内容

pager2.PNG

オプションに関して

参考サイトのGitHubの「README.md」に記載してある。

使ってみて

大体「X.PagedList.Mvc.Core」使っておけばOKな気がする。
表示方法のオプションとか、独自でタグにクラスもつけれるので、困ることはあんまりないかなと。(Bootstrap3とBootstrap4でタグのクラスのつけ方が違うので、そこだけ注意。)
ただ、Microsoftのドキュメント読むのも面白いし勉強になるので、MVC勉強中の人はドキュメント読むのもお勧めします。

参考サイト

X.PagedList
Students/Index にページングを追加する(Miscrosoft)
ページ送り(Pagination)

14
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?