Home
Manage Your Code
Snippet: GroupDropDownList (C#)
Title: GroupDropDownList Language: C#
Description: DropDownList that implements the Optgroup Views: 259
Author: Kevin Isom Date Added: 11/2/2007
Copy Code  
1using System;
2using System.Collections;
3using System.ComponentModel;
4using System.Web;
5using System.Web.UI;
6using System.Web.UI.WebControls;
7
8namespace KevinIsom.Internet.Web.UI
9{
10	/// <summary>

11	/// Summary description for GroupDropDownList.

12	/// </summary>

13	[ToolboxData("<{0}:GroupDropDownList runat=server></{0}:GroupDropDownList>")]
14	public class GroupDropDownList : DropDownList
15	{
16		/// <summary>

17		/// The field in the datasource which provides values for groups

18		/// </summary>

19		[DefaultValue(""), Category("Data")]
20		public virtual string DataGroupField
21		{
22			get
23			{
24				object obj = ViewState["DataGroupField"];
25				if (obj != null)
26				{
27					return (string) obj;
28				}
29				return string.Empty;
30			}
31			set { ViewState["DataGroupField"] = value; }
32		}
33
34
35		/// <summary>

36		/// Render this control to the output parameter specified.

37		/// Based on the source code of the original DropDownList method

38		/// </summary>

39		/// <param name="writer">The <see cref="T:System.Web.UI.HtmlTextWriter"></see> that represents the output stream used to write content to a Web page.</param>

40		protected override void RenderContents(HtmlTextWriter writer)
41		{
42			ListItemCollection items = Items;
43			int itemCount = Items.Count;
44			string curGroup = String.Empty;
45			string itemGroup;
46			bool bSelected = false;
47
48			if (itemCount <= 0)
49			{
50				return;
51			}
52
53			for (int i = 0; i < itemCount; i++)
54			{
55				ListItem item = items[i];
56				itemGroup = (string) item.Attributes["DataGroupField"];
57				if (itemGroup != null && itemGroup != curGroup)
58				{
59					if (curGroup != String.Empty)
60					{
61						writer.WriteEndTag("optgroup");
62						writer.WriteLine();
63					}
64
65					curGroup = itemGroup;
66					writer.WriteBeginTag("optgroup");
67					writer.WriteAttribute("label", curGroup, true);
68					writer.Write('>');
69					writer.WriteLine();
70				}
71
72				writer.WriteBeginTag("option");
73				if (item.Selected)
74				{
75					if (bSelected)
76					{
77						throw new HttpException("Cant_Multiselect_In_DropDownList");
78					}
79					bSelected = true;
80					writer.WriteAttribute("selected", "selected", false);
81				}
82				writer.WriteAttribute("value", item.Value, true);
83				writer.Write('>');
84				HttpUtility.HtmlEncode(item.Text, writer);
85				writer.WriteEndTag("option");
86				writer.WriteLine();
87			}
88			if (curGroup != String.Empty)
89			{
90				writer.WriteEndTag("optgroup");
91				writer.WriteLine();
92			}
93		}
94
95		/// <summary>

96		/// Perform data binding logic that is associated with the control

97		/// </summary>

98		/// <param name="e">An EventArgs object that contains the event data</param>

99		protected override void OnDataBinding(EventArgs e)
100		{
101			// Call base method to bind data

102			base.OnDataBinding(e);
103
104			if (DataGroupField == String.Empty)
105			{
106				return;
107			}
108
109			// For each Item add the attribute "DataGroupField" with value from the datasource

110			IEnumerable dataSource = GetResolvedDataSource(DataSource, DataMember);
111			if (dataSource != null)
112			{
113				ListItemCollection items = Items;
114				int i = 0;
115
116				string groupField = DataGroupField;
117				foreach (object obj in dataSource)
118				{
119					string groupFieldValue = DataBinder.GetPropertyValue(obj, groupField, null);
120					ListItem item = items[i];
121					item.Attributes.Add("DataGroupField", groupFieldValue);
122					i++;
123				}
124			}
125		}
126
127		/// <summary>

128		/// This is copy of the internal ListControl method

129		/// </summary>

130		/// <param name="dataSource"></param>

131		/// <param name="dataMember"></param>

132		/// <returns></returns>

133		private IEnumerable GetResolvedDataSource(object dataSource, string dataMember)
134		{
135			if (dataSource != null)
136			{
137				IListSource source1 = dataSource as IListSource;
138				if (source1 != null)
139				{
140					IList list1 = source1.GetList();
141					if (!source1.ContainsListCollection)
142					{
143						return list1;
144					}
145					if ((list1 != null) && (list1 is ITypedList))
146					{
147						ITypedList list2 = (ITypedList) list1;
148						PropertyDescriptorCollection collection1 = list2.GetItemProperties(new PropertyDescriptor[0]);
149						if ((collection1 == null) || (collection1.Count == 0))
150						{
151							throw new HttpException("ListSource_Without_DataMembers");
152						}
153						PropertyDescriptor descriptor1 = null;
154						if ((dataMember == null) || (dataMember.Length == 0))
155						{
156							descriptor1 = collection1[0];
157						}
158						else
159						{
160							descriptor1 = collection1.Find(dataMember, true);
161						}
162						if (descriptor1 != null)
163						{
164							object obj1 = list1[0];
165							object obj2 = descriptor1.GetValue(obj1);
166							if ((obj2 != null) && (obj2 is IEnumerable))
167							{
168								return (IEnumerable) obj2;
169							}
170						}
171						throw new HttpException("ListSource_Missing_DataMember");
172					}
173				}
174				if (dataSource is IEnumerable)
175				{
176					return (IEnumerable) dataSource;
177				}
178			}
179			return null;
180		}
181	}
182}
Usage
Just set the DataGroupField for the OptGroup
Notes
found on some russian site...not sure where but damn useful