asp打造自动调整大小的Label.docx
- 文档编号:18342776
- 上传时间:2023-08-15
- 格式:DOCX
- 页数:16
- 大小:228.38KB
asp打造自动调整大小的Label.docx
《asp打造自动调整大小的Label.docx》由会员分享,可在线阅读,更多相关《asp打造自动调整大小的Label.docx(16页珍藏版)》请在冰点文库上搜索。
asp打造自动调整大小的Label
很少更新技术的博客,原因很简单,虽然不是从来不遇到问题但是遇到的问题很少会系统地总结出解决思路,也一直觉得没什么写出来的价值,大多是些小问题。
今天遇到一个问题,解决很快不过几分钟的时间,但是还是写出来试试看吧。
当然,还是老规矩,发到新手区,哎,没勇气发首页啊,估计也没发首页的必要吧。
Let'sbegin.
1.问题的提出
我们偶尔需要这样一个控件,就是只需要显示一段文本的label,但是呢,这个Label的文本我们是不知道长度的,但是我们却希望它能自动地随着Label的长度增加而增加它的显示区域。
我们用Label吧,好办,它能搞透明背景色的,这比较符合我的胃口。
TextBox吗?
不做手脚还透明不了~~哎,不符合要求啊不符合。
我们先来看看现在的label控件,能直接用吗?
1.都知道label有个AutoSize属性,并且默认是true的(不知道?
那就给我面壁去)。
这种模式下是会自动调整大小的,但是问题是,嗯,它的宽度也是自动调整的,意味着遇到换行才会开新行,如果这里有一行很长很长很长很长的文字,那会怎样?
估计你猜对了,文字都overflow啦,看不到啦。
至少到现在我还没找到怎么让其乖乖地自动换行的方法,你要是找到了千万别忘记告诉我啊,我会感激不尽的:
-)
2.关掉AutoSize以后又有一个问题了。
文字是能自动换行,但是必须预置一个高度和宽度,在这个高度以外的文字都是显示不出来的。
这回你要说啦,问题不就结了吗,我一开始就给它一个很高很高很高。
。
。
。
高到能够装下所有文字的高度不就万事大吉了吗?
貌似如此。
但是我们的问题是不知道具体有多少文字呀,有可能只有一行,也可能有很多很多很多很多。
。
。
。
。
行呢?
比如我现在想要在一个FlowLayoutPanel这个流布局容器里面显示很多很多的Label来显示很多段文字,但是偏偏每段文字都不一样多的话,都预置好高度……似乎有点不现实吧,也是不可行的。
(也许你会说谁会需要这么变态的功能啊!
呵呵偏偏我就要用,咋办捏)。
问题就是供人解决的,我们来解决it吧。
不好意思上面废话有点多,下面尽量少点。
2.从简单考虑?
从简单的考虑,我们会想要问题的解决简单一点,这就迫使我们会去考虑是否控件本身会提供了这样的功能?
在下面的考虑中,我们会使用相当多的联想和推测,这在程序开发中是个很重要的方面。
我遇到相当多的人问的问题其实如果他们多联想一下和推测一下的话,是很容易自己解决的,也许这样会更有成就感一些。
首先,我们会考虑是否控件本身提供这样的功能了?
从上面看显然没有啊,不然这篇文章还写啥写哦。
那我们就从如何实现它来考虑。
这里的症结是,对应的文字所要求显示的区域是未知的,而控件的大小是固顶的,或自动调整的大小是不符合要求的。
那我们先来选定一个前提状态,就是预置好Label的属性。
AutoSize显然不能用了,那么就用固定大小的吧。
这样还有一个优势,就是我们可以使用Label的Anchor属性固定好它的宽度,而只让它的高度自动变化。
设置好属性的Label现在是这样的:
(为了做例子这里放在了一个UserControl里面)
注意下面还有很多很多很多的。
。
。
垃圾文字哦,呵呵。
先提前说一下,这里设置的大小是300*117。
现在来继续。
我们可以在它显示的时候自动调整大小嘛。
那现在的症结就是如何获得本身应该具有的最佳显示区域?
先从自身的属性上考虑?
关于显示区域的属性,Label原生的关于显示区域和尺寸的有下面这些属性:
DisplayRectangle,ClientRectangle,Size
看看上面的名字我觉得没用,下断点跟踪一下也确实没用,都是我眼看到的大小。
莫非非要我们自己用GDI+画一下才知道大小?
先浏览一下Label所有的属性,突然有个属性蹦进了视线:
自从安装了VS2008SP1以后提示全英文了。
。
我也很怨念的。
所以英文不看也罢。
但是看属性名字似乎有用哦。
与此同时还有一个方法:
GetPreferredSize(),应该就是与这个属性相关联的函数。
从这个属性表面上看起来是获得最佳显示效果的尺寸,是这样吗?
我们下断点看一下。
相信你跟我也一样很囧。
因为这个尺寸一看就知道同AutoSize打开时自动调整的大小一样,就是文字不换行,很长很长很长很长。
。
。
想知道效果?
翻到这篇烂文的最开始去:
-(。
此路不通,呵呵,我们得换条方法。
好像我们刚刚看到了一个。
。
。
GetPreferredSize函数?
既然那个属性派不上,我们用这个玩意儿来试试看。
先让我们来看看声明。
囧了,原来这个方法还要传递一个期望的尺寸。
但是你猜如果我们把它当前的尺寸传递进去,会是什么效果?
我猜就是在给定宽度下最佳的新尺寸?
你猜呢?
试试看。
开心了吧?
看宽度很接近原始宽度,而高度却大了很多,很明显,这不就是最理想的嘛。
不过你可能会说,可是这个宽度咋是295呢?
它的真正宽度不是300吗?
这个需要牵涉到自动换行了,因为自动换行切换了文字,但是最后的宽度不够显示一个字符的,这就留下一段空白了,这几个像素就是留空,不用理它,最后显示的时候只要按照原始宽度300来就OK了。
那现在我们写下这段代码?
publicTestControl()
{
InitializeComponent();
System.Drawing.Sizes=label1.GetPreferredSize(label1.Size);
label1.Size=s;
}
F5一下~恩,结果很好。
3.我们考虑封装一下?
如果只是上面的一个控件那还好办,可是如果我们现在想用很多很多很多这样的控件呢?
或我们需要动态加载呢?
这就涉及到易用性的问题了。
我们要不再来封装一下吧。
我们来建立一个自定义的控件吧,把Label扩展下,就叫……LabelEx吧。
1:
internalclassLabelEx:
System.Windows.Forms.Label
2:
{
3:
publicLabelEx()
4:
:
base()
5:
{
6:
//关闭AutoSize
7:
this.AutoSize=false;
8:
9:
//捕捉事件
10:
this.TextChanged+=newEventHandler(LabelEx_TextChanged);
11:
}
12:
13:
///
14:
///重写AutoSize属性,防止AutoSize再被打开
15:
///
16:
publicoverrideboolAutoSize
17:
{
18:
get
19:
{
20:
returnfalse;
21:
}
22:
}
23:
24:
voidLabelEx_TextChanged(objectsender,EventArgse)
25:
{
26:
//文字变化了,那就改变一下当前的大小
27:
System.Drawing.Sizeps=GetPreferredSize(this.Size);
28:
29:
//这里构造一个新的Size对象,目的是使用原始的宽度。
原因嘛,见上面
30:
this.Size=newSystem.Drawing.Size(this.Width,ps.Height);
31:
}
32:
}
现在编译一下,然后拖一个到界面上,然后在代码里面手动绑定它的Text属性(不可以在设计器里面修改,这样你会发现你的设计器里面的控件尺寸是始终自动变化的)。
运行看看效果?
(加了一个边框是为了看效果)
设置代码如下:
1:
publicTestControl()
2:
{
3:
InitializeComponent();
4:
5:
labelEx1.Text="label1label1label1label1label1label1label1llabel1label1label1label1\n"+
6:
"label1label1\n"+
7:
"label1label1\n"+
8:
"label1label1\n"+
9:
"label1label1label1label1label1label1label1label1label1label1label1labeel1label1label1label1label1label1\n"+
10:
"label1label1\n"+
11:
"label1label1\n"+
12:
"label1label1\n"+
13:
"label1label1label1label1label1label1label1label1label1label1label1lbel1label1label1label1label1label1label1\n"+
14:
"label1label1\n"+
15:
"label1label1\n"+
16:
"label1label1\n";
17:
}
显示如下:
貌似很符合要求?
活活。
4.我们扩展下?
有时候我们会考虑在一个子控件里面封装这么个东东,比如加点花边之类的。
可是里面的label纵然会自动调整大小可是容器不行,那可不好,因为溢出的东东又会隐藏了,就像这样的:
Bingo!
当然是有解决方法的,因为有个父控件呗!
改!
重写LabelEx_TextChanged函数如下:
1:
voidLabelEx_TextChanged(objectsender,EventArgse)
2:
{
3:
//记录下当前的高度
4:
intoh=this.Height;
5:
6:
//文字变化了,那就改变一下当前的大小
7:
System.Drawing.Sizeps=GetPreferredSize(this.Size);
8:
9:
//这里构造一个新的Size对象,目的是使用原始的宽度。
原因嘛,见上面
10:
this.Size=newSystem.Drawing.Size(this.Width,ps.Height);
11:
12:
if(this.Parent!
=null&&AutoResizeParent)
13:
{
14:
//调整容器大小
15:
this.Parent.Size=newSystem.Drawing.Size(this.Parent.Width,ps.Height-oh+this.Parent.Height);
16:
}
17:
}
添加一个功能开关的属性
1:
///
2:
///是否自动调整父控件
3:
///
4:
publicboolAutoResizeParent{get;set;}
哦也?
哦也。
可是我隐隐约约好像还有问题啊。
。
。
比如原本好像显示得好好的:
可是我把窗体缩小(利用Anchor让LabelEx也缩小)后惊喜地发现……
:
-(
好吧,继续改写,好了~
最终代码如下:
1:
internalclassLabelEx:
System.Windows.Forms.Label
2:
{
3:
publicLabelEx()
4:
:
base()
5:
{
6:
//关闭AutoSize
7:
this.AutoSize=false;
8:
9:
//捕捉事件
10:
this.TextChanged+=newEventHandler(LabelEx_TextChanged);
11:
this.SizeChanged+=newEventHandler(LabelEx_SizeChanged);
12:
}
13:
14:
//记录原始的宽度
15:
int_oldw;
16:
17:
voidLabelEx_SizeChanged(objectsender,EventArgse)
18:
{
19:
//如果宽度没变,那就返回
20:
if(this.Width==_oldw)return;
21:
22:
//重新计算高度
23:
LabelEx_TextChanged(null,null);
24:
25:
//记录
26:
_oldw=this.Width;
27:
}
28:
29:
///
30:
///重写AutoSize属性,防止AutoSize再被打开
31:
///
32:
publicoverrideboolAutoSize
33:
{
34:
get
35:
{
36:
returnfalse;
37:
}
38:
}
39:
40:
///
41:
///是否自动调整父控件
42:
///
43:
publicboolAutoResizeParent{get;set;}
44:
45:
voidLabelEx_TextChanged(objectsender,EventArgse)
46:
{
47:
//记录下当前的高度
48:
intoh=this.Height;
49:
50:
//文字变化了,那就改变一下当前的大小
51:
System.Drawing.Sizeps=GetPreferredSize(this.Size);
52:
53:
//这里构造一个新的Size对象,目的是使用原始的宽度。
原因嘛,见上面
54:
this.Size=newSystem.Drawing.Size(this.Width,ps.Height);
55:
56:
if(this.Parent!
=null&&AutoResizeParent)
57:
{
58:
//调整容器大小
59:
this.Parent.Size=newSystem.Drawing.Size(this.Parent.Width,ps.Height-oh+this.Parent.Height);
60:
}
61:
}
62:
}
5.用处?
我们上面写这一大票还是不好使啊!
比如这个labelex控件的容器(比如上面的GroupBox)的大小溢出了,还是要隐藏的啊。
呵呵。
不过我们早就说过了,这个东东最主要是用在流式布局的(因为溢出会自动滚动),比如下面的代码:
1:
publicForm1()
2:
{
3:
InitializeComponent();
4:
5:
6:
LoadFlowControls();
7:
}
8:
9:
voidLoadFlowControls()
10:
{
11:
//允许自动滚动
12:
flowLayoutPanel1.AutoScroll=true;
13:
14:
stringtext="这里是第{0}段第{0}行文字,测试测试啦!
\n";
15:
16:
System.Text.StringBuildersb=newStringBuilder();
17:
18:
for(inti=1;i<10;i++)
19:
{
20:
sb.AppendFormat(text,i.ToString());
21:
22:
//创建LabelEx控件
23:
LabelExlab=newLabelEx()
24:
{
25:
Text=sb.ToString(),
26:
Anchor=AnchorStyles.Top|AnchorStyles.Left|AnchorStyles.Right,
27:
Location=newPoint(0,0),
28:
Left=0,
29:
Size=newSize(flowLayoutPanel1.ClientSize.Width-30,10),
30:
//加边框以便观察
31:
BorderStyle=BorderStyle.FixedSingle
32:
};
33:
//添加到容器里面
34:
flowLayoutPanel1.Controls.Add(lab);
35:
}
36:
}
显示效果如下:
嘿。
现在能猜出来我要做啥了不?
是一个可以显示论坛帖子文字内容的Label~~~哈哈
PS,本文在WLW中发布的,再编辑一次后所有的CSS样式全部丢失了,所以代码高亮都无效的,咳
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- asp 打造 自动 调整 大小 Label
![提示](https://static.bingdoc.com/images/bang_tan.gif)