Expiring Today—Celebrate National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

DropdownList items are cleared on postback

Posted on 2009-05-05
1
Medium Priority
?
903 Views
Last Modified: 2013-12-17
Hi,

I have created a custom dropdownlist that gets its values from a datasource (database).
My problem exists, when the page is posted back to itself - the items in the list are not persisted.

In my code, I can see why this happens - it is because I am not refilling the list automatically on postback (common practice).
However, how does the list refill itself.


     Q: Are the items in the list, supposed to be maintained across postback (must I call some methods like CreateChildControls)????
     Q: Do I have to rebind the list in the lists SelectedIndexChanged event handler (like you would with a GridView/DataList etc)????


This has been an issue for sometime now - to resolve it, I have just removed the !Page.IsPostBack condition (however, as this suggests, the code gets run when leaving pages etc which is inefficient - this is the main reason for it being there).

Hopefully, this is a 101 question - and I have missed this lesson early in my career.

Any help appreciated - thanks for your time.

Cheers.

using System;
using System.Web.UI.WebControls;
using System.Collections;
using System.ComponentModel;
 
namespace MWeb.Web.UI.WebControls
{
	/// <summary>
	/// Base Class for Extra Item <code>DropDownList</code>s
	/// </summary>
	abstract public class ExtraItemDropDownList : System.Web.UI.WebControls.DropDownList, IExtraItemList
    {
        #region Declarations
 
        #region Constants
 
        public const string DEFAULT_EXTRAITEM_TEXT = "None";
		public const string DEFAULT_EXTRAITEM_VALUE = "0";
 
		public const string DEFAULT_DATATEXT_FIELD = "DataTextField";
		public const string DEFAULT_DATAVALUE_FIELD = "DataValueField";
 
        public const int DEFAULT_CACHE_TIME_IN_MINS = 0;
 
		#endregion
 
        #region Member Variables
 
        //private bool _hasDataBind = false;
 
        #endregion
 
        #endregion
 
        #region Constructor
 
        public ExtraItemDropDownList():
                base()
		{
            this.Init += new EventHandler(this.Control_Init);
            this.Load += new EventHandler(this.Control_Load);
            this.PreRender += new EventHandler(this.Control_PreRender);
        }   
 
		#endregion
 
		#region Abstract and Virtuals
 
		protected abstract void Fill();
		public virtual void Refresh()
		{
            //clear all items.
            this.Items.Clear();
 
            //refill.
            this.Fill();
 
            //clean data.
            this.IsDirtyData = false;
		}
 
		#endregion
 
		#region Control Events
 
		///<summary>
		///Fills the DropDownList with items from the database on the first request
		///If PopulateOnLoad is true. Will populate itself on any request where
		///IsDirtyData is true.
        ///</summary>       
        private void Control_Init(object sender, System.EventArgs e)
        {
            if ((!Page.IsPostBack && this.PopulateOnLoad) || this.IsDirtyData)
            {
                this.Refresh(); ////////////////*************THIS IS NOT EXECUTED ON POSTBACK (AS EXPECTED) - BUT IT FILLS THE LIST!!!! QUESTION: Are the list items suppossed to be maintained across postback or am I supposed to rebind the list!
            }
        }
 
        private void Control_Load(object sender, System.EventArgs e)
        {
 
        }
 
        private void Control_PreRender(object sender, System.EventArgs e)
        {
            //disable if only single item.
            if (this.DisableSingleItem && this.Enabled)
            {//must already be enabled!
 
                this.Enabled = this.IncludeExtraItem ? (this.Items.Count > 2) : (this.Items.Count > 1);
            }
 
            //remove excluded values.
            if (!string.IsNullOrEmpty(this.ExcludedValueList))
            {
                string[] excludedValues = this.ExcludedValueList.Split(new char[] { ',', ' ' });
                foreach (string excludedValue in excludedValues)
                {
                    this.Items.Remove(this.Items.FindByValue(excludedValue));
                }
            }
        }
 
        public override void DataBind()
        {
            //bind data.
            //try
            //{
                //base.DataBind();
            //}
            //catch { ;} //TODO: THIS IS A HACK - a selected index exception was being thrown when I was filtering/refreshing lists. Couldnt find a solution so this was a temp fix.
 
            //create new list item
            if (this.IncludeExtraItem)
            {
                ListItem newItem = new ListItem();
                newItem.Text = this.ExtraItemText;
                newItem.Value = this.ExtraItemValue;
                newItem.Selected = false;
 
                //add list item to specified position
                if ((this.ExtraItemPosition == ExtraItemPosition.Top || this.ExtraItemPosition == ExtraItemPosition.Start))
                {
                    this.Items.Insert(0, newItem);
                }
                else if ((ExtraItemPosition == ExtraItemPosition.Bottom || this.ExtraItemPosition == ExtraItemPosition.End))
                {
                    this.Items.Add(newItem);
                }
            }
 
            // now select the default item
            if (this.InitialValue.ToString().Length > 0)
            {
                for (int i = 0; i < this.Items.Count;i++)
                {
                    ListItem li = this.Items[i];
                    if (li.Value == this.InitialValue)
                    {
                        if (!li.Selected)
                            li.Selected = true;
                        break;
                    }
                }
            }
 
            //set binded flag.
            //this._hasDataBind = true;
        }		
		
		#endregion
 
		#region Properties
 
