ASP.NET组件编程step by step

ASP.NET组件编程step by step

 

       事先声明:本文只适合对组件编程感兴趣的初、中级程序员,如果您对组件编程很牛X了,您可以略过此地。欢迎各位指导并发表意见和建议。

 

       事情的起因(纯粹为了增强文章的趣味性)

       我对电影一向不感冒,最近网上、电视上《十面埋伏》的广告和评论扑天盖地,加上张艺谋在中央电视台还搞了个晚会,专门宣传该影片,不免也蠢蠢欲动起来。我没有去电影院看电影的习惯,所以如果网上有就到网上看了。恰巧一日QQ聊天时,一个群里的会员发了个链接,说是可以下载《十面埋伏》,我试了一下,果然,速度还不错,有70K的速度,100M的东东很快就下完了(是不是我特别容易满足?)。可是效果不太好,颜色基本上没有了,像过去的黑白电影,还不清晰,不过免费的东西就这样了,将就一下啦。

 

       看了十几分钟,终于看不下去了,都是打打杀杀,三个主要人物都出场了,没有帅哥也没有美女,看得我头晕眼花直打盹。为了防止见周公,鼠标在我手里不安份起来,我用的播放器是为了看这个电影刚下载的realplay10的,这可是头一次见,以前都用8.0的,界面没新版的好看(虽然我并不觉得好看,笨笨的),所以想看看有些什么功能,最后,我打开了下面的界面:

 

     

       咦,我一看那个蓝色的背景挺有趣的啊,“名称”标签和文件框组合成一个复合控件,背景颜色还可以变化,有点创意,效果也不错,那我也做一个啊,哈哈,有时候一个想法就是这样无意中产生的。

 

       基础知识

       ASP.net中做一个复合控件不是很难了,但是如果是刚刚接触的话,可能还是需要指点一下方向,所以不妨在这里啰嗦一下,高手们莫怪。

       Javascript:当今最流行的客户端脚本语言,如果要做出特效来他最有能耐。

       CSS:级联样式表,用于设置元素的样式。

       DHTML:动态HTML,和浏览器交互会用到。

       System.Web.UI.WebControls.WebControl:在ASP.NET中自定义控件的基类,我们可能会重写他的一些方法,常用的有:

       CreateChildControls():给予控件创建内定子控件的机会,预设情况OnPreRender()方法会调用此方法要求该控件创建其子控件,别一种情况则是由FindControl()方法调用。

       OnPreRender():触发PreRender事件,在绘制控件之前发生。

       Render():绘制控件。

       AddAttributesToRender():向标签中添加HTML样式或属性。

       另外,还有一个方法:EnsureChildControls()该方法用于确定服务器控控件是否包含子控件,如果不包含,则创建子控件,在设计阶段起作用。

    其他的慢慢去看啦,这几个是我们的例子中会用到的。

 

    最终效果

    先看看效果,这样心中才有明确的目标。

   

    没有任何鼠标动作            鼠标移到控件上              鼠标移出后还原

 

    怎么样?效果挺炫吧?(我在自夸呢)

   

    跟我一步一步来

       现在,请听我的指令:喜欢这个效果的站左边,不喜欢这个效果或者极为不屑的站右边。好了,右边的朋友请关闭您的浏览器继续您喜欢的网上之旅,左边的朋友请跟我来:

 

1、  我们先完成效果部分,也就是编写javascript脚本。我的方法是写一个HTML文件,试验脚本的正确性:

<HTML>

<HEAD>

<META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0">

<TITLE></TITLE>

 

<script language=javascript>

var OldColor;

function mouseover(ctrl,color)

{

        OldColor = ctrl.style.backgroundColor;

        ctrl.style.color = "#ffffff";

        ctrl.style.backgroundColor = color;

       

}

function mouseout(ctrl)

{

        ctrl.style.backgroundColor = OldColor;

        ctrl.style.color = "#000000";

}

</script>

</HEAD>

<BODY>

 

<table  border="0" style="font-size:9pt" onmouseover="mouseover(this,'#ff0044')" onmouseout="mouseout(this)">

<tr >

        <td><span>姓名:</span></td><td><input name="_ctl2" type="text" /></td>

</tr>

</table>

 

</BODY>

</HTML>

新建一个文本文件,将这段代码复制过去,然后将文件的扩展名改为.html,用IE打开,是不是看到了想要的效果?

 

2、  前期工作准备完成了,接下来打开VS.NET IDE,新建一个项目,选择Visual C#项目(别问我要VB.net的代码,我不会),在右边列表中选择“WEB控件库”,输入项目名称:LabelTextBox

