MVC PagedList Dynamic Page/Page 大小由模型决定

MVC PagedList Dynamic Page/Page Size determined by model

我正在使用 PagedList.mvc 助手来处理我的应用程序的分页,在所有示例中我发现人们倾向于明确设置页面大小。我希望根据模型中的数据动态设置页面大小,也希望根据数据创建新页面。

Table

我有上图中规定的 table,我希望第 1 页是所有 MonthInt 为 1 的条目,第 2 页所有条目为 MonthInt 2 等等。但是我想要每个页面大小取决于每个月有多少条目。它目前根据第一页动态设置页面大小,并且仅限制第一页显示带有 MonthInt 1-3 的条目,之后它会到下一页,但不遵循相同的规则。任何 help/suggestions 都很好,

控制器代码:

// GET: Customers/Details/5
    public ActionResult Details(int? id, string sortOrder, string searchString, string currentFilter, int? page)
    {
        Customer customer = db.Customers.Find(id);

        var viewModel = new CustomerViewModel();


        if (id != null)
        {
            IEnumerable<Vehicle> vehicles = db.Vehicles.Where(c => c.CustomerId == customer.Id);
            List<Vehicle> vehiclesList = vehicles.OrderBy(m => m.MonthId).ThenBy(r => r.Register).ToList();

            if (searchString != null)
            {
                page = 1;
            }
            else
            {
                searchString = currentFilter;
            }

            ViewBag.CurrentFilter = searchString;
            int pageSize = vehicles.Count(m => m.MonthId <= 3);
            int pageNumber = (page ?? 1);

            if (!String.IsNullOrEmpty(searchString))
            {
                vehiclesList = vehicles.Where(r => r.Register.Contains(searchString.ToUpper())
                                                   || r.License.Contains(searchString.ToUpper())).ToList();
            }

            PagedList<Vehicle> pagedList = new PagedList<Vehicle>(vehiclesList, pageNumber,pageSize);

            viewModel = new CustomerViewModel()
            {
                Vehicles = pagedList,
                Customer = customer
            };
        }

        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }

        if (customer == null)
        {
            return HttpNotFound();
        }

        return View(viewModel);
    }

查看代码:

@model Application.ViewModels.CustomerViewModel
@using PagedList;
@using PagedList.Mvc
<link href="~/Content/PagedList.css" rel="stylesheet" type="text/css" />
@{
    ViewBag.Title = "Fleet Details";
 }

 <div>
      <h2>@Model.Customer.Name</h2>

@using (Html.BeginForm("Details", "Customers", FormMethod.Get))
{

    <div class="input-group">
        <div class="input-group-btn">
            <div class="btn-toolbar">
                @Html.TextBox("searchString", ViewBag.CurrentFilter as string, null, new {@class = "form-control", placeholder = "Find by Register/License", autofocus = "autofocus"})
                <input class="btn-warning btn" type="submit" value="search"/>
            </div>               
        </div>
    </div>
}
<hr />
@if (!Model.Vehicles.Any())
{
    <p>No Vehicles loaded</p>
    <br />
}
else
{
    <table class="table table-hover table-bordered">
        <tr>
            <th>@Html.DisplayName("Owner")</th>
            <th>@Html.DisplayName("License")</th>
            <th>@Html.DisplayName("Make")</th>
            <th>@Html.DisplayName("Register")</th>
            <th>@Html.DisplayName("MonthInt")</th>
            <th>@Html.DisplayName("Month")</th>
        </tr>
        @foreach (var item in Model.Vehicles)
        {
            <tr>
                <td>@Html.DisplayFor(modelItem => item.OwnerName)</td>
                <td>@Html.DisplayFor(modelItem => item.License)</td>
                <td>@Html.DisplayFor(modelItem => item.Make)</td>
                <td>@Html.DisplayFor(modelItem => item.Register)</td>
                <td>@Html.DisplayFor(modelItem => item.MonthId)</td>
                <td>@Html.DisplayFor(modelItem => item.MonthName)</td>
                <td>
                    <div class="btn-toolbar">
                        @Html.ActionLink("Edit", "Edit", "Vehicles", new { id = item.VehicleId }, new { @class = "btn btn-primary" })
                        @Html.ActionLink("Details", "Details", "Vehicles", new { id = item.VehicleId }, new { @class = "btn btn-default" })
                        @Html.ActionLink("Delete", "Delete", "Vehicles", new { id = item.VehicleId }, new { @class = "btn btn-danger" })
                    </div>
                </td>
            </tr>
        }
    </table>
}
<div class="btn-toolbar">
    @Html.ActionLink("Add Vehicle", "Create", "Vehicles", new { id = Model.Customer.Id }, new { @class = "btn-success btn" })
    @Html.ActionLink("Edit Customer Name", "Edit", new { id = Model.Customer.Id }, new { @class = "btn btn-primary" })
    @Html.ActionLink("Delete Customer", "Delete", new { id = Model.Customer.Id }, new { @class = "btn-danger btn" })
    @Html.ActionLink("Back to List", "Index", null, new { @class = "btn-default btn" })
</div>
<br/>
Page @(Model.Vehicles.PageCount < Model.Vehicles.PageNumber ? 0 : Model.Vehicles.PageNumber) of @Model.Vehicles.PageCount
@Html.PagedListPager(Model.Vehicles, page => Url.Action("Details", 
    new { page, pageSize = @Model.Vehicles.PageSize }))
Showing @Model.Vehicles.FirstItemOnPage to @Model.Vehicles.LastItemOnPage
of @Model.Vehicles.TotalItemCount Vehicles

示例:Example 1 Example 2

解决方案是在尝试其他事情时突然出现的。当前的解决方案允许每个月都在其自己的页面上。它可能不是最好的解决方案,但它确实有效。

为分组数据添加了自定义 class:

public class Group<T, TK>
{
    public TK Key;
    public IEnumerable<T> Values;
}

已更新 ViewModel:

public PagedList<Group<Vehicle, string>> VehiclesGroup { get; set; }

更新的详细信息控制器:

public ActionResult Details(int? id, string searchString, string currentFilter, int? page, int? item)
    {
        var customer = db.Customers.Find(id);

        if (customer == null)
        {
            return HttpNotFound();
        }

        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }

        var vehicles = from f in db.Vehicles
                       where f.CustomerId == customer.Id
                       select f;

        var vehiclesList = vehicles.OrderBy(m => m.MonthId).ThenBy(r => r.Register).ToList();

        var groupedVehicles = from v in vehiclesList
                              group v by v.MonthName
                              into g
                              select new Group<Vehicle, string> { Key = g.Key, Values = g };


        if (searchString != null)
        {
            page = 1;
        }
        else
        {
            searchString = currentFilter;
        }

        ViewBag.CurrentFilter = searchString;

        var pageSize = vehicles.Count(v => v.MonthId <= 0);
        if (pageSize == 0)
        {
            pageSize = 1;
        }
        var pageNumber = (page ?? 1);

        if (!string.IsNullOrEmpty(searchString))
        {
            vehicles = vehicles.Where(r => r.Register.Contains(searchString.ToUpper())
                                           || r.License.Contains(searchString.ToUpper())
                                           || r.Make.Contains(searchString.ToUpper())
                                           || r.OwnerName.Contains(searchString.ToUpper())
                                           || r.Vin.Contains(searchString.ToUpper())
                                           || r.MonthName.Contains(searchString.ToUpper()));
            vehiclesList = vehicles.ToList();
            groupedVehicles = from v in vehiclesList
                              group v by v.MonthName
                              into g
                              select new Group<Vehicle, string> { Key = g.Key, Values = g };
        }

        var pagedList = new PagedList<Group<Vehicle, string>>(groupedVehicles, pageNumber, pageSize);

        var viewModel = new CustomerVehicleViewModel()
        {
            VehiclesGroup = pagedList,
            Customer = customer
        };

        return View(viewModel);

    }

更新视图:

