⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pager.cs

📁 基于.Net环境下c#实现的国人自己的Blog平台,基于.Text的核心技术,但做了汉化以及改写了一部分的核心代码,值得研究学习
💻 CS
字号:
#region Disclaimer/Info

///////////////////////////////////////////////////////////////////////////////////////////////////
// .Text WebLog
// 
// .Text is an open source weblog system started by Scott Watermasysk. 
// Blog: http://ScottWater.com/blog 
// RSS: http://scottwater.com/blog/rss.aspx
// Email: Dottext@ScottWater.com
//
// For updated news and information please visit http://scottwater.com/dottext and subscribe to 
// the Rss feed @ http://scottwater.com/dottext/rss.aspx
//
// On its release (on or about August 1, 2003) this application is licensed under the BSD. However, I reserve the 
// right to change or modify this at any time. The most recent and up to date license can always be fount at:
// http://ScottWater.com/License.txt
// 
// Please direct all code related questions to:
// GotDotNet Workspace: http://www.gotdotnet.com/Community/Workspaces/workspace.aspx?id=e99fccb3-1a8c-42b5-90ee-348f6b77c407
// Yahoo Group http://groups.yahoo.com/group/DotText/
// 
///////////////////////////////////////////////////////////////////////////////////////////////////

#endregion

#undef    Diagnostic
using System;
using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.Design;

namespace Dottext.Web.Admin.WebUI
{
	public enum DisplayType
	{
		Block,
		Inline
	}

	[Designer(typeof (PagerDesigner)), ToolboxData("<{0}:Pager runat=\"server\" />")]
	public class Pager : Control
	{
		protected const string VSKEY_ITEMCOUNT = "ItemCount";
		protected const string VSKEY_PAGEINDEX = "PageIndex";
		protected const string VSKEY_PAGESIZE = "PageSize";
		protected const string VSKEY_DISPLAYPAGES = "DisplayPages";

		protected const int FIRST_PAGE_INDEX = 1;
		protected const int PAGESIZE_MIN = 1;
		protected const int PAGESIZE_DEFAULT = 20;
		protected const int DISPLAYPAGES_MIN = 3;
		protected const int DISPLAYPAGES_DEFAULT = 9;

		protected const string SPACER_DEFAULT = "&nbsp;";
		protected const string FIRSTTEXT_DEFAULT = "最前";
		protected const string LASTTEXT_DEFAULT = "最后";
		protected const string PREFIXTEXT_DEFAULT = "到页&nbsp;";
		protected const string SUFFIXTEXT_DEFAULT = "";
		protected const string URLFORMAT_DEFAULT = "/?pageid={0}";
		protected const string LINKFORMAT_DEFAULT = "<a href=\"{0}\">{1}</a>";
		protected const string LINKFORMAT_ACTIVE_DEFAULT = "<a href=\"{0}\" class=\"Current\">&#187;{1}&#171;</a>";

		protected DisplayType _displayMode = DisplayType.Block;

		protected string _cssClass;

		protected bool _useSpacer = true;
		protected string _spacer;

		protected string _urlFormat = URLFORMAT_DEFAULT;
		protected string _linkFormat = LINKFORMAT_DEFAULT;
		protected string _linkFormatActive = LINKFORMAT_ACTIVE_DEFAULT;

		protected bool _useFirstLast = true;
		protected string _firstText = FIRSTTEXT_DEFAULT;
		protected string _lastText = LASTTEXT_DEFAULT;

		protected bool _usePrefixSuffix = true;
		protected string _prefixText = PREFIXTEXT_DEFAULT;
		protected string _suffixText = SUFFIXTEXT_DEFAULT;

		protected int _padLeft;
		protected int _padRight;

		public Pager()
		{
			ViewState[VSKEY_ITEMCOUNT] = 0;
			ViewState[VSKEY_PAGEINDEX] = FIRST_PAGE_INDEX;
			ViewState[VSKEY_PAGESIZE] = PAGESIZE_DEFAULT;
			this.DisplayPages = DISPLAYPAGES_DEFAULT;
		}

