ASP.NET控件开发入门系列之PlanItem控件

本文介绍了一种自定义的进度控件PlanItem的开发过程。该控件通过三个div元素实现进度显示,能够根据进度百分比动态调整背景图片宽度,并支持多种属性设置以满足不同需求。

在portal项目第一迭代中,我主要负责控件库这一块的工作。所谓知识需要分享,阅读丰富人生。我希望和大家分享一下控件经验并相互探讨以求共同进步,一起成长。


以下是所需控件和其功能描述:

名称

说明

备注

ScollGridView

带滚动的GridVIew,与asp.net GridView有别,Asp.net GridView在数据过多时采用的是分页,而ScollGridView在数据过多时采用垂直滚动条解决

运用于各种统计页面

PlanItem

具体表现为图片的宽度为进度的百分比。

运用于进度的表示

StatusItem

利用不同的图片与文字表现不同的状态

BiasItem

将偏差的正负值转换为落后与超前及相应的色彩

用于表示偏差方向

今天先讲一下PlanItem控件吧

首先,我们先回忆一下VS2010中自带的.NET控件都有些什么特征,如属性、事件等等,并且都可以自己设置相关属性和编写事件实现的相关代码...是吧,而现在我们要写控件也要让它拥有这些特征,暴露出其相关的属性和事件,我们会用到面向对象编程里的继承,继承属性、事件、方法...在我看来,好的控件应该满足活字印刷中的一些特征,如灵活性、可扩展性、可复用性...另外最重要的一点,也是我们不得不考虑的问题——兼容性。
关于兼容性问题可以参考:Portal项目的Hackhttp://blog.youkuaiyun.com/zouyujie1127/article/details/6903278

1、打开VS2010,新建一个空白的解决方案。

2、在空白解决方案中新建类库,类库名为PlanItem,选择PlanItem并右键单击“引用”,选择“添加引用”,添加System.Web和System.Web.Extension的引用


在PlanItem类库中新建一个类MyPlanItem.cs用于描述PlanItem控件

3、介绍一下控件开发中常用的属性的设计时特性

[Category("显示")]:设置该控件在属性面板中显示的组名。

[Description("进度文本,保留两位小数")]:设置属性说明,在选中该控件后,可以在属性面板的底部看到属性的说明。
[DefaultValue("0.00")]:设置属性的默认值。


4、首先,我应该知道控件其实也是一个类,而控件的最终基类就是Control类,在.NET控件开发中,我们常用到三个类,它们分别是Control、WebControl、CompositeControl(复合控件)这里我们让其继承Control,WebControl是Control的一个子类,所以其具有比Control更多的属性,如Style样式等等...

在接下来的.NET控件开发中,我们会使用一个Render()的重写方法,从而将控件输出到页面中去,要知道,.NET控件的最终显示形式就是以HTML标记显示的。

所以,我们可以在要开发什么控件之前,先用Dreamver8将其画出来,然后在对其进行编码实现。

最后,将PlanItem.cs编译成dll类库,然后在工具箱面板对其进行添加后,就可以像使用.NET控件一样将其拖放到将要放置的位置进行使用了。

编译命令,大家还记得吧。(csc /target:library PlanItem.cs)

protected override void Render(HtmlTextWriter writer) 160. { 161. string div1 = "<div style='position:static;float:left;width:" + this.DivWidth + "px;height:" + this.DivHeight + "px;z-index:1;background-image: url(" + this.BgImageDown + ");_background-image: none;'/>"; 162. writer.Write(div1); 163. string div2 = "<div style='position:static;width:" + this.ImgWidth + "%;height:" + this.DivHeight + "px;z-index:2;float:left;background-image: url(" + this.BgImageUp + ");_background-image: none; '/>"; 164. writer.Write(div2); 165. string div3 = "<div style='position:static;margin-left:auto;margin-right:auto;width:" + DivWidth + "px;height:" + DivHeight + "px;line-height:" + DivHeight + "px;z-index:3; text-align:center; vertical-align:middle;color:" + TextColor + ";font-size:12px;'>"; 166. writer.Write(div3); 167. writer.Write(this.Text + "%"); 168. writer.Write("</div>"); 169. }

细心的朋友可能会发现,在Render(HtmlTextWriter writer)方法中,出现了 _background-image: none;这是为了解决IE6中的侵吞现象而设的。如下图(左边为正常显示,右边为IE6中侵吞现象的结果):