3、  把自动生成的代码删除,只留下一个类的框架,像下面这样(命名空间自定):

using System;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.ComponentModel;

using System.Drawing;

 

namespace LzhTextBpx

{      

    public class LabelTextbox : System.Web.UI.WebControls.WebControl

{

}

}

 

4、  上面看到的效果其实是一个一行两列的表格,我们把表格的border属性设成0,所以看不出来了,其中左边单元格放标签,右边单元格放文本框,所以,我们要用代码生成这个表格。用到的类有:

a)         Table:表示表格

b)        TableRow:表示表格行

c)        TableCell:表示表格中的单元格

注意:一个表格可以有多个表格行,一个表格行中可以放置多个单元格

生成代码如下:

//定义一个表对象

            Table t = new Table();

            //添加一行

            TableRow tr = new TableRow();

            //添加两个单元格

            TableCell tc1 = new TableCell();

            TableCell tc2 = new TableCell();

            //将控件添加到Controls集中.

            tc1.Controls.Add(label);

            tc2.Controls.Add(textBox);

            tr.Controls.Add(tc1);

            tr.Controls.Add(tc2);

            t.Controls.Add(tr);

this.Controls.Add(t);  

我们还要响应表格的鼠标移入移出事件,背景色的变化就是在这里触发的,下面的代码完成此事:

//添加鼠标事件

        t.Attributes.Add("onmouseover","mouseover(this,'" + "#" + R + G + B + "')");

t.Attributes.Add("onmouseout","mouseout(this)");

Attributes表示表格的属性集,Add()方法用于添加一个新的属性。

顺便把表格中的字体也设置一下:

//添加样式,用来控制字体

t.Style.Add("font-size","10pt");

看到上面的R、G、B三个变量了吗?这三个变量是某种颜色的十六进制的字符串表示。使用如下的方法对颜色进行分解:

//以下将颜色值转化成十六进制表示

        string R,G,B;

        R = (Convert.ToInt32(this._backgroundColor.R)).ToString("X");

        G = (Convert.ToInt32(this._backgroundColor.G)).ToString("X");

B = (Convert.ToInt32(this._backgroundColor.B)).ToString("X");

其中_backgroundColor是自定义属性。

 

这一步的全部代码如下:

private void CreateControls()//创建控件以及设置控件的相关属性

        {

            //以下将颜色值转化成十六进制表示

            string R,G,B;

            R = (Convert.ToInt32(this._backgroundColor.R)).ToString("X");

            G = (Convert.ToInt32(this._backgroundColor.G)).ToString("X");

            B = (Convert.ToInt32(this._backgroundColor.B)).ToString("X");

            //定义一个表对象

            Table t = new Table();

 

            //添加鼠标事件

            t.Attributes.Add("onmouseover","ltmouseover(this,'" + "#" + R + G + B + "')");

            t.Attributes.Add("onmouseout","ltmouseout(this)");

 

            //添加样式,用来控制字体

            t.Style.Add("font-size","10pt");

 

            //添加一行

            TableRow tr = new TableRow();

            //添加两个单元格

            TableCell tc1 = new TableCell();

            TableCell tc2 = new TableCell();

 

            //将控件添加到Controls集中.

            tc1.Controls.Add(label);

            tc2.Controls.Add(textBox);

            tr.Controls.Add(tc1);

            tr.Controls.Add(tc2);

 

            t.Controls.Add(tr);

 

            this.Controls.Add(t);          

        }

 

5、  本控件向外提供了三个属性,backgroundColor 表示鼠标移入控件的背景颜色,labelString 为标签内文本,textString 为文本框内容。定义如下:

private Label label = new Label();//创建一个标签

        private TextBox textBox = new TextBox();//创建一个文本框

private Color _backgroundColor;//鼠标移入的背景颜色

public Color backgroundColor

        {

            get

            {

                if(_backgroundColor == Color.Empty)

                    return Color.Blue;

                return _backgroundColor;

            }

            set

            {

                _backgroundColor = value;

            }

        }

 

        public string labelString

        {

            get

            {

                return label.Text;

            }

            set

            {

                label.Text = value;

            }

        }

 

        public string textString

        {

            get

            {

                return textBox.Text;

            }

            set

            {

                textBox.Text = value;

            }

        }

 

6、  这一步需要重写 CreateChildControls() 方法,该方法会自动被调用,用来生成子控件。

protected override void CreateChildControls()

        {

            this.EnsureChildControls();//如果子控件没有创建,则创建

            base.CreateChildControls ();//调用方法

            CreateControls();

}

 

7、  将第一步的脚本存到一个常量中:

private const string MOUSE_SCRIPT = //用来触发鼠标事件的脚本

            "<script language=javascript>/n" +

            "var OldColor;/n" +

            "function ltmouseover(ctrl,color)/n" + //当鼠标移入时,调用该方法,ctrl为表格,color为要改变的颜色值

            "{/n" +

                "OldColor = ctrl.style.backgroundColor;/n" + //记录下原来的文档背景颜色

                "ctrl.style.color = '#ffffff';/n" +//将字体颜色改为白色

                "ctrl.style.backgroundColor = color;/n" + //更改表格背景颜色

            "}/n" +

            "function ltmouseout(ctrl)/n" + //鼠标移出时调用 ,参数同上

            "{/n" +

                "ctrl.style.backgroundColor = OldColor;/n" + //还原背景颜色

                "ctrl.style.color = '#000000';" + //将字体颜色还原成黑色

            "}/n" +

        "</script>/n";

 

重写OnPreRender()方法将该脚本输出到浏览器,考虑到同一页面可能会有多个该控件的情况,此时并不需要每个控件都生成一段脚本,而是所有控件共享这段脚本,所以,我们要用Page.IsClientScriptBlockRegistered()判断该脚本是否已经输出,如果输出,就不需要再次输出了。

protected override void OnPreRender(EventArgs e)

        {

            //将脚本输出到页面中.

            if(!Page.IsClientScriptBlockRegistered("mousescript")) //防止重复输出.

            {

                Page.RegisterClientScriptBlock("mousescript",MOUSE_SCRIPT);

            }

            base.OnPreRender (e);

}

   

    控件的使用

    使用控件显然比创建控件简单得多,下面讲一下该控件的使用方法(适合初学者):

    将该项目编译后,会生成一个叫LabelTextbox.dll的程序集。

   

    1、创建一个测试项目,打开工具箱,点击右键,选择“添加/移除项”,如下图:

   

   

       2、弹出“自定义工具箱”,选择“.net FramWork组件”选项卡,点击“浏览”,在LabelTextBox工程目录下找到“LabelTextbox.dll”程序集,如图:

      

 

       3、确定后,在工具箱中出现该控件的图标,如下图:

      

 

       4、直接将该控件拖到WEB窗体就能使用了。

 

       本程序调试环境:Windows2000 ServerMS.NET2003

posted on 2004年07月23日 3:45 PM

反馈

# 回复:有点小BUG //以下将颜色值转化成十六进制表示
string R,G,B;
R = (Convert.ToInt32(this._backgroundColor.R)).ToString("X");
G = (Convert.ToInt32(this._backgroundColor.G)).ToString("X");
B = (Convert.ToInt32(this._backgroundColor.B)).ToString("X");
if(R.Length==1)R = "0" + R;
if(G.Length==1)G = "0" + G;
if(B.Length==1)B = "0" + B;
2004-08-21 9:52 PM | 良良(feky)的藏经阁

# 回复:ASP.NET组件编程step by step

谢谢这位朋友.
2004-08-22 8:27 AM | lizanhong

# 回复:ASP.NET组件编程step by step

thank ,good
2004-08-24 10:52 AM | AoioA

# 回复:ASP.NET组件编程step by step

好实例。你是个写书的好料子,应该出书
2004-08-24 1:45 PM | darkit

# 回复:ASP.NET组件编程step by step

thank you !
2004-08-24 2:13 PM | yscfdavid

# 回复:ASP.NET组件编程step by step

thnks a lot ,it is good
2004-08-24 2:52 PM | yhy

# 回复:ASP.NET组件编程step by step

要是大家都像你就好了 呵呵
2004-08-24 3:10 PM | faintboy

# 回复:ASP.NET组件编程step by step

直接将该控件拖到WEB窗体就能使用了。
??
工具是灰色的,用不了
2004-08-24 3:11 PM | S.F.Lau

# 回复:ASP.NET组件编程step by step

有个问题,这里面的子控件,如TextBox,不能接受运行时赋值,该怎么解决?
2004-08-24 3:12 PM | insect

# 回复:ASP.NET组件编程step by step

多謝
2004-08-24 3:23 PM | neu_leaf

# 回复:ASP.NET组件编程step by step

一下子看到那么多人留言才知道这篇文章被放到了CSDN首页,有些网友调试不能通过,现在我把整个工程的源代码都上传了,不过如果要下载要先注册才行,只好麻烦一下大家了.

下载地址:http://www.codesky.net/show.asp?id=2886
2004-08-24 3:23 PM | lizanhong

# 回复:ASP.NET组件编程step by step

