我正在ASP.NET MVC视图上实现分页,我想从视图中调用控制器中的方法。
视图中的代码:
<a href="<%= Url.Action("Search",
new { page = NextPage(Request["exactPage"])).ToString()}) %>">
控制器方法:
public string NextPage(string currentPage)
{
return (int.Parse(currentPage) + 1).ToString();
}
如何从视图中调用NextPage方法?
谢谢!
答案 0 :(得分:2)
如果您知道当前页面的编号,您是否只能渲染上一页和下一页链接页面值= 当前页面加/减1的链接?您实际上不需要视图来询问控制器下一个/上一个页码是什么。该信息可以基于当前页面索引的值从视图派生。
编辑:我建议控制器向视图传递一个额外的值,表示可用的总页数。然后,视图可以将此值与当前页码进行比较,以确定是否显示 next 链接。
答案 1 :(得分:2)
我忘了它来自哪里。也许有人可以在这里发布链接作为评论。
我认为这是完整的代码。
我把它作为一个项目;
MvcPaging;
<强> IPagedList 强>
using System.Collections.Generic;
namespace MvcPaging
{
public interface IPagedList<T> : IList<T>
{
int PageCount { get; }
int TotalItemCount { get; }
int PageIndex { get; }
int PageNumber { get; }
int PageSize { get; }
bool HasPreviousPage { get; }
bool HasNextPage { get; }
bool IsFirstPage { get; }
bool IsLastPage { get; }
}
}
<强> PagedList 强>
using System;
using System.Collections.Generic;
using System.Linq;
using MvcPaging;
namespace MvcPaging
{
public class PagedList<T> : List<T>, IPagedList<T>
{
public PagedList(IEnumerable<T> source, int index, int pageSize)
: this(source, index, pageSize, null)
{
}
public PagedList(IEnumerable<T> source, int index, int pageSize, int? totalCount)
{
Initialize(source.AsQueryable(), index, pageSize, totalCount);
}
public PagedList(IQueryable<T> source, int index, int pageSize)
: this(source, index, pageSize, null)
{
}
public PagedList(IQueryable<T> source, int index, int pageSize, int? totalCount)
{
Initialize(source, index, pageSize, totalCount);
}
#region IPagedList Members
public int PageCount { get; private set; }
public int TotalItemCount { get; private set; }
public int PageIndex { get; private set; }
public int PageNumber { get { return PageIndex + 1; } }
public int PageSize { get; private set; }
public bool HasPreviousPage { get; private set; }
public bool HasNextPage { get; private set; }
public bool IsFirstPage { get; private set; }
public bool IsLastPage { get; private set; }
#endregion
protected void Initialize(IQueryable<T> source, int index, int pageSize, int? totalCount)
{
//### argument checking
if (index < 0)
{
throw new ArgumentOutOfRangeException("PageIndex cannot be below 0.");
}
if (pageSize < 1)
{
throw new ArgumentOutOfRangeException("PageSize cannot be less than 1.");
}
//### set source to blank list if source is null to prevent exceptions
if (source == null)
{
source = new List<T>().AsQueryable();
}
//### set properties
if (!totalCount.HasValue)
{
TotalItemCount = source.Count();
}
PageSize = pageSize;
PageIndex = index;
if (TotalItemCount > 0)
{
PageCount = (int)Math.Ceiling(TotalItemCount / (double)PageSize);
}
else
{
PageCount = 0;
}
HasPreviousPage = (PageIndex > 0);
HasNextPage = (PageIndex < (PageCount - 1));
IsFirstPage = (PageIndex <= 0);
IsLastPage = (PageIndex >= (PageCount - 1));
//### add items to internal list
if (TotalItemCount > 0)
{
AddRange(source.Skip((index) * pageSize).Take(pageSize).ToList());
}
}
}
}
<强>寻呼机强>
using System;
using System.Text;
using System.Web.Mvc;
using System.Web.Routing;
namespace MvcPaging
{
public class Pager
{
private ViewContext viewContext;
private readonly int pageSize;
private readonly int currentPage;
private readonly int totalItemCount;
private readonly RouteValueDictionary linkWithoutPageValuesDictionary;
public Pager(ViewContext viewContext, int pageSize, int currentPage, int totalItemCount, RouteValueDictionary valuesDictionary)
{
this.viewContext = viewContext;
this.pageSize = pageSize;
this.currentPage = currentPage;
this.totalItemCount = totalItemCount;
this.linkWithoutPageValuesDictionary = valuesDictionary;
}
public string RenderHtml()
{
int pageCount = (int)Math.Ceiling(this.totalItemCount / (double)this.pageSize);
int nrOfPagesToDisplay = 10;
var sb = new StringBuilder();
// Previous
if (this.currentPage > 1)
{
sb.Append(GeneratePageLink("Previous", this.currentPage - 1));
}
else
{
sb.Append("<span class=\"disabled\">Previous</span>");
}
int start = 1;
int end = pageCount;
if (pageCount > nrOfPagesToDisplay)
{
int middle = (int)Math.Ceiling(nrOfPagesToDisplay / 2d) - 1;
int below = (this.currentPage - middle);
int above = (this.currentPage + middle);
if (below < 4)
{
above = nrOfPagesToDisplay;
below = 1;
}
else if (above > (pageCount - 4))
{
above = pageCount;
below = (pageCount - nrOfPagesToDisplay);
}
start = below;
end = above;
}
if (start > 3)
{
sb.Append(GeneratePageLink("1", 1));
sb.Append(GeneratePageLink("2", 2));
sb.Append("...");
}
for (int i = start; i <= end; i++)
{
if (i == this.currentPage)
{
sb.AppendFormat("<span class=\"current\">{0}</span>", i);
}
else
{
sb.Append(GeneratePageLink(i.ToString(), i));
}
}
if (end < (pageCount - 3))
{
sb.Append("...");
sb.Append(GeneratePageLink((pageCount - 1).ToString(), pageCount - 1));
sb.Append(GeneratePageLink(pageCount.ToString(), pageCount));
}
// Next
if (this.currentPage < pageCount)
{
sb.Append(GeneratePageLink("Next", (this.currentPage + 1)));
}
else
{
sb.Append("<span class=\"disabled\">Next</span>");
}
return sb.ToString();
}
private string GeneratePageLink(string linkText, int pageNumber)
{
var pageLinkValueDictionary = new RouteValueDictionary(this.linkWithoutPageValuesDictionary);
pageLinkValueDictionary.Add("page", pageNumber);
//var virtualPathData = this.viewContext.RouteData.Route.GetVirtualPath(this.viewContext, pageLinkValueDictionary);
var virtualPathData = RouteTable.Routes.GetVirtualPath(this.viewContext.RequestContext, pageLinkValueDictionary);
if (virtualPathData != null)
{
string linkFormat = "<a href=\"{0}\">{1}</a>";
return String.Format(linkFormat, virtualPathData.VirtualPath, linkText);
}
else
{
return null;
}
}
}
}
<强> PagingExtensions 强>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using System.Web.Routing;
using MvcPaging;
namespace MvcPaging
{
public static class PagingExtensions
{
public static string Pager(this HtmlHelper htmlHelper, int pageSize, int currentPage, int totalItemCount)
{
return Pager(htmlHelper, pageSize, currentPage, totalItemCount, null, null);
}
public static string Pager(this HtmlHelper htmlHelper, int pageSize, int currentPage, int totalItemCount, string actionName)
{
return Pager(htmlHelper, pageSize, currentPage, totalItemCount, actionName, null);
}
public static string Pager(this HtmlHelper htmlHelper, int pageSize, int currentPage, int totalItemCount, object values)
{
return Pager(htmlHelper, pageSize, currentPage, totalItemCount, null, new RouteValueDictionary(values));
}
public static string Pager(this HtmlHelper htmlHelper, int pageSize, int currentPage, int totalItemCount, string actionName, object values)
{
return Pager(htmlHelper, pageSize, currentPage, totalItemCount, actionName, new RouteValueDictionary(values));
}
public static string Pager(this HtmlHelper htmlHelper, int pageSize, int currentPage, int totalItemCount, RouteValueDictionary valuesDictionary)
{
return Pager(htmlHelper, pageSize, currentPage, totalItemCount, null, valuesDictionary);
}
public static string Pager(this HtmlHelper htmlHelper, int pageSize, int currentPage, int totalItemCount, string actionName, RouteValueDictionary valuesDictionary)
{
if (valuesDictionary == null)
{
valuesDictionary = new RouteValueDictionary();
}
if (actionName != null)
{
if (valuesDictionary.ContainsKey("action"))
{
throw new ArgumentException("The valuesDictionary already contains an action.", "actionName");
}
valuesDictionary.Add("action", actionName);
}
var pager = new Pager(htmlHelper.ViewContext, pageSize, currentPage, totalItemCount, valuesDictionary);
return pager.RenderHtml();
}
public static IPagedList<T> ToPagedList<T>(this IQueryable<T> source, int pageIndex, int pageSize)
{
return new PagedList<T>(source, pageIndex, pageSize);
}
public static IPagedList<T> ToPagedList<T>(this IQueryable<T> source, int pageIndex, int pageSize, int totalCount)
{
return new PagedList<T>(source, pageIndex, pageSize, totalCount);
}
public static IPagedList<T> ToPagedList<T>(this IEnumerable<T> source, int pageIndex, int pageSize)
{
return new PagedList<T>(source, pageIndex, pageSize);
}
public static IPagedList<T> ToPagedList<T>(this IEnumerable<T> source, int pageIndex, int pageSize, int totalCount)
{
return new PagedList<T>(source, pageIndex, pageSize, totalCount);
}
}
}
然后在我的控制器中;
public class IndexArticlesFormViewModel
{
public IPagedList<Article> articles {get; set;}
public IQueryable<string> userTags { get; set; }
public string tag {get; set;}
}
public ActionResult SearchResults(int? page, string tag)
{
IndexArticlesFormViewModel fvm = new IndexArticlesFormViewModel();
fvm.articles = ar.Search(tag).ToPagedList(page.HasValue ? page.Value - 1 : 0, 8);
fvm.tag = tag;
return View(fvm);
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult SearchResults(int? page, string tag, FormCollection collection)
{
if (!string.IsNullOrEmpty(collection["txtSearch"]))
return RedirectToAction("SearchResults", new {page = 1, tag = collection["txtSearch"] });
return RedirectToAction("SearchResults", new { page = page, searchTerm = tag });
}
然后是View;
<div class="pager">
<%= Html.Pager(ViewData.Model.articles.PageSize, ViewData.Model.articles.PageNumber, ViewData.Model.articles.TotalItemCount, new { tag = Model.tag })%>
</div>
答案 2 :(得分:0)
正如其他人所建议的那样,HtmlHelper在这里可能是合适的,但是如果你想在其他类上调用静态方法,你可以在视图的顶部添加名称空间导入。
<%@ Import Namespace="YOURCONTROLLERNAMESPACE"%>