创建ASP.NET WEB自定义控件——例程1
WEB自定义控件编程是ASP.NET编程里面比较难的一部分,尤其是复杂的控件需要用到平常不常用的一些技术技巧。
下面根据一些我自己的实践经验,向读者介绍一下这方面的技术。
简单的继承控件:ConfirmButton
我们在用ASP.NET编写应用程序的时候,经常需要在按钮提交的时候弹出一个[OK][Cancel]的确认框,以防止用户在操作的时候误提交。实现这个功能传统的方法是在代码页的Page_Load事件里添加按钮的Attributes,但是每个按钮都要添加一遍比较麻烦。下面我们来自己制作一个有这样功能的按钮解决这个问题。
(例程采用C#语言)
1.新建项目
首先打开Visual Studio.net,建立一个新的Web控件库项目,取名TestLib。在解决方案资源管理器里会有一个标识为WebCustomControl1.cs的源代码文件,将其改名为ConfirmButton.cs。
2.编辑代码
打开ConfirmButton.cs源文件,将类名“WebCustomControl1”改为“ConfirmButton”;将类继承自“System.Web.UI.WebControls.WebControl”改为“System.Web.UI.WebControls.Button”;
将代码“[DefaultProperty("Text"),
ToolboxData("<{0}:WebCustomControl1 runat=server></{0}:WebCustomControl1>")]”
改为“[DefaultProperty("Text"),
ToolboxData("<{0}:ConfirmButton runat=server></{0}:ConfirmButton>")]”,这样使得aspx页面显示的该控件xml代码标识显示“<cc1:ConfirmButton …> …</cc1: ConfirmButton>”。
下面进一步修改代码,删除原有代码:
private string text;
[Bindable(true),
Category("Appearance"),
DefaultValue("")]
public string Text
{
get
{
return text;
}
set
{
text = value;
}
}
添加新代码(用于设置在弹出的确认框中显示的信息):
private string _confirmMessage = "Is OK?";
[Bindable(true),
Category("Appearance"),
DefaultValue("Is OK?")]
public string ConfirmMessage
{
get
{
return _confirmMessage;
}
set
{
_confirmMessage = value;
}
}
最后将
protected override void Render(HtmlTextWriter output)
{
output.Write(Text);
}
改为protected override void Render(HtmlTextWriter output)
{
base.Attributes.Add("OnClick","return confirm('"+this._confirmMessage+"');");
base.Render(output);
}
3.添加在工具箱中显示的图标
选择菜单[项目]/[添加新项],在弹出的对话框中选择创建“位图文件”并将文件名改为“ConfirmButton”(很重要,位图文件名必需和类名一致)。然后在“解决方案资源管理器”中选中该位图文件,并在属性设置框中将“生成操作”的值设置为“嵌入的资源”。
好了,编译一下吧,一切OK了。剩下的事,就是把编译好的dll文件找到并添加到工具箱中,在以后的WEB应用程序中就可以用了。
创建ASP.NET WEB自定义控件——例程2
本文通过一段完整的代码向读者介绍复合自定义控件的制作,包括:自定义属性、事件处理、控件间数据传递等方面的技术。
作者在http://damao.0538.org有一些控件和代码,并在更新中,有兴趣的读者可以去下载。
以下是一个登陆框的代码,包括:用户名输入TextBox、密码输入TextBox、提交Button、重置Button以及承载以上四项的Panel。控件类名为LoginCtrl。
(例程使用C#)
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;
using System.Drawing;
namespace TestLib
{
[DefaultProperty("BackColor"),
ToolboxData("<{0}:LoginCtrl runat=server></{0}:LoginCtrl>")]
public class LoginCtrl : System.Web.UI.WebControls.WebControl
{
private Color _fontColor = Color.Black;//声明字体颜色变量
private Color _backColor = Color.White;//声明控件背景变量
首先声明要在复合控件中使用的子控件。
private Label lblUserName = new Label();//显示“用户名”的Label控件
private Label lblPassWord = new Label();//显示“密码”的Label控件
private TextBox txtUserName = new TextBox();//用户名输入的TextBox控件
private TextBox txtPassWord = new TextBox();//密码输入的TextBox控件
private Button submitButton = new Button();//提交Button控件
private Button clearButton = new Button();//重置Button控件
private System.Web.UI.WebControls.Panel pnlFrame = new System.Web.UI.WebControls.Panel();//承载其它控件的容器Panel控件
当然要在符合控件中使用的事件一定要声明的,它们会出现在属性框的事件栏里。
public event EventHandler SubmitOnClick;//声明自定义控件LoginCtrl的提交事件
public event EventHandler ClearOnClick;//声明自定义控件LoginCtrl的重置事件
public LoginCtrl()
{
刚刚声明的子控件和事件要在这里进行初始化处理。
//初始化控件的属性
this.lblUserName.Text = "用户名:";
this.lblPassWord.Text = "密 码:";
this.txtPassWord.TextMode = System.Web.UI.WebControls.TextBoxMode.Password;
this.pnlFrame.Width = 240;
this.pnlFrame.Height = 120;
this.pnlFrame.BackColor = Color.Empty;
//添加提交按钮点击事件
submitButton.Text = "确定";
submitButton.Click += new EventHandler(this.SubmitBtn_Click);
//添加重置按钮点击事件
clearButton.Text = "重置";
clearButton.Click += new EventHandler(this.ClearBtn_Click);
//将声明的各子控件添加到LoginCtrl中
this.Controls.Add(this.submitButton);
this.Controls.Add(this.clearButton);
this.Controls.Add(this.txtUserName);
this.Controls.Add(this.txtPassWord);
this.Controls.Add(this.lblUserName);
this.Controls.Add(this.lblPassWord);
this.Controls.Add(this.pnlFrame);
}
根据自己的需要添加或重载符合控件的公共属性
//字体颜色属性
[Bindable(false),
Category("Appearance"),
DefaultValue("")]
public override Color ForeColor
{
get
{
return this._fontColor;
}
set
{
this._fontColor = value;
}
}
//控件背景属性
[Bindable(false),
Category("Appearance"),
DefaultValue("")]
public override Color BackColor
{
get
{
return this._backColor;
}
set
{
this._backColor = value;
}
}
//用户名属性
[Bindable(false),
Category("Appearance"),
DefaultValue("")]
public string UserName
{
get
{
return this.txtUserName.Text;
}
set
{
this.txtUserName.Text = value;
}
}
//密码属性
[Bindable(false),
Category("Appearance"),
DefaultValue(""), Browsable(false)]
public string PassWord
{
get
{
return this.txtPassWord.Text;
}
set
{
this.txtPassWord.Text = value;
}
}
//控件宽度属性
[Bindable(false),
Category("Appearance"),
DefaultValue("")]
建ASP.NET WEB自定义控件——例程3
建ASP.NET WEB自定义控件——例程3
本系列文章中“例程1”和“例程2”讲述了利用Visual Studio.NET2003中已有的WEB自定义控件,通过继承或复合一些简单控件生成自己需要的自定义控件。这样的控件制作比较简单,但是它的执行效率相对要低一些,所以如果我们不继承已有的控件那么这个控件该怎么做呢?
下面作者通过实例向大家讲述这种自写控件的编程方法。
(例程使用C#)
本例程实现一个TextBox,该TextBox对于输入的字符串进行检验,将半角单引号替换为全角单引号(半角单引号导致数据库错误)。
控件首先要继承所有控件的基类:System.Web.UI.Control,实现两个接口:IStateManager(实现ViewState),IPostBackDataHandler(处理回发数据),然后可以仿照System.Web.UI.WebControls.TextBox编写一些常用的属性和方法。因篇幅限制,本例只实现Text属性。
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;
namespace Demo
{
/// <summary>
/// WebCustomControl1 的摘要说明。
/// </summary>
像前两个例子一样,先处理一下控件设计时属性。
[DefaultProperty("Text"),
Designer("Demo.DemoDesigner"),
ToolboxData("<{0}:DemoTextBox runat=server></{0}:DemoTextBox>")]
public class DemoTextBox : System.Web.UI.Control,IStateManager,IPostBackDataHandler
{
private StateBag _state;
private bool _marked;
下面就是我们要实现的属性:Text
[Bindable(true),
Category("Appearance"),
DefaultValue("")]
public string Text
{
get
{
string _text = (string) ViewState["Text"];
return _text==null?"":_text;
}
set
{
string text = "";
text = value;
text = text.Replace("'","’");
ViewState["Text"] = text;
}
}
为了能实现视图状态就必须实现IStateManager接口
object IStateManager.SaveViewState()
{
object _stateState = null;
if( _state != null )
_stateState = ((IStateManager)_state).SaveViewState();
if ( _stateState == null )
return null;
return _stateState;
}
void IStateManager.TrackViewState()
{
_marked = true;
if( _state != null )
((IStateManager)_state).TrackViewState();
}
void IStateManager.LoadViewState( object state )
{
if( state != null )
{
object _newState = (object)state;
((IStateManager)ViewState).LoadViewState( _newState );
}
}
bool IStateManager.IsTrackingViewState
{
get
{
return _marked;
}
}
internal new StateBag ViewState //注意,这里覆盖基类的ViewState属性
{
get
{
if( _state == null )
{
_state = new StateBag( true );
if( ((IStateManager)this).IsTrackingViewState )
((IStateManager)_state).TrackViewState();
}
return _state;
}
}
下面把控件的表现输出到页面,其实System.Web.UI.WebControls.TextBox也是重新包装了Input而已。
protected override void Render(HtmlTextWriter output)
{
string strOutput = "<Input name=\""+this.ClientID+"\" type=\"text\" value=\""+this.Text+"\">";
output.Write(strOutput);
}
#region IPostBackDataHandler 成员
public void RaisePostDataChangedEvent()
{
// TODO: 添加 DemoTextBox.RaisePostDataChangedEvent 实现
}
下面的方法很重要,把回发的数据保存。
public bool LoadPostData(string postDataKey, System.Collections.Specialized.NameValueCollection postCollection)
{
// TODO: 添加 DemoTextBox.LoadPostData 实现
string presentValue = this.Text;
string postedValue = postCollection[postDataKey];
if (!presentValue.Equals(postedValue))//如果回发数据不等于原有数据
{
this.Text = postedValue;
return true;
}
return false;
}
#endregion
}
}
好了,一个自己写的TextBox控件完成了。如果读者觉得自己实现ViewState麻烦,那么可以把继承的基类由System.Web.UI.Control改为System.Web.UI.WebControls.WebControl,这样只需要实现IPostBackDataHandler就可以了,ViewState的问题控件自己就解决了。