您的位置:首页 > 编程语言 > ASP

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

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

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

名称

说明

备注

ScollGridView

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

运用于各种统计页面

PlanItem

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

运用于进度的表示

StatusItem

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

BiasItem

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

用于表示偏差方向

今天先讲一下PlanItem控件吧

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

关于兼容性问题可以参考:Portal项目的Hack/article/7596629.html

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>");
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: