locked
ViewState of custom radiobuttonlist not maintained. RRS feed

  • Question

  • User-1491118713 posted

    Hi there,

    I'm extending the RadioButtonList class to produce a Custom RadionButtonList. It works fine but it does not maintain the viewstate. My "ASP.NET Unleashed" book insructed me to implement the IPostBackDataHandler

    interface to maintain ViewState. I'm stuck on how to implement the methods of this interface for my RadioButtonList class. I'm using .Net version 1.1. My class is given below. Any ideas?Thanks

    public class CustomRadioButtonList : RadioButtonList , IPostBackDataHandler
    {
    bool need_raise;

    protected override void Render(HtmlTextWriter writer)

    {

    bool isTableLayout = (RepeatLayout == RepeatLayout.Table);

    if (isTableLayout)

    {

    int i = 0;

    foreach (ListItem listItem in Items)

    {

    writer.WriteBeginTag("input");

    writer.WriteAttribute("id", this.UniqueID + "_" + i);

    writer.WriteAttribute("type", "radio");

    writer.WriteAttribute("name", this.UniqueID);

    writer.WriteAttribute("value", listItem.Value, true);

    listItem.Attributes.Render(writer);

    writer.Write('>');

    writer.WriteEndTag("input");

    writer.WriteBeginTag("label");

    writer.WriteAttribute("for", this.UniqueID + "_" + i);

    listItem.Attributes.Render(writer);

    writer.Write('>');

    HttpUtility.HtmlEncode(listItem.Text, writer);

    writer.WriteEndTag("label");

    if (i < Items.Count - 1)

    writer.Write("<br />");

    i++;

    } //end foreach

    } //end if (isTableLayout)

    } //end render

     

     

    protected bool LoadPostData(string postDataKey, NameValueCollection postCollection)

    {

    string val = postCollection [postDataKey];

    ListItemCollection items = Items;

    int end = items.Count;

    int selected = SelectedIndex;

    for (int i = 0; i < end; i++) {

    ListItem item = items [i];

    if (item == null || val != item.Value)

    continue;

    if (i != selected) {

    SelectedIndex = i;

    need_raise = true;

    }

    return true;

    }

    return false;

    }

     

    protected void RaisePostDataChangedEvent()

    {

    if (need_raise)

    OnSelectedIndexChanged(EventArgs.Empty);

    }

    bool IPostBackDataHandler.LoadPostData(string postDataKey, NameValueCollection postCollection)

    {

    return LoadPostData(postDataKey, postCollection);

    }

    void IPostBackDataHandler.RaisePostDataChangedEvent()

    {

    RaisePostDataChangedEvent();

    }

    } //end CustomRadioButtonList class

     

    Thursday, July 27, 2006 6:43 PM

All replies

  • User2032526919 posted

    Hi,

    when you loop Items and render them, you also need to set the checked state .

    foreach (ListItem listItem in Items)
                    {

                        writer.WriteBeginTag("input");
                        writer.WriteAttribute("id", this.UniqueID + "_" + i);
                        writer.WriteAttribute("type", "radio");
                        writer.WriteAttribute("name", this.UniqueID);
                        writer.WriteAttribute("value", listItem.Value, true);
                       
    if (listItem.Selected)
                            writer.WriteAttribute("checked", "true");
                        listItem.Attributes.Render(writer);

    //....

    And what comes generally to rendering, your control doesn't know utilize Framework's mechanisms fully since you are basically bit hardcoding stuff (what comes to when tags are closed and when aren't). What if you'd render the control like this? Does this work for you?

    foreach (ListItem listItem in Items)
                    {

                        //INPUT
                        writer.AddAttribute("id", this.UniqueID + "_" + i);
                        writer.AddAttribute("type", "radio");
                        writer.AddAttribute("name", this.UniqueID);
                        writer.AddAttribute("value", listItem.Value, true);
                        if (listItem.Selected)
                            writer.AddAttribute("checked", "true");
                        listItem.Attributes.AddAttributes(writer);
                        writer.RenderBeginTag("input");
                       
                        writer.RenderEndTag();
                       
                   
                        //LABEL
                        writer.AddAttribute("for", this.UniqueID + "_" + i);
                        listItem.Attributes.AddAttributes(writer);
                        writer.RenderBeginTag( "label");
                       
                       
                        HttpUtility.HtmlEncode(listItem.Text, writer);
                        writer.RenderEndTag();

                        if (i < Items.Count - 1)
                            writer.Write(

                            "<br />");
                        i++;

                    }

    Friday, July 28, 2006 4:01 AM
  • User-1491118713 posted

    Thanks joteke for your help.

    I've tried your suggestion but it still won't retain it's selected value upon postback. I've read many resources and it appears that the trick is in implementing the IPostBackDataHandler interface properly. I need to know how to implement the LoadPostData and RaisePostDataChangedEvent methods for this to succeed. Any clues?

    Thanks,
    Ernest 

    Friday, July 28, 2006 5:14 AM
  • User2032526919 posted

    I took your code in the original post, did the changes I mentioned on previous post and it worked fine. I uploaded it on my site for you to check. All code is here below:

    URL to the Page: http://www.teemukeiski.net/samples/default6.aspx

    Code for the aspx:

    <%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default6.aspx.vb" Inherits="Default6" %>
    <%@ Register Namespace="Samples" TagPrefix="ss"   %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "
    http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    <html xmlns="http://www.w3.org/1999/xhtml" >
    <head runat="server">
        <title>Untitled Page</title>
    </head>
    <body>
        <form id="form1" runat="server">
     <ss:CustomRadioButtonList ID="rdblist1" runat="server" >
        <Items>
            <asp:ListItem Value="1" moi="moi">One</asp:ListItem>
            <asp:ListItem Value="2">Two</asp:ListItem>
            <asp:ListItem Value="3">Three</asp:ListItem>
        </Items>
     </ss:CustomRadioButtonList><asp:Button ID="Button1" runat="server" Text="Button" />
           
     
        </form>
      
    </body>
    </html>

    And code for the control

    using System;
    using System.Data;
    using System.Configuration;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Web.UI.HtmlControls;
    using System.Collections;
    using System.Collections.Specialized;


    /// <summary>
    /// Summary description for CustomRadioButtonList
    /// </summary>
    namespace Samples
    {
        public class CustomRadioButtonList : RadioButtonList, IPostBackDataHandler
        {
            bool need_raise;

            protected override void Render(HtmlTextWriter writer)
            {


                bool isTableLayout = (RepeatLayout == RepeatLayout.Table);


                if (isTableLayout)
                {


                    int i = 0;

                    foreach (ListItem listItem in Items)
                    {

                        //INPUT
                        writer.AddAttribute("id", this.UniqueID + "_" + i);
                        writer.AddAttribute("type", "radio");
                        writer.AddAttribute("name", this.UniqueID);
                        writer.AddAttribute("value", listItem.Value, true);
                        if (listItem.Selected)
                            writer.AddAttribute("checked", "true");
                        listItem.Attributes.AddAttributes(writer);
                        writer.RenderBeginTag("input");
                       
                        writer.RenderEndTag();
                       
                   
                        //LABEL
                        writer.AddAttribute("for", this.UniqueID + "_" + i);
                        listItem.Attributes.AddAttributes(writer);
                        writer.RenderBeginTag( "label");
                       
                       
                        HttpUtility.HtmlEncode(listItem.Text, writer);
                        writer.RenderEndTag();

                        if (i < Items.Count - 1)
                            writer.Write(

                            "<br />");
                        i++;

                    }

                    //end foreach
                }

                //end if (isTableLayout)
            }

            //end render

     

     

            protected bool LoadPostData(string postDataKey, NameValueCollection postCollection)
            {


                string val = postCollection[postDataKey];

                ListItemCollection items = Items;

                int end = items.Count;

                int selected = SelectedIndex;

                for (int i = 0; i < end; i++)
                {

                    ListItem item = items[i];

                    if (item == null || val != item.Value)

                        continue;

                    if (i != selected)
                    {
                        SelectedIndex = i;

                        need_raise =             true;
                    }


                    return true;
                }


                return false;
            }

     


            protected void RaisePostDataChangedEvent()
            {


                if (need_raise)
                    OnSelectedIndexChanged(

                    EventArgs.Empty);
            }


            bool IPostBackDataHandler.LoadPostData(string postDataKey, NameValueCollection postCollection)
            {


                return LoadPostData(postDataKey, postCollection);
            }


            void IPostBackDataHandler.RaisePostDataChangedEvent()
            {

                RaisePostDataChangedEvent();

            }

        }

        //end CustomRadioButtonList class
    }

    Friday, July 28, 2006 5:27 AM
  • User-1491118713 posted

    Sorry my friend, I'm not sure what was happening with my code. It worked for me only when I
    modified your new line of code as follows: 

    if (listItem.Selected)
    {
       writer.Write(
    " checked=\"true\"");
    }

    As you can see, you have used the "WriteAttribute" method in your code and it works for you and not me. This is strange. Do you have any explanation for this?

    Also I did not need to implement the "IPostBackDataHandler"  interface at all as I had wrongly thought.  Thanks again because you are the one that directed me in the right direction. I've been working on this since yesterday and my head was beginning to hurt.

    Regards,

    Ernest

     


     

    Friday, July 28, 2006 6:33 AM
  • User698394135 posted

    Hi joteke,

     I am working on a custom radio button list. In my case i have to group multiple radio button lists as a one radio button list. The way i found is to extend radio button list by adding a new property GroupName. Then i am overriding RenderItem method in my extended list class and using my GroupName for each radio button instead of using default group name. Every thing is working perfectly. The only issue i am getting is. Its not firing SelectedIndexChanged event and also not giving the SelectedValue on postback. I've tried to shadow  LoadPostData method. But pointer never goes to that line as far as i am using my own group name. If i keep the radio button(item)  id and name same then it works. I hope there should be way around this. Am i missing some thing or am i doing the wrong way? Please help i am stuck here. Even i tried your code as well. But if you change the group name then it did work either. Please help.

    Thanks in advance

     Protected Overrides Sub RenderItem(ByVal itemType As ListItemType, ByVal repeatIndex As Integer, ByVal repeatInfo As RepeatInfo, ByVal writer As HtmlTextWriter)

     

    writer.AddAttribute("name", GroupName)

    MyBase.RenderItem(itemType, repeatIndex, repeatInfo, writer)

    End Sub

     

    Tuesday, July 1, 2008 10:43 AM