		#region Accessors

		public DisplayType DisplayMode
		{
			get { return _displayMode; }
			set { _displayMode = value; }
		}

		public string CssClass
		{
			get { return _cssClass; }
			set { _cssClass = value; }
		}

		public int ItemCount
		{
			get { return (int) ViewState[VSKEY_ITEMCOUNT]; }
			set
			{
				if (value < 0)
					ViewState[VSKEY_ITEMCOUNT] = 0;
				else
					ViewState[VSKEY_ITEMCOUNT] = value;
			}
		}

		public int PageIndex
		{
			get { return (int) ViewState[VSKEY_PAGEINDEX]; }
			set
			{
				if (value >= FIRST_PAGE_INDEX)
					ViewState[VSKEY_PAGEINDEX] = value;
				else
					ViewState[VSKEY_PAGEINDEX] = FIRST_PAGE_INDEX;
			}
		}

		public int PageSize
		{
			get { return (int) ViewState[VSKEY_PAGESIZE]; }
			set
			{
				if (value >= PAGESIZE_MIN)
					ViewState[VSKEY_PAGESIZE] = value;
				else
					ViewState[VSKEY_PAGESIZE] = PAGESIZE_MIN;
			}
		}

		public int DisplayPages
		{
			get { return (int) ViewState[VSKEY_DISPLAYPAGES]; }
			set
			{
				int displayPages = value;
				if (displayPages < DISPLAYPAGES_MIN)
					displayPages = DISPLAYPAGES_MIN;

				ViewState[VSKEY_DISPLAYPAGES] = displayPages;
			}
		}

		public int MaxPages
		{
			get
			{
				if (PageSize > 0)
					return (int) Math.Ceiling((double) ItemCount/PageSize);
				else
					return 0;
			}
		}

		public string Spacer
		{
			get
			{
				if (null == _spacer || _spacer.Length == 0)
					_spacer = SPACER_DEFAULT;

				return _spacer;
			}
			set { _spacer = value; }
		}

		public bool UseSpacer
		{
			get { return _useSpacer; }
			set { _useSpacer = value; }
		}

		public string UrlFormat
		{
			get { return _urlFormat; }
			set { _urlFormat = value; }
		}

		public string LinkFormat
		{
			get { return _linkFormat; }
			set { _linkFormat = value; }
		}

		public string LinkFormatActive
		{
			get { return _linkFormatActive; }
			set { _linkFormatActive = value; }
		}

		public bool UseFirstLast
		{
			get { return _useFirstLast; }
			set { _useFirstLast = value; }
		}

		public string FirstText
		{
			get { return _firstText; }
			set { _firstText = value; }
		}

		public string LastText
		{
			get { return _lastText; }
			set { _lastText = value; }
		}

		public bool UsePrefixSuffix
		{
			get { return _usePrefixSuffix; }
			set { _usePrefixSuffix = value; }
		}

		public string SuffixText
		{
			get { return _suffixText; }
			set { _suffixText = value; }
		}

		public string PrefixText
		{
			get { return _prefixText; }
			set { _prefixText = value; }
		}


		#endregion

		// TODO: linkcss
		// TODO: linkherecss

		protected void CalcPadding(int displayPages)
		{
			// want even padding if we can have it
			_padLeft = displayPages/2;
			_padRight = _padLeft;

			// but if PageSize is even, shift current over one slot to the left by reducing _padLeft
			if (displayPages%2 == 0)
				_padLeft--;
		}

		protected string RenderLink(int pageid, bool isCurrent)
		{
			return RenderLink(pageid, pageid.ToString(), isCurrent);
		}

		protected string RenderLink(int linkIndex, string display)
		{
			return RenderLink(linkIndex, display, false);
		}

		protected string RenderLink(int linkIndex, string display, bool isCurrent)
		{
			string url = String.Format(_urlFormat, linkIndex);
			return String.Format(isCurrent ? _linkFormatActive : _linkFormat,
			                     url, display);
		}

		protected virtual void WriteConditional(HtmlTextWriter writer, string value, bool condition)
		{
			if (condition)
				writer.Write(value);
		}

