天天看點

自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)

 在項目中常常需要這樣的功能:把RadioButton控件放到GridView(容器)控件中,設定GroupName為固定的一個值的時候實作單選功能,但是當最終生成HTML頁面的時候,生成的Name會用 INamingContainer的規則自動生成不同的Name,就不能達到實作單選的效果。 (Name不唯一造成)

問題:如果在容器控件(如GridView)中的模闆列中放入Asp:RadioButton控件的時候,實作對清單中的RadioButton的單選,應該怎麼實作呢?

有人建議用用戶端控件,可以很好的實作綁定,但是背景隻能擷取到選中項的值,但有時候需要擷取未被選中的值,這樣的話用用戶端控件是不能達到需要的效果的。

那麼用伺服器端的控件該怎樣實作radiobutton的單選呢?

在網上查找了相關的解決方案,找到兩種解決方案,但都不是那麼令人滿意。

1.通過JavaScript腳本設定生成的不唯一Name的radiobutton實作單選的效果.

當然這種通過JavaScript能達到想要的效果,也能實作其功能,但是畢竟Javascript語言是不穩定的。(使用者禁用Javascript後發送到伺服器後可能會引起一些未知的問題)。

2.通過asp.net Ajax架構中的UpdatePanel,當使用者點選伺服器端的asp:radioButton後發送到伺服器端,執行伺服器端的代碼,讓其實作單選,這樣雖然能夠實作,但是這樣增加了用戶端和伺服器端資料的傳輸量。這是不推薦使用的。

思考:其實用實作單選功能,隻需要把radiobutton的Name屬性設定成一樣就可以(這才是關鍵),但是由于Asp.net機制,放到容器控件中的Template控件中後,生成後的RadioButton的Name就不是唯一的的(模闆行ID+radiobutton的ID)(如:Repeater1_ctl02_CustomerRadio1,Repeater1_ctl03_CustomerRadio1)

根據上面的思路:自己做一個自定義控件,實作像asp:radioButton那樣的功能,又能實作在容器中的Template中也能實作唯一的ID(設定相同的GroupName即可)。根據這個思路,終于實作了,下面是相關的代碼實作:請參考

自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)

 public class SingleCheckRadio : WebControl, IPostBackDataHandler

自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)

{

自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)

        public string GroupName

自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)

            get

自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)

                return ViewState["GroupName"] == null ? this.UniqueID : ViewState["GroupName"].ToString();

自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)

            }

自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)

            set

自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)

                ViewState["GroupName"] = value;

自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)

        }

自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)

        public string Text

自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)

                return ViewState["_text"] == null ? "" : ViewState["_text"].ToString();

自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)

                ViewState["_text"] = value;

自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)

        [DefaultValue(false)]

自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)

        public Boolean Checked

自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)

                object obj2 = this.ViewState["_checked"];

自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)

                return ((obj2 != null) && ((bool)obj2));

自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)

                ViewState["_checked"] = value;

自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)

        protected override void OnInit(EventArgs e)

自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)

            Page.RegisterRequiresPostBack(this);

自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)

            base.OnInit(e);

自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)

        protected override void Render(HtmlTextWriter writer)

自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)

            string output = string.Empty;

自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)

            if (Checked)

自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)

{//如果為true就設定為選擇,否則的話不選中。

自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)

                output = "<input id=/"" + this.ClientID + "/" type=/"radio/" name=/""+GroupName+"/" checked=/"checked/" value=/"" + this.ClientID + "/" />";

自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)

            else

自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)

                output = "<input id=/"" + this.ClientID + "/" type=/"radio/" name=/""+GroupName+"/"  value=/"" + this.ClientID + "/" />";

自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)

            if (!string.IsNullOrEmpty(Text))//如果使用者設定了Text屬性就增加一個label标簽(這裡類似于asp:radioButton的Text屬性的實作)

自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)

                output += "<label for=/"" + this.ClientID + "/">" + Text + "</label>";

自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)

            writer.Write(output);

自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)

        protected virtual bool LoadPostData(string postDataKey, NameValueCollection postCollection)

自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)

            bool flag = false;

自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)

            string str = postCollection[GroupName];

自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)

            bool flag2 = string.Equals(str, this.ClientID);//這裡是關鍵,比較使用者選擇的那個radiobutton,如果為true的話就把該Check屬性設定為true,否則為false.(後怎樣把使用者選擇的值儲存下來)

自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)

            flag = flag2 != this.Checked;

自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)

            this.Checked = flag2;//這

自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)

            return flag;

自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)

        IPostBackDataHandler 成員#region IPostBackDataHandler 成員

自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)

        bool IPostBackDataHandler.LoadPostData(string postDataKey, NameValueCollection postCollection)

自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)

            return LoadPostData(postDataKey, postCollection);

自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)

        public void RaisePostDataChangedEvent()

自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)

            return;

自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)

        #endregion        

自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)

    }

這樣編寫的自定義RadioButton控件,放到容器控件的Template中,生成的RadioButton的Name就是唯一的,都是使用者設定的GroupName的值。

下面是根據上面開發的自定義控件做的測試:aspx頁面如下:

 <asp:Repeater ID="Repeater1" runat="server">

        <ItemTemplate>

                <cc1:SingleCheckRadio ID="SingleCheckRadio" Text='<%#DataBinder.Eval(Container.DataItem,"Name") %>' GroupName="test" runat="server" />

        </ItemTemplate>

        </asp:Repeater>      

下面是背景.cs代碼,比較簡單就不多說了。(綁定資料并擷取選擇項radiobutton的text屬性。)

 public class Person

    {

        public string Name { get; set; }

        public int Age { get; set; }

    public partial class _Default : System.Web.UI.Page

        protected void Page_Load(object sender, EventArgs e)

        {

            if (!IsPostBack)

            {

                List<Person> Persons = new List<Person>();

                for (int i = 0; i < 10; i++)

                {

                    Person p = new Person();

                    p.Name = "Charles" + i;

                    p.Age = 21 + i;

                    Persons.Add(p);

                }

                Repeater1.DataSource = Persons;

                Repeater1.DataBind();

        protected void Button1_Click(object sender, EventArgs e)

            string str = String.Empty;

            foreach (RepeaterItem item in Repeater1.Items)

                CustomerRadioNamespace.SingleCheckRadio btn = item.FindControl("SingleCheckRadio") as CustomerRadioNamespace.SingleCheckRadio;

                if (btn.Checked == true)

                    str = btn.Text;

            Response.Write(str);

最後我們來看看生成的HTML源代碼:(可以看出生成出來的Name就是程式中設定的GroupName屬性且是唯一的,這樣就能實作單選功能了)

自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)
自定義伺服器端的RadioButton控件實作單選功能 (轉自部落格園Charles2008)

Code

 <div>

                <input id="Repeater1_ctl00_SingleCheckRadio" type="radio" name="test"  value="Repeater1_ctl00_SingleCheckRadio" /><label for="Repeater1_ctl00_SingleCheckRadio">Charles0</label>

                <input id="Repeater1_ctl01_SingleCheckRadio" type="radio" name="test"  value="Repeater1_ctl01_SingleCheckRadio" /><label for="Repeater1_ctl01_SingleCheckRadio">Charles1</label>

                <input id="Repeater1_ctl02_SingleCheckRadio" type="radio" name="test"  value="Repeater1_ctl02_SingleCheckRadio" /><label for="Repeater1_ctl02_SingleCheckRadio">Charles2</label>

                <input id="Repeater1_ctl03_SingleCheckRadio" type="radio" name="test"  value="Repeater1_ctl03_SingleCheckRadio" /><label for="Repeater1_ctl03_SingleCheckRadio">Charles3</label>

                <input id="Repeater1_ctl04_SingleCheckRadio" type="radio" name="test"  value="Repeater1_ctl04_SingleCheckRadio" /><label for="Repeater1_ctl04_SingleCheckRadio">Charles4</label>

                <input id="Repeater1_ctl05_SingleCheckRadio" type="radio" name="test"  value="Repeater1_ctl05_SingleCheckRadio" /><label for="Repeater1_ctl05_SingleCheckRadio">Charles5</label>

                <input id="Repeater1_ctl06_SingleCheckRadio" type="radio" name="test"  value="Repeater1_ctl06_SingleCheckRadio" /><label for="Repeater1_ctl06_SingleCheckRadio">Charles6</label>

                <input id="Repeater1_ctl07_SingleCheckRadio" type="radio" name="test"  value="Repeater1_ctl07_SingleCheckRadio" /><label for="Repeater1_ctl07_SingleCheckRadio">Charles7</label>

                <input id="Repeater1_ctl08_SingleCheckRadio" type="radio" name="test"  value="Repeater1_ctl08_SingleCheckRadio" /><label for="Repeater1_ctl08_SingleCheckRadio">Charles8</label>

                <input id="Repeater1_ctl09_SingleCheckRadio" type="radio" name="test"  value="Repeater1_ctl09_SingleCheckRadio" /><label for="Repeater1_ctl09_SingleCheckRadio">Charles9</label>

    </div>

這樣上面提到的效果實作了。而且相容該控件放到其他子控件,還是比較實用的。

注:另外還可以為該控件定義事件,通過使用者選擇觸發相應的伺服器事件。(上面的代碼未提供)

最後希望各位朋友們多多提出寶貴的意見,非常感謝。

繼續閱讀