建立ASP.NET WEB自訂控制項——常式3

來源:互聯網
上載者:User
本系列文章中“常式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"),

        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控制項完成了,現在把編譯好的dll檔案找到並添加到工具箱中就可以拖放到頁面上了。本例實現的ViewState處理是一個示範,協助大家瞭解自己實現ViewState的方法,繼承的Control類已經實現了該處理,實際中只需要實現IPostBackDataHandler就可以了,ViewState的問題控制項自己就解決了。

控制項產生,但是當拖放到頁面上的時候它的設計時的顯示不太友好,只是一串文字。那麼如何像System.Web.UI.WebControls.TextBox那樣拖上去後顯示為一個輸入框呢?

下面我為讀者介紹改變顯示的方法。

首先在控制項項目中添加一個類檔案,命名為:Designer.cs。然後修改為如下代碼:

using System;

using System.Web.UI.Design;

using System.ComponentModel;

 

namespace Demo

{

    /// <summary>

    /// Designer 的摘要說明。

    /// </summary>

    public class DemoDesigner : ControlDesigner//繼承ControlDesigner類

    {

        private DemoTextBox demoTextBox;//聲明一個控制項類對象

 

        public override void Initialize(IComponent component)

        {

            this.demoTextBox = (DemoTextBox)component;

            base.Initialize(component);

        }

        //重載函數GetDesignTimeHtml()

        public override string GetDesignTimeHtml()

        {

            string _html = "";

            _html = "<Input type=\"text\" value="+this.demoTextBox.Text+">";

            return _html;

        }

    }

}

設計器完成了,但是還不能使控制項擁有設計時顯示,還要在控制項類的屬性代碼中添加Designer("Demo.DemoDesigner"),使控制項和設計器關聯。屬性代碼如下所示:

[DefaultProperty("Text"),

Designer("Demo.DemoDesigner"),

        ToolboxData("<{0}:DemoTextBox runat=server></{0}:DemoTextBox>")]

 

    現在這個控制項基本完成了,編譯後再拖到頁面上你會發現顯示的樣子與TextBox一樣了。

    以這個代碼為架構,讀者可以按自己的需要擴充控制項的屬性。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.