ListItems attributes in a DropDownList are lost on postback? ListItems attributes in a DropDownList are lost on postback? asp.net asp.net

ListItems attributes in a DropDownList are lost on postback?


I had the same problem and wanted to contribute this resource where the author created an inherited ListItem Consumer to persist attributes to ViewState. Hopefully it will save someone the time I wasted until I stumbled on it.

protected override object SaveViewState(){    // create object array for Item count + 1    object[] allStates = new object[this.Items.Count + 1];    // the +1 is to hold the base info    object baseState = base.SaveViewState();    allStates[0] = baseState;    Int32 i = 1;    // now loop through and save each Style attribute for the List    foreach (ListItem li in this.Items)    {        Int32 j = 0;        string[][] attributes = new string[li.Attributes.Count][];        foreach (string attribute in li.Attributes.Keys)        {            attributes[j++] = new string[] {attribute, li.Attributes[attribute]};        }        allStates[i++] = attributes;    }    return allStates;}protected override void LoadViewState(object savedState){    if (savedState != null)    {        object[] myState = (object[])savedState;        // restore base first        if (myState[0] != null)            base.LoadViewState(myState[0]);        Int32 i = 1;        foreach (ListItem li in this.Items)        {            // loop through and restore each style attribute            foreach (string[] attribute in (string[][])myState[i++])            {                li.Attributes[attribute[0]] = attribute[1];            }        }    }}


Thanks, Laramie. Just what I was looking for. It keeps the attributes perfectly.

To expand, below is a class file I created using Laramie's code to create a dropdownlist in VS2008. Create the class in the App_Code folder. After you create the class, use this line on the aspx page to register it:

<%@ Register TagPrefix="aspNewControls" Namespace="NewControls"%>

You can then put the control on your webform with this

<aspNewControls:NewDropDownList ID="ddlWhatever" runat="server">                                                </aspNewControls:NewDropDownList>

Ok, here's the class...

using System;using System.Collections.Generic;using System.ComponentModel;using System.Security.Permissions;using System.Linq;using System.Text;using System.Web;using System.Web.UI;using System.Web.UI.WebControls;namespace NewControls{  [DefaultProperty("Text")]  [ToolboxData("<{0}:ServerControl1 runat=server></{0}:ServerControl1>")]  public class NewDropDownList : DropDownList  {    [Bindable(true)]    [Category("Appearance")]    [DefaultValue("")]    [Localizable(true)]    protected override object SaveViewState()    {        // create object array for Item count + 1        object[] allStates = new object[this.Items.Count + 1];        // the +1 is to hold the base info        object baseState = base.SaveViewState();        allStates[0] = baseState;        Int32 i = 1;        // now loop through and save each Style attribute for the List        foreach (ListItem li in this.Items)        {            Int32 j = 0;            string[][] attributes = new string[li.Attributes.Count][];            foreach (string attribute in li.Attributes.Keys)            {                attributes[j++] = new string[] { attribute, li.Attributes[attribute] };            }            allStates[i++] = attributes;        }        return allStates;    }    protected override void LoadViewState(object savedState)    {        if (savedState != null)        {            object[] myState = (object[])savedState;            // restore base first            if (myState[0] != null)                base.LoadViewState(myState[0]);            Int32 i = 1;            foreach (ListItem li in this.Items)            {                // loop through and restore each style attribute                foreach (string[] attribute in (string[][])myState[i++])                {                    li.Attributes[attribute[0]] = attribute[1];                }            }        }    }  }}


Simple solution is to add the tooltip attributes in the pre-render event of the dropdown. Any changes to the state should be done at pre-render event.

sample code :

protected void drpBrand_PreRender(object sender, EventArgs e)        {            foreach (ListItem _listItem in drpBrand.Items)            {                _listItem.Attributes.Add("title", _listItem.Text);            }            drpBrand.Attributes.Add("onmouseover", "this.title=this.options[this.selectedIndex].title");        }