前段时间在优化项目时,突然想到在Panel上显示文字并换行的问题。当有一段文字需要显示并且最好是显示在Panel。于是我就动手写了下,做了一个Demo程序,现在将主要的代码贴出来,如果存在不足还希望能够帮忙提意见,以补充完善.
///
<summary>
///
显示文本时需要用到的方法
///
</summary>
int lineDistance =
5;
//行间距
Graphics gcs;
int iHeight =
0;
string[] nrLine;
string[] nrLinePos;
int searchPos =
0;
int section =
1;
int sectionHeight =
10;
DispMode dm = DispMode.None;
int iPanelNotPagerHeight=
0;
///
<summary>
///
分析要显示文本的内容,将文本进行分段,分行,并测算好行距,段距等
///
</summary>
///
<param name="pl"></param>
///
<param name="ft"></param>
///
<param name="iWidth"></param>
///
<param name="value"></param>
private
void
GetTextInfo(Panel pl,Font ft,
int iWidth,
string
value)
{
try
{
iHeight =
0;
if (
value !=
"")
{
if (gcs ==
null)
{
gcs = pl.
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];
//存放每行分割的Index数字
SizeF sf1, sf2;
string temps, tempt;
string drawstring;
int temPos;
//临时Index
int ipos;
//文字Index
//将每一段文字的分成句子,并记下每句的起始Idex
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)
{
break;
}
}
ipos += drawstring.Length;
nrLinePos[i] +=
"," + ipos.
ToString();
iHeight++;
}
}
if (dm == DispMode.None)
{
if (
value ==
"")
{
iPanelNotPagerHeight =
0;
return;
}
else
{
iPanelNotPagerHeight = iHeight * (ft.Height + lineDistance) + (section -
1) * (sectionHeight - lineDistance);
}
}
}
catch(Exception e)
{
label1.Text=e.Message;
return;
}
}
///
<summary>
///
根据GetTextInfo方法中测算好的信息来绘制文本,将文本显示到Panel上
///
</summary>
///
<param name="pl"></param>
///
<param name="text"></param>
///
<param name="font"></param>
///
<param name="solidbrushColor"></param>
///
<param name="iWidth"></param>
private
void
PaintTextOnPanel(Panel pl,
string text,Font font,Color solidbrushColor,
int iWidth)
{
Graphics g = pl.
CreateGraphics();
String drawString = text;
Font drawFont = font;
SolidBrush drawBrush =
new
SolidBrush(solidbrushColor);
SizeF textSize = g.
MeasureString(text, font);
//文本的矩形区域大小
int lineCount = Convert.
ToInt16(textSize.Width / iWidth) +
1;
//计算行数
int fHeight = font.Height;
int htHeight =
0;
bool isPageStart =
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;
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]);
//每句的结束Index
midStr = subStr.
Substring(first, idx - first);
//通过上句的结束Index和本句的结束Index计算本句的内容
if (dm == DispMode.None)
{
g.
DrawString(midStr, drawFont, drawBrush, x, Convert.
ToInt16(htHeight), drawFormat);
}
if (j == idxs.Length -
1)
{
htHeight += (fHeight + sectionHeight);
}
else
{
htHeight += (fHeight + lineDistance);
}
first = idx;
//记下本句结束的Index
}
}
}
}
///
<summary>
///
显示模式,分为全显示和分页显示两种
///
</summary>
public
enum DispMode
{
None =
0,
Page =
1
}
调用显示Panel上文本的方法如下
private showTextOnPanel()
{
string txt="客服本来就是一个充满压力的工作,也许你以前没怎么挨过骂,起码挨骂还可以顶嘴,但是作为一个专业的客服专员,你就不允许在电话里表现出情绪波动,无论客户如何无理,如果语气不好,甚至爆粗,你的导师都会教你如何应付,但是前提是你一定不可以表现的不客气,否则全都是你错。这个就是客服,专业的客服!你会面对客户的质问(为什么这个你不懂?我要知道准确的解决时间),面对客户的质疑(你是不是新手啊?你确定这样做一定有效?),面对客户的威胁(再弄不好我要投诉你!你经理是谁?我要你经理接电话)。";
//指定字体
Font drawFont = new Font("Arial", 14);
//调用方法显示
GetTextInfo(panel1,drawFont,400,txt);
PaintTextOnPanel(panel1,txt,drawFont,Color.Red,400);
}