建立ASP.NET WEB自定義控制元件(轉)

鴨脖發表於2013-12-16

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

相關文章