IE6的侵吞现象:两个设置了背景的div叠加在一起,哪怕上面那个div的宽度小于下面的那个div的宽度,上面的div也会将下面的div完全覆盖。由于我这里使用到了三个div,无法解决其侵吞现象,如果是两个div的话可以在代码加上 override:hiddren 即可,这里我让其在IE6中不显示进度背景只显示进度文字了(为了过测试部那一关)。这里我简单提一下,解决IE6中侵吞现象最直接的办法是将IE升级到7.0,微软于两年前已经宣布IE6正式淘汰,呼吁全世界的朋友使用更高版本的IE浏览器。

不知道大家发现了没有,我这个控件使用的是三个div叠加,从而实现项目进度的显示,下面两个div都设置了背景图片,最下面的div表示总宽度,中间的那个div的背景图片的宽度表示的是项目的进度,而最上面的div用文字显示项目进度(居中显示),这里我使用到了position:static;而不是让父div相对定位,子div绝对定位。这是有原因的,因为考虑到这个控件会嵌套使用在collGridView控件中,如果不设置为position:static;一旦出现滚动,则在谷歌浏览器中div会飘起来,出现如下现象:

这个控件的实现比较简单,难点事浏览器的兼容性问题。临渊羡鱼,不如退而结网,动手试一下吧!

MyPlanItem.cs源码:

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Web; using System.Web.UI; using System.ComponentModel; namespace PlanItem { public class MyPlanItem : Control { private string text; [Category("显示")] [Description("进度文本,保留两位小数")] [DefaultValue("0.00")] public string Text { get { if (text== null||text=="") { return "0.00"; } else { decimal num = Convert.ToDecimal(text); int index = num.ToString().IndexOf('.'); if (index < 1) { return Math.Round(num, 2).ToString() + ".00"; } else { int sum = (num.ToString().Length - index - 1); if (sum == 1) { return Math.Round(num, 2).ToString() + "0"; } else { return Math.Round(num, 2).ToString(); } } } } set { text= value; } } [Category("显示")] [Description("进度图片宽度")] [DefaultValue(0)] public UInt64 ImgWidth { get { return (Text =="0.00") ? 0 : Convert.ToUInt64(Convert.ToDouble(text)); } } [Category("显示")] [Description("背景图片路径")] public string BgImageDown { get { string s = (string)ViewState["ImageDownUrl"]; return s; } set { ViewState["ImageDownUrl"] = value; } } [Category("显示")] [Description("进度图片路径")] public string BgImageUp { get { string s = (string)ViewState["ImageUpUrl"]; return s; } set { ViewState["ImageUpUrl"] = value; } } private int divWidth; [Category("显示")] [Description("宽度")] [DefaultValue(100)] public int DivWidth { get { return divWidth; } set { divWidth = value; } } private int divHeight; [Category("显示")] [Description("高度")] [DefaultValue(30)] public int DivHeight { get { return divHeight; } set { divHeight = value; } } private string textColor; [Category("显示")] [Description("文本颜色")] [DefaultValue("black")] public string TextColor { get { return textColor; } set { textColor = value; } } private string bgColor; [Category("显示")] [Description("进度背景颜色")] [DefaultValue("blue")] public string BgColor { get { return bgColor; } set { bgColor = value; } } //将控件呈现到浏览器中显示 protected override void Render(HtmlTextWriter writer) { string div1 = "<div style='position:static;float:left;width:" + this.DivWidth + "px;height:" + this.DivHeight + "px;z-index:1;background-image: url(" + this.BgImageDown + ");_background-image: none;'/>"; writer.Write(div1); string div2 = "<div style='position:static;width:" + this.ImgWidth + "%;height:" + this.DivHeight + "px;z-index:2;float:left;background-image: url(" + this.BgImageUp + ");_background-image: none; '/>"; writer.Write(div2); string div3 = "<div style='position:static;margin-left:auto;margin-right:auto;width:" + DivWidth + "px;height:" + DivHeight + "px;line-height:" + DivHeight + "px;z-index:3; text-align:center; vertical-align:middle;color:" + TextColor + ";font-size:12px;'>"; writer.Write(div3); writer.Write(this.Text + "%"); writer.Write("</div>"); } } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值