		#region Render

		protected override void Render(HtmlTextWriter writer)
		{
			// there's only 1 page, a pager is useless so render nothing
			if (FIRST_PAGE_INDEX == MaxPages)
				return;

			if (_cssClass.Length > 0)
				writer.AddAttribute("class", _cssClass);

			if (_displayMode == DisplayType.Block)
				writer.RenderBeginTag(HtmlTextWriterTag.Div);
			else
				writer.RenderBeginTag(HtmlTextWriterTag.Span);

			// write prepended label if appropriate and an optional spacer literal
			WriteConditional(writer, _prefixText, _usePrefixSuffix);
			WriteConditional(writer, Spacer, _useSpacer);

			CalcPadding(DisplayPages);

			// there may be a more straightforward way of dealing with padding edge cases,
			// we thought we had one but it was not catching the very first use case (selected
			// index = first page). This seems more kludgy, but it works.
			//
			// we can't have overflow and underflow at the same time if we have more possible 
			// pages to display than we've allowed for. if we can display all the possible pages
			// without scrolling left and right, then we only need to worry about the left
			// padding and keeping the initial counter in the right place (1).
			//
			// what we'll do is see if our current selected index is with in range (amount of 
			// padding) of either the first or last pages. if it is, then we'll shift the 
			// amount of padding slots that we can't use to the other end.
			if ((PageIndex - _padLeft) <= 0)
			{
				// our current index falls inside the padded beginning: underflow
				_padRight += _padLeft - PageIndex + 1;
				_padLeft = PageIndex - 1;
			}
			else if ((PageIndex + _padRight) > MaxPages)
			{
				// our current index falls inside the padded end: overflow
				_padLeft += _padRight - (MaxPages - PageIndex);
				_padRight = MaxPages - PageIndex;
			}

			// walk the counter backwards to the first item we're going to display from the 
			// currently selected item. _padLeft will put as at the right place to start.
			int counter = _padLeft;
			int idx = 1;
			while (counter > 0)
			{
				idx = PageIndex - counter;
				if (idx >= FIRST_PAGE_INDEX)
					break;
				counter--;
			}

			// if we specified including 'First' link back to page 1, write it plus an 
			// optional spacer
			if (idx > FIRST_PAGE_INDEX && _useFirstLast)
			{
				writer.Write(RenderLink(FIRST_PAGE_INDEX, _firstText));
				WriteConditional(writer, Spacer, _useSpacer);
			}

			// starting at the place where we walked the counter back to, draw N links
			// as long as we're in the allowable bounds
			for (int i = idx; i < idx + DisplayPages; i++)
			{
				if (i >= FIRST_PAGE_INDEX && i <= MaxPages)
				{
					writer.Write(RenderLink(i, i == PageIndex));
					WriteConditional(writer, Spacer, _useSpacer);
				}
			}

			// if we specified including 'Last' link back to the last page, write it plus 
			// an optional spacer
			if (!(idx + DisplayPages > MaxPages) && _useFirstLast)
			{
				writer.Write(RenderLink(MaxPages, _lastText));
				WriteConditional(writer, Spacer, _useSpacer);
			}

			WriteConditional(writer, _suffixText, _usePrefixSuffix);

			writer.RenderEndTag();

#if    Diagnostic
			writer.Write("<br>PageIndex={0}, _padLeft={1}, _padRight={2}, MaxPages={3}, DisplayPages={4}, ItemCount={5}<br>",
			             PageIndex, _padLeft, _padRight, MaxPages, DisplayPages, ItemCount);
#endif

		}

		#endregion
	}

	public class PagerDesigner : ControlDesigner
	{
		public override string GetDesignTimeHtml()
		{
			return base.GetDesignTimeHtml();
		}

		public override void Initialize(IComponent component)
		{
			if (component is Pager)
			{
				Pager context = component as Pager;
				context.PageSize = 10;
				context.ItemCount = 120;
				context.PageIndex++;
			}

			base.Initialize(component);
		}

	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -