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}