Solved

DropdownList items are cleared on postback

Posted on 2009-05-05
1
896 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
1 Comment
 
LVL 6

Accepted Solution

by:
M3mph15 earned 500 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

3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
List<PaisEntity> - show some 1 24
Expression Evaluater 3 25
Can't disable touch pad on Windows 10 computer 16 33
JSON  parse help 7 26
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
This article shows how to deploy dynamic backgrounds to computers depending on the aspect ratio of display
This Micro Tutorial will give you a basic overview how to record your screen with Microsoft Expression Encoder. This program is still free and open for the public to download. This will be demonstrated using Microsoft Expression Encoder 4.
This Micro Tutorial demonstrates using Microsoft Excel pivot tables, how to reverse engineer competitors' marketing strategies through backlinks.

777 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