@model Application.ViewModels.CustomerVehicleViewModel
@using PagedList.Mvc
<link href="~/Content/PagedList.css" rel="stylesheet" type="text/css" />
@{
ViewBag.Title = "Fleet Details";

if (TempData["Error"] != null)
{
    ViewBag.Error = TempData["Error"];

}

}

    <h2>@Model.Customer.Name</h2>

    <div class="row">
        <div class="col-md-12">
            <div class="row">
                <div class="col-md-6" style="margin-bottom: 1%">
                    @using (Html.BeginForm("Details", "Customers", FormMethod.Get))
                    {
                        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
                        <div class="input-group">
                            <div class="input-group">
                                <span class="input-group-addon"><span class="glyphicon glyphicon-search"></span></span>
                                @Html.TextBox("searchString", ViewBag.CurrentFilter as string, null, new { @class = "form-control", placeholder = "Search", autofocus = "autofocus", style = "margin-right:1%" })
                            </div>
                            <div class="input-group-btn">
                                <input class="btn-warning btn" type="submit" value="search" />
                                @Html.ActionLink("Reset", null, null, null, new { @class = "btn btn-info", style = "margin-left: 5%" })
                            </div>
                        </div>
                    }
                </div>
                <div class="col-md-6">
                    <div class="btn-toolbar">
                        @Html.ActionLink("Add Vehicle", "Create", "Vehicles", new { id = Model.Customer.Id }, new { @class = "btn-success btn" })
                        @Html.ActionLink("Edit Customer", "Edit", new { id = Model.Customer.Id }, new { @class = "btn btn-primary" })
                        @Html.ActionLink("Delete Customer", "Delete", new { id = Model.Customer.Id }, new { @class = "btn-danger btn" })
                        @Html.ActionLink("Back to List", "Index", null, new { @class = "btn-default btn" })
                        @Html.ActionLink("BRN/ID", "ViewFile", "Customers", new { cid = Model.Customer.Id, id = Model.Customer.FileId }, new { @class = "btn-info btn", target = "_blank" })
                    </div>
                </div>
            </div>
        </div>
    </div>
    @Html.ValidationMessage("", $"{ViewBag.Error}", new { @class = "text-danger" })
    <hr />
    @if (!Model.VehiclesGroup.Any())
    {
        <p>No Vehicles loaded</p>
        <br />
    }
    else
    {
        <table class="table table-hover table-bordered" id="table">
            <thead>
                <tr>
                    <th>@Html.DisplayName("Owner")</th>
                    <th>@Html.DisplayName("License")</th>
                    <th>@Html.DisplayName("Make")</th>
                    <th>@Html.DisplayName("Register")</th>
                    <th>@Html.DisplayName("VIN")</th>
                    <th>@Html.DisplayName("Month")</th>
                    <th class="remove">
                        <button id="btnPrint" class="btn btn-warning"><span class="glyphicon glyphicon-print" aria-hidden="true"></span> Print Table</button>
                    </th>
                </tr>
            </thead>
            <tbody>
                @foreach (var item in Model.VehiclesGroup)
                {
                    foreach (var i in item.Values)
                    {
                        <tr>
                            <td>@Html.DisplayFor(modelItem => i.OwnerName)</td>
                            <td>@Html.DisplayFor(modelItem => i.License)</td>
                            <td>@Html.DisplayFor(modelItem => i.Make)</td>
                            <td>@Html.DisplayFor(modelItem => i.Register)</td>
                            <td>@Html.DisplayFor(modelItem => i.Vin)</td>
                            <td>@Html.DisplayFor(modelItem => i.MonthName)</td>
                            <td class="remove">
                                <div class="btn-toolbar">
                                    @Html.ActionLink("Edit", "Edit", "Vehicles", new { id = i.VehicleId }, new { @class = "btn btn-primary" })
                                    @Html.ActionLink("Details", "Details", "Vehicles", new { id = i.VehicleId }, new { @class = "btn btn-default" })
                                    @Html.ActionLink("Delete", "Delete", "Vehicles", new { id = i.VehicleId }, new { @class = "btn btn-danger" })
                                    @Html.ActionLink("Scan", "ViewFile", "Vehicles", new { cId = i.CustomerId, id = i.VehicleId }, new { @class = "btn btn-info", target = "_blank" })
                                </div>
                            </td>
                        </tr>

                    }
                    <tr>
                        <td colspan="3">@item.Key</td>
                        <td colspan="3"></td>
                    </tr>

                }
            </tbody>
        </table>
    }
    <br />
        Page @(Model.VehiclesGroup.PageCount < Model.VehiclesGroup.PageNumber ? 0 : Model.VehiclesGroup.PageNumber) of @Model.VehiclesGroup.PageCount

        @Html.PagedListPager(Model.VehiclesGroup, page => Url.Action("Details",
                                                new
                                                {
                                                    page,
                                                    currentFilter = ViewBag.CurrentFilter,
                                                    pageSize = @Model.VehiclesGroup.PageSize
                                                }))

       Total of @Model.VehiclesGroup.TotalItemCount Pages

月份的更新显示 January/page 1 Page 1

月份更新显示 February/page 2 Page 2

第 3 页的更新显示 Page 3

希望对大家有所帮助,或者如果有人有更好的想法请分享!