建立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的問題控制項自己就解決了。