这样就行了
/// <summary>
/// 获取或设置文本框内容
/// </summary>
public string textString
{
get
{
this.EnsureChildControls();
return textBox.Text;
}
set
{
this.EnsureChildControls();
textBox.Text = value;

}
}
2004-08-24 3:50 PM | insect

# 回复:ASP.NET组件编程step by step

有个提议,把事件改为当文本框获得焦点事触发,然后失去焦点时还原背景色。怎么实现失去焦点这个事件呢?
2004-08-24 3:57 PM | insect

# 回复:ASP.NET组件编程step by step

哈哈,我根据你的代码做了写修改,


using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;
using System.Drawing;


namespace Insect.WebControls.LabelTextBoxs
{
/// <summary>
/// LabelTextBox 的摘要说明。
/// </summary>
[DefaultProperty("Text"),
ToolboxData("<{0}:LabelTextBox width='100px' runat=server></{0}:LabelTextBox>")]
public class LabelTextBox : System.Web.UI.WebControls.WebControl , INamingContainer
{
private Label label = new Label();//创建一个标签

private TextBox textBox = new TextBox();//创建一个文本框

private Color _backgroundColor;//鼠标移入的背景颜色

private int _fontSize;//字体大小


/// <summary>
/// 获取或设置高亮背景色
/// </summary>
public Color backgroundColor
{
get
{
this.EnsureChildControls();
if(_backgroundColor == Color.Empty)
return Color.Blue;
return _backgroundColor;
}
set
{
this.EnsureChildControls();
_backgroundColor = value;
}
}



public string labelString
{
get
{
this.EnsureChildControls();
return label.Text;
}
set
{
this.EnsureChildControls();
label.Text = value;
}
}


/// <summary>
/// 获取或设置文本框内容
/// </summary>
public string textString
{
get
{
this.EnsureChildControls();
return textBox.Text;
}
set
{
this.EnsureChildControls();
textBox.Text = value;

}
}


/// <summary>
/// 获取或设置单元格字体大小,单位为pt
/// </summary>
public int fontSize
{
get
{
this.EnsureChildControls();
return _fontSize;
}
set
{
this.EnsureChildControls();
_fontSize = value;
}
}



/// <summary>
/// 获取或设置文本框的CssClass
/// </summary>
public string textBoxCssClass
{
get
{
this.EnsureChildControls();
return this.textBox.CssClass;
}
set
{
this.EnsureChildControls();
this.textBox.CssClass=value;
}
}


/// <summary>
/// 用来触发鼠标事件的脚本
/// </summary>
private const string MOUSE_SCRIPT =
"<script language=javascript>/n" +
"var OldColor;/n" +
"function ltmouseover(ctrl,color)/n" + //当鼠标移入时,调用该方法,ctrl为表格,color为要改变的颜色值
"{/n" +
"OldColor = ctrl.style.backgroundColor;/n" + //记录下原来的文档背景颜色
"ctrl.style.color = '#ffffff';/n" +//将字体颜色改为白色
"ctrl.style.backgroundColor = color;/n" + //更改表格背景颜色
"}/n" +
"function ltmouseout(ctrl)/n" + //鼠标移出时调用 ,参数同上
"{/n" +
"ctrl.style.backgroundColor = OldColor;/n" + //还原背景颜色
"ctrl.style.color = '#000000';" + //将字体颜色还原成黑色
"}/n" +
"</script>/n";


private const string MOUSE_SCRIPT_REGESTIGER_KEY=//注册到客户端页面的关键字
"Insect.WebControls.LabelTextBox.mousescript";



/// <summary>
/// //创建控件以及设置控件的相关属性
/// </summary>
private void CreateControls()
{

//定义一个表对象

Table t = new Table();


//添加样式,用来控制字体
if(this._fontSize==0)
t.Style.Add("font-size","10pt");
else
t.Style.Add("font-size",""+this._fontSize+"pt");



//添加一行
TableRow tr = new TableRow();

//添加两个单元格
TableCell tc1 = new TableCell();
TableCell tc2 = new TableCell();


//将控件添加到Controls集中.
tc1.Controls.Add(label);
tc2.Controls.Add(textBox);
tr.Controls.Add(tc1);
tr.Controls.Add(tc2);

t.Controls.Add(tr);


this.Controls.Add(t);



}



/// <summary>
/// 重写CreateChildControls()
/// </summary>
protected override void CreateChildControls()
{

this.EnsureChildControls();//如果子控件没有创建,则创建

this.CreateControls();

base.CreateChildControls ();//调用基类方法



}


/// <summary>
/// 重写OnPreRender()
/// </summary>
/// <param name="e"></param>
protected override void OnPreRender(EventArgs e)
{

//添加鼠标事件
for(int i=0;i<Controls.Count;i++)
{
if(Controls[i] is Table)
{

//以下将颜色值转化成十六进制表示
string R,G,B;

R = (Convert.ToInt32(this._backgroundColor.R)).ToString("X");

G = (Convert.ToInt32(this._backgroundColor.G)).ToString("X");

B = (Convert.ToInt32(this._backgroundColor.B)).ToString("X");

if(R.Length==1)
R = "0" + R;
if(G.Length==1)
G = "0" + G;
if(B.Length==1)
B = "0" + B;


Table t=(Table)Controls[i];

t.Attributes.Add("id",t.ClientID);

this.textBox.Attributes["onfocus"]="ltmouseover("+t.ClientID+",'" + "#" + R + G + B + "')";
this.textBox.Attributes["onblur"]="ltmouseout("+t.ClientID+")";

}
}


//将脚本输出到页面中.
if(!Page.IsClientScriptBlockRegistered(MOUSE_SCRIPT_REGESTIGER_KEY)) //防止重复输出.
{
Page.RegisterClientScriptBlock(MOUSE_SCRIPT_REGESTIGER_KEY,MOUSE_SCRIPT);
}
base.OnPreRender (e);
}
}
}
2004-08-24 4:49 PM | insect

