话说分页这玩意在开发中可是相当的常见。网上到处都是分页的资料。可是在Winform中要做到分页显示文本内容就没有那么容易。而且不能使用一些可以分页的控件,比较DateGridView等。只好在已有的代码基础上开发了一个具备分页功能,并且可以改变行间距的Label。
代码写的比较长,可以拷贝下来直接使用,体验下。
using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Drawing;
using System.Text.RegularExpressions;
public partial class LabelEx : System.Windows.Forms.Label
{
int lineDistance = 5;//行间距
Graphics gcs;
int iHeight = 0, height = 200;
string[] nrLine;
string[] nrLinePos;
int searchPos = 0;
int section = 1;
int sectionHeight = 5;
int pageHeight = 100;
DispMode dm = DispMode.None;
private int pageno = 1;
private bool isend = false;//是否尾页
public event EventHandler EndPage;
///Label所在的容器的高度
private int containerHeight=0;
///Label在容器下端显示不了时附加高度
private int attachHeight = 20;
//是否清除文本中的Html文本标签
private bool fClearHtml = false;
[DescriptionAttribute("")]
public bool FClearHtml
{
get { return fClearHtml; }
set
{
fClearHtml = value;
}
}
[DescriptionAttribute("Label在容器下端显示不了时附加高度")]
public int AttachHeight
{
get { return attachHeight; }
set
{
attachHeight = value;
}
}
[DescriptionAttribute("Label所在的容器的高度")]
public int ContainerHeight
{
get { return containerHeight; }
set
{
containerHeight = value;
}
}
[DescriptionAttribute("获取或设置行距")]
public int LineDistance
{
get { return lineDistance; }
set
{
lineDistance = value;
Changed(this.Font, this.Width, this.Text);
}
}
[DescriptionAttribute("页码,在翻页模式下有用")]
public int PageNo
{
get { return pageno; }
set
{
if (value > 0 && pageno != value)
{
if (isend && value>pageno)
return;
pageno = value;
this.Refresh();
}
}
}
public LabelEx()
: base()
{
//this.TextChanged += new EventHandler(LabelEx_TextChanged);
this.SizeChanged += new EventHandler(LabelEx_SizeChanged);
this.FontChanged += new EventHandler(LabelEx_FontChanged);
//this.Font = new Font(this.Font.FontFamily, this.Font.Size, GraphicsUnit.Pixel);
}
void LabelEx_FontChanged(object sender, EventArgs e)
{
Changed(this.Font, this.Width, this.Text);
}
void LabelEx_SizeChanged(object sender, EventArgs e)
{
Changed(this.Font, this.Width, this.Text);
}
public LabelEx(IContainer container)
{
container.Add(this);
//base.Height
//InitializeComponent();
}
[DescriptionAttribute("页面高度,在翻页模式下有用")]
public int PageHeight
{
get { return pageHeight; }
set
{
pageHeight = value;
base.Height = value;
}
}
[DescriptionAttribute("呈现模式")]
public DispMode DisplayMode
{
get { return dm; }
set { dm = value; }
}
[DescriptionAttribute("获取文字高度")]
public int FHeight
{
get { return this.Font.Height; }
}
[DescriptionAttribute("获取行高")]
public int LineHeight
{
get { return this.Font.Height + lineDistance; }
}
public int SectionHeight
{
get { return this.Font.Height + sectionHeight; }
}
[DescriptionAttribute("设置或获取段落间距")]
public int SecDisTance
{
get { return sectionHeight; }
set { sectionHeight = value; }
}
public new int Height
{
get { return height; }
set
{
height = value;
base.Height = value;
}
}
public override string Text
{
get
{
return base.Text;
}
set
{
//is.Font.Size.
if (FClearHtml)
{
base.Text=value;
string strText = base.Text;
strText = ClearHtml(strText);
base.Text = strText;
Changed(this.Font, this.Width, strText);
}
else
{
base.Text = value;
Changed(this.Font, this.Width, value);
}
}
}
public bool IsEnd
{
get { return isend; }
}
protected void Changed(Font ft, int iWidth, string value)
{
iHeight = 0;
if (value != "")
{
if (gcs == null)
{
gcs = this.CreateGraphics();
SizeF sf0 = gcs.MeasureString(new string('测', 20), ft);
searchPos = (int)(iWidth * 20 / sf0.Width);
if (searchPos > 2) searchPos -= 2;
}
nrLine = value.Split(new string[1] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
section = nrLine.Length;
nrLinePos = new string[section];
SizeF sf1, sf2;
string temps, tempt;
string drawstring;
int temPos, ipos;
for (int i = 0; i < section; i++)
{
ipos = 0;
temPos = searchPos;
if (searchPos >= nrLine[i].Length)
{
ipos += nrLine[i].Length;
nrLinePos[i] += "," + ipos.ToString();
iHeight++;
continue;
}
drawstring = nrLine[i];
nrLinePos[i] = "";
while (drawstring.Length > searchPos)
{
bool isfind = false;
for (int j = searchPos; j < drawstring.Length; j++)
{
temps = drawstring.Substring(0, j);
tempt = drawstring.Substring(0, j + 1);
sf1 = gcs.MeasureString(temps, ft);
sf2 = gcs.MeasureString(tempt, ft);
if (sf1.Width < iWidth && sf2.Width > iWidth)
{
iHeight++;
ipos += j;
nrLinePos[i] += "," + ipos.ToString();
isfind = true;
drawstring = drawstring.Substring(j);
break;
}
}
if (!isfind)
{
//drawstring = drawstring.Substring(searchPos);
//iHeight++;
break;
}
}
ipos += drawstring.Length;
nrLinePos[i] += "," + ipos.ToString();
iHeight++;
//tempLine = (int)(sf1.Width - 1) / this.Width + 1;
//iHeight += tempLine;
}
}
if (dm == DispMode.None)
{
//this.Height = iHeight * (ft.Height + lineDistance) + (section - 1) * (sectionHeight - lineDistance);
//add by kevin gao 20110511 --------------begine
if (value == "")
{
this.Height = 0;
return;
}
if (this.ContainerHeight == 0)
{
this.Height = iHeight * (ft.Height + lineDistance) + (section - 1) * (sectionHeight - lineDistance);
}
else
{
int tmpHeight = 0;
int fHeight = ft.Height;
for (int i = 0; i < section; i++)
{
int iLineNum = 0;
if (nrLinePos[i] == null || nrLinePos[i] == "")
{
return;
}
string strLinePos = nrLinePos[i].TrimStart(',');
iLineNum = strLinePos.Split(',').Length;
for (int j = 0; j < iLineNum; j++)
{
int iTop = this.Top + tmpHeight;
if (ContainerHeight == 0)
{
return;
}
//if (this.Top < 0)
//{
// iTop = ContainerHeight + this.Top + tmpHeight;
//}
int RelTop = iTop % ContainerHeight;
int TempHeight = 0;
if (j == iLineNum - 1)
{
TempHeight = RelTop + (fHeight + sectionHeight);
}
else
{
TempHeight = RelTop + (fHeight + lineDistance);
}
if (TempHeight > ContainerHeight)
{
if (RelTop + fHeight > containerHeight)
{
AttachHeight = ContainerHeight - RelTop;
tmpHeight += AttachHeight;
}
//tmpHeight += TempHeight - ContainerHeight + 2;
}
if (j == iLineNum - 1)
{
tmpHeight += fHeight + sectionHeight;
}
else
{
tmpHeight += fHeight + lineDistance;
}
}
}
this.Height = tmpHeight;
}
//add by kevin gao 20110511 --------------end
}
}
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
//base.OnPaint(e);
//if (isPaint) return;
//isPaint = true;
Graphics g = e.Graphics;
String drawString = this.Text;
Font drawFont = this.Font;
SolidBrush drawBrush = new SolidBrush(this.ForeColor);
SizeF textSize = g.MeasureString(this.Text, this.Font);//文本的矩形区域大小
int lineCount = Convert.ToInt16(textSize.Width / this.Width) + 1;//计算行数
int fHeight = this.Font.Height;
int htHeight = 0;
bool isPageStart = false;
this.AutoSize = false;
float x = 0.0F;
StringFormat drawFormat = new StringFormat();
lineCount = drawString.Length;//行数不超过总字符数目
int i, idx, first;
string subStr, tmpStr = "", midStr = "";
string[] idxs;
int tmpPage = 1;
isend = false;
string preLineStr = "";
for (i = 0; i < section; i++)
{
if (i == 10)
{
first = 0;
}
first = 0;
subStr = nrLine[i];
if (nrLinePos[i] != null) tmpStr = nrLinePos[i].TrimStart(',');
midStr = subStr.Substring(first);
if (tmpStr != "")
{
idxs = tmpStr.Split(',');
for (int j = 0; j < idxs.Length; j++)
{
idx = int.Parse(idxs[j]);
midStr = subStr.Substring(first, idx - first);
if (dm == DispMode.None)
{
//add by kevin gao 20110511 ---begine
if (ContainerHeight == 0)
{
e.Graphics.DrawString(midStr, drawFont, drawBrush, x, Convert.ToInt16(htHeight), drawFormat);
}
else
{
int iTop = this.Top + htHeight;
if (this.Top < 0)
{
iTop = ContainerHeight + this.Top + htHeight;
}
int RelTop = iTop % ContainerHeight;
int TempHeight = 0;
if (j == idxs.Length - 1)
{
TempHeight = RelTop + (fHeight + sectionHeight);
}
else
{
TempHeight = RelTop + (fHeight + lineDistance);
}
if (TempHeight > ContainerHeight)
{
if (RelTop + fHeight > containerHeight)
{
AttachHeight = ContainerHeight - RelTop;
htHeight += AttachHeight;
e.Graphics.DrawString(midStr, drawFont, drawBrush, x, Convert.ToInt16(htHeight), drawFormat);
}
else
{
e.Graphics.DrawString(midStr, drawFont, drawBrush, x, Convert.ToInt16(htHeight), drawFormat);
}
}
else
{
e.Graphics.DrawString(midStr, drawFont, drawBrush, x, Convert.ToInt16(htHeight), drawFormat);
}
}
//add by kevin gao 20110511 ---end
//e.Graphics.DrawString(midStr, drawFont, drawBrush, x, Convert.ToInt16(htHeight), drawFormat);
}
else
{
if ((htHeight + fHeight) > pageHeight)
{
tmpPage++;
if (tmpPage > pageno)
{
//e.Graphics.DrawString(midStr, drawFont, drawBrush, x, Convert.ToInt16(htHeight), drawFormat);
this.Height = htHeight + fHeight;
if (i == section - 1 && j == idxs.Length - 1)
{
isend = true;
if (EndPage != null)
EndPage(this, e);
}
return;
}
preLineStr = midStr;
isPageStart = true;
htHeight = 0;
}
else
{
if (tmpPage == pageno)
{
if (isPageStart)
{
e.Graphics.DrawString(preLineStr, drawFont, drawBrush, x, 0, drawFormat);
}
isPageStart = false;
e.Graphics.DrawString(midStr, drawFont, drawBrush, x, Convert.ToInt16(htHeight), drawFormat);
}
if (i == section - 1 && j == idxs.Length - 1)
{
isend = true;
if (EndPage != null)
EndPage(this, e);
}
}
}
if (j == idxs.Length - 1)
{
htHeight += (fHeight + sectionHeight);
}
else
{
htHeight += (fHeight + lineDistance);
}
first = idx;
}
}
}
}
/// <summary>
/// 清除文本中的Html标签
/// </summary>
/// <param name="patrn">要替换的标签正则表达式</param>
/// <param name="strRep">替换为的内容</param>
/// <param name="content">要替换的内容</param>
/// <returns></returns>
private string Zxj_ReplaceHtml(string patrn, string strRep, string content)
{
if (string.IsNullOrEmpty(content))
{
content = "";
}
Regex rgEx = new Regex(patrn, RegexOptions.IgnoreCase);
string strTxt = rgEx.Replace(content, strRep);
return strTxt;
}
/// <summary>
/// 清除文本中Html的标签
/// </summary>
/// <param name="Content"></param>
/// <returns></returns>
private string ClearHtml(string Content)
{
Content = Zxj_ReplaceHtml("&#[^>]*;", "", Content);
Content = Zxj_ReplaceHtml("</?marquee[^>]*>", "", Content);
Content = Zxj_ReplaceHtml("</?object[^>]*>", "", Content);
Content = Zxj_ReplaceHtml("</?param[^>]*>", "", Content);
Content = Zxj_ReplaceHtml("</?embed[^>]*>", "", Content);
Content = Zxj_ReplaceHtml("</?table[^>]*>", "", Content);
Content = Zxj_ReplaceHtml(" ", "", Content);
Content = Zxj_ReplaceHtml("</?tr[^>]*>", "", Content);
Content = Zxj_ReplaceHtml("</?th[^>]*>", "", Content);
Content = Zxj_ReplaceHtml("</?p[^>]*>", "", Content);
Content = Zxj_ReplaceHtml("</?a[^>]*>", "", Content);
Content = Zxj_ReplaceHtml("</?img[^>]*>", "", Content);
Content = Zxj_ReplaceHtml("</?tbody[^>]*>", "", Content);
Content = Zxj_ReplaceHtml("</?li[^>]*>", "", Content);
Content = Zxj_ReplaceHtml("</?span[^>]*>", "", Content);
Content = Zxj_ReplaceHtml("</?div[^>]*>", "", Content);
Content = Zxj_ReplaceHtml("</?th[^>]*>", "", Content);
Content = Zxj_ReplaceHtml("</?td[^>]*>", "", Content);
Content = Zxj_ReplaceHtml("</?script[^>]*>", "", Content);
Content = Zxj_ReplaceHtml("(javascript|jscript|vbscript|vbs):", "", Content);
Content = Zxj_ReplaceHtml("on(mouse|exit|error|click|key)", "", Content);
Content = Zxj_ReplaceHtml("<\\?xml[^>]*>", "", Content);
Content = Zxj_ReplaceHtml("<\\/?[a-z]+:[^>]*>", "", Content);
Content = Zxj_ReplaceHtml("</?font[^>]*>", "", Content);
Content = Zxj_ReplaceHtml("</?b[^>]*>", "", Content);
Content = Zxj_ReplaceHtml("</?u[^>]*>", "", Content);
Content = Zxj_ReplaceHtml("</?i[^>]*>", "", Content);
Content = Zxj_ReplaceHtml("</?strong[^>]*>", "", Content);
string clearHtml = Content;
return clearHtml;
}
}
/// <summary>
/// 显示模式,分为全显示和分页显示两种
/// </summary>
public enum DispMode
{
None = 0,
Page = 1
}