        [Description("Sets the cache time in minutes for the list."), Category("Loading")]
        public int CacheTimeInMins
        {
            get
            {
                if (this.ViewState["CacheTimeInMins"] == null)
                {
                    this.ViewState["CacheTimeInMins"] = DEFAULT_CACHE_TIME_IN_MINS;
                }
                return (int)this.ViewState["CacheTimeInMins"];
            }
            set
            {
                this.ViewState["CacheTimeInMins"] = value;
            }
        }
 
        [Description("If you set this value to true before the Load event occurs then the control will reload its self."), Category("Loading")]
        public bool IsDirtyData
        {
            get
            {
                if (this.ViewState["IsDirtyData"] == null)
                {
                    this.ViewState["IsDirtyData"] = false;
                }
                return (bool)this.ViewState["IsDirtyData"];
            }
            set
            {
                this.ViewState["IsDirtyData"] = value;
            }
        }
 
        [Description("If you set this value to true then this control will pre-populate itself when it loads."), Category("Loading")]
        public bool PopulateOnLoad
        {
            get
            {
                if (this.ViewState["PopulateOnLoad"] == null)
                {
                    this.ViewState["PopulateOnLoad"] = true;
                }
                return (bool)this.ViewState["PopulateOnLoad"];
            }
            set
            {
                this.ViewState["PopulateOnLoad"] = value;
            }
        }
 
        [Description("The value of the initially selected item"), Category("Data")]
        public string InitialValue
        {
            get
            {
                if (this.ViewState["InitialValue"] == null)
                {
                    this.ViewState["InitialValue"] = string.Empty;
                }
                return (string)this.ViewState["InitialValue"];
            }
 
            set
            {
                this.ViewState["InitialValue"] = value;
            }
        }
 
		[Description("bool:  Include extra item in list?"),Category("Extra")]
		public bool IncludeExtraItem
		{
			get
			{
				if(this.ViewState["IncludeExtraItem"]==null)
				{
					this.ViewState["IncludeExtraItem"] = false;
				}
				return (bool) this.ViewState["IncludeExtraItem"];
			}
			set
			{
				this.ViewState["IncludeExtraItem"] = value;
			}
		}
 
		[Description("bool:  Should the extra item always been shown at the top of the list"),Category("Extra")]
		public ExtraItemPosition ExtraItemPosition
		{
			get
			{
				if(this.ViewState["ExtraItemPosition"]==null)
				{
					this.ViewState["ExtraItemPosition"] = ExtraItemPosition.Top;
				}
				return (ExtraItemPosition) this.ViewState["ExtraItemPosition"];
			}
			set
			{
				this.ViewState["ExtraItemPosition"] = value;
			}
		}
 
		[Description("string:  The text string displayed for extra item"),Category("Extra")]
		public string ExtraItemText
		{
			get
			{
				if(this.ViewState["ExtraItemText"]==null)
				{
					this.ViewState["ExtraItemText"] = string.Empty;
				}
				return (string) this.ViewState["ExtraItemText"];
			}
			set
			{
				this.ViewState["ExtraItemText"] = value;
			}
		}		
 
		[Description("string:  The value used for the extra item"),Category("Extra")]
		public string ExtraItemValue
		{
			get
			{
                if (this.ViewState["ExtraItemValue"] == null)
				{
                    this.ViewState["ExtraItemValue"] = string.Empty;
				}
                return (string)this.ViewState["ExtraItemValue"];
			}
			set
			{
                this.ViewState["ExtraItemValue"] = value;
			}
        }
 
        [Description("If you set this to true, the list will disabled when their is only one item in the list."), Category("Loading")]
        public bool DisableSingleItem
        {
            get
            {
                if (this.ViewState["DisableSingleItem"] == null)
                {
                    this.ViewState["DisableSingleItem"] = true;
                }
                return (bool)this.ViewState["DisableSingleItem"];
            }
            set
            {
                this.ViewState["DisableSingleItem"] = value;
            }
        }
 
        [Description("Excludes the values specified from list."), Category("Loading")]
        public string ExcludedValueList
        {
            get
            {
                return (string)this.ViewState["ExcludedValueList"];
            }
            set
            {
                this.ViewState["ExcludedValueList"] = value;
            }
        }
	
		#endregion
 
	}
}

Open in new window

0
Comment
Question by:smacca
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
1 Comment
 
LVL 6

Accepted Solution

by:
M3mph15 earned 2000 total points
ID: 24311008
Hi,

Any controls of list items that are created dynamically, so if your binding the Datasource to the DropDownList in your code behind then you will need to bind them at every postback.
0

Featured Post

On Demand Webinar: Networking for the Cloud Era

Ready to improve network connectivity? Watch this webinar to learn how SD-WANs and a one-click instant connect tool can boost provisions, deployment, and management of your cloud connection.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

More often than not, we developers are confronted with a need: a need to make some kind of magic happen via code. Whether it is for a client, for the boss, or for our own personal projects, the need must be satisfied. Most of the time, the Framework…
A long time ago (May 2011), I have written an article showing you how to create a DLL using Visual Studio 2005 to be hosted in SQL Server 2005. That was valid at that time and it is still valid if you are still using these versions. You can still re…
Visualize your data even better in Access queries. Given a date and a value, this lesson shows how to compare that value with the previous value, calculate the difference, and display a circle if the value is the same, an up triangle if it increased…
In this video, Percona Solution Engineer Rick Golba discuss how (and why) you implement high availability in a database environment. To discuss how Percona Consulting can help with your design and architecture needs for your database and infrastr…

719 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question