# 回复:ASP.NET组件编程step by step

ToolboxData("<{0}:LabelTextBox width='100px' runat=server ></{0}:LabelTextBox>")]
改为
ToolboxData("<{0}:LabelTextBox width='100px' runat=server textString=''></{0}:LabelTextBox>")]
2004-08-24 5:00 PM | insect

# 回复:ASP.NET组件编程step by step

insect :
呵,思维挺严谨的。不错。
2004-08-24 5:16 PM | lizanhong

# 回复:ASP.NET组件编程step by step

谢谢
2004-08-24 6:03 PM | dondon

# 回复:ASP.NET组件编程step by step

这本书有电子版吗?有的话请发一份给我,感谢

mydotnet@163.com
2004-08-24 8:42 PM | 笨猫.NET

# 回复:ASP.NET组件编程step by step

感谢~~~~~
期望能在看高楼长的新作~~
2004-08-25 8:56 AM | 出了好多错误

# 回复:ASP.NET组件编程step by step

这本书有电子版吗?有的话请发一份给我,感谢

xiao-maolover@163.com

谢谢楼主..收藏了..
2004-08-25 9:27 AM | matrix

# ASP.NET组件编程step by step

Ping Back来自:blog.csdn.net
2004-08-25 11:01 AM | kanshangren

# ASP.NET分页组件学与用——使用篇

Ping Back来自:blog.csdn.net
2004-08-25 5:40 PM | 椰子林

# ASP.NET分页组件学与用——使用篇

Ping Back来自:blog.csdn.net
2004-08-25 7:52 PM | GZ's TOBY

# ASP.NET组件编程step by step

Ping Back来自:blog.csdn.net
2004-08-26 1:07 AM | 南山居

# 回复:ASP.NET组件编程step by step

留个记号!
2004-08-26 9:21 AM | xjm

# 回复:ASP.NET组件编程step by step

上回我回复的-------------------
# 回复:有点小BUG
//以下将颜色值转化成十六进制表示
string R,G,B;
R = (Convert.ToInt32(this._backgroundColor.R)).ToString("X");
G = (Convert.ToInt32(this._backgroundColor.G)).ToString("X");
B = (Convert.ToInt32(this._backgroundColor.B)).ToString("X");
if(R.Length==1)R = "0" + R;
if(G.Length==1)G = "0" + G;
if(B.Length==1)B = "0" + B;
-----------------------------------

其实以下代码可以换成一行代码就搞定--------------------
//以下将颜色值转化成十六进制表示
string R,G,B;

R = (Convert.ToInt32(this._backgroundColor.R)).ToString("X");

G = (Convert.ToInt32(this._backgroundColor.G)).ToString("X");

B = (Convert.ToInt32(this._backgroundColor.B)).ToString("X");

if(R.Length==1)
R = "0" + R;
if(G.Length==1)
G = "0" + G;
if(B.Length==1)
B = "0" + B;


Table t=(Table)Controls[i];

t.Attributes.Add("id",t.ClientID);

this.textBox.Attributes["onfocus"]="ltmouseover("+t.ClientID+",'" + "#" + R + G + B + "')";
--------改成-------------------------
this.textBox.Attributes.Add("onmouseover","ltmouseover(this,'" + ColorTranslator.ToHtml(this._mouseoverColor) + "')");
简单吧!无意中发现的!因为我想想MS不可能把一个颜色转换要自己写得这么麻烦。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值