2003-07-21 Gonzalo Paniagua Javier <gonzalo@ximian.com>
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / ListControl.cs
1 /**\r
2  * Namespace: System.Web.UI.WebControls\r
3  * Class:     ListControl\r
4  *\r
5  * Author:  Gaurav Vaish\r
6  * Maintainer: gvaish@iitk.ac.in\r
7  * Contact: <my_scripts2001@yahoo.com>, <gvaish@iitk.ac.in>\r
8  * Implementation: yes\r
9  * Status:  100%\r
10  *\r
11  * (C) Gaurav Vaish (2001)\r
12  */\r
13 \r
14 using System;\r
15 using System.Collections;\r
16 using System.ComponentModel;\r
17 using System.Web;\r
18 using System.Web.UI;\r
19 using System.Web.Util;\r
20 \r
21 namespace System.Web.UI.WebControls\r
22 {\r
23         [DefaultEvent("SelectedIndexChanged")]\r
24         [DefaultProperty("DataSource")]\r
25         //[Designer("??")]\r
26         //[DataBindingHandler("??")]\r
27         [ParseChildren(true, "Items")]\r
28         public abstract class ListControl: WebControl\r
29         {\r
30                 private static readonly object SelectedIndexChangedEvent = new object();\r
31 \r
32                 private object             dataSource;\r
33                 private ListItemCollection items;\r
34 \r
35                 private int cachedSelectedIndex = -1;\r
36 \r
37                 public ListControl(): base(HtmlTextWriterTag.Select)\r
38                 {\r
39                 }\r
40 \r
41                 public event EventHandler SelectedIndexChanged\r
42                 {\r
43                         add\r
44                         {\r
45                                 Events.AddHandler(SelectedIndexChangedEvent, value);\r
46                         }\r
47                         remove\r
48                         {\r
49                                 Events.RemoveHandler(SelectedIndexChangedEvent, value);\r
50                         }\r
51                 }\r
52 \r
53                 public virtual bool AutoPostBack\r
54                 {\r
55                         get\r
56                         {\r
57                                 object o = ViewState["AutoPostBack"];\r
58                                 if(o!=null)\r
59                                         return (bool)o;\r
60                                 return false;\r
61                         }\r
62                         set\r
63                         {\r
64                                 ViewState["AutoPostBack"] = value;\r
65                         }\r
66                 }\r
67 \r
68                 public virtual string DataMember\r
69                 {\r
70                         get\r
71                         {\r
72                                 object o = ViewState["DataMember"];\r
73                                 if(o!=null)\r
74                                         return (string)o;\r
75                                 return String.Empty;\r
76                         }\r
77                         set\r
78                         {\r
79                                 ViewState["DataMember"] = value;\r
80                         }\r
81                 }\r
82 \r
83                 public virtual object DataSource\r
84                 {\r
85                         get\r
86                         {\r
87                                 return dataSource;\r
88                         }\r
89                         set\r
90                         {\r
91                                 if(value != null)\r
92                                 {\r
93                                         if(value is IListSource || value is IEnumerable)\r
94                                         {\r
95                                                 dataSource = value;\r
96                                                 return;\r
97                                         }\r
98                                 }\r
99                                 throw new ArgumentException(HttpRuntime.FormatResourceString(ID, "Invalid DataSource Type"));\r
100                         }\r
101                 }\r
102 \r
103                 public virtual string DataTextField\r
104                 {\r
105                         get\r
106                         {\r
107                                 object o = ViewState["DataTextField"];\r
108                                 if(o!=null)\r
109                                         return (string)o;\r
110                                 return String.Empty;\r
111                         }\r
112                         set\r
113                         {\r
114                                 ViewState["DataTextField"] = value;\r
115                         }\r
116                 }\r
117 \r
118                 public virtual string DataTextFormatString\r
119                 {\r
120                         get\r
121                         {\r
122                                 object o = ViewState["DataTextFormatString"];\r
123                                 if(o!=null)\r
124                                         return (string)o;\r
125                                 return String.Empty;\r
126                         }\r
127                         set\r
128                         {\r
129                                 ViewState["DataTextFormatString"] = value;\r
130                         }\r
131                 }\r
132 \r
133                 public virtual string DataValueField\r
134                 {\r
135                         get\r
136                         {\r
137                                 object o = ViewState["DataValueField"];\r
138                                 if(o!=null)\r
139                                         return (string)o;\r
140                                 return String.Empty;\r
141                         }\r
142                         set\r
143                         {\r
144                                 ViewState["DataValueField"] = value;\r
145                         }\r
146                 }\r
147 \r
148                 public virtual ListItemCollection Items\r
149                 {\r
150                         get\r
151                         {\r
152                                 if(items==null)\r
153                                 {\r
154                                         items = new ListItemCollection();\r
155                                         if(IsTrackingViewState)\r
156                                         {\r
157                                                 items.TrackViewState();\r
158                                         }\r
159                                 }\r
160                                 return items;\r
161                         }\r
162                 }\r
163 \r
164                 public virtual int SelectedIndex\r
165                 {\r
166                         get {\r
167                                 ListItemCollection items = Items;\r
168                                 int last = items.Count;\r
169                                 for (int i = 0; i < last; i++) {\r
170                                         if (items [i].Selected)\r
171                                                 return i;\r
172                                 }\r
173                                 return -1;\r
174                         }\r
175                         set {\r
176                                 if (value < -1 || value > Items.Count)\r
177                                         throw new ArgumentOutOfRangeException ();\r
178 \r
179                                 ClearSelection ();\r
180                                 if (value != -1)\r
181                                         Items [value].Selected = true;\r
182                         }\r
183                 }\r
184 \r
185                 public virtual ListItem SelectedItem\r
186                 {\r
187                         get\r
188                         {\r
189                                 int idx = SelectedIndex;\r
190                                 if (idx < 0)\r
191                                         return null;\r
192 \r
193                                 return Items [idx];\r
194                         }\r
195                 }\r
196 \r
197 #if NET_1_1\r
198                 public virtual string SelectedValue {\r
199                         get {\r
200                                 int idx = SelectedIndex;\r
201                                 if (idx == -1)\r
202                                         return "";\r
203 \r
204                                 return Items [idx].Value;\r
205                         }\r
206 \r
207                         set {\r
208                                 ListItem item = null;\r
209 \r
210                                 if (value != null) {\r
211                                         item = Items.FindByValue (value);\r
212                                         if (item == null)\r
213                                                 throw new ArgumentOutOfRangeException (value);\r
214                                 }\r
215 \r
216                                 ClearSelection ();\r
217                                 if (item != null)\r
218                                         item.Selected = true;\r
219                         }\r
220                 }\r
221 #endif\r
222                 \r
223                 internal virtual ArrayList SelectedIndices\r
224                 {\r
225                         get\r
226                         {\r
227                                 ArrayList si = new ArrayList();\r
228                                 for(int i=0; i < Items.Count; i++)\r
229                                 {\r
230                                         if(Items[i].Selected)\r
231                                                 si.Add(i);\r
232                                 }\r
233                                 return si;\r
234                         }\r
235                 }\r
236 \r
237                 internal void Select(ArrayList indices)\r
238                 {\r
239                         ClearSelection();\r
240                         foreach(object intObj in indices)\r
241                         {\r
242                                 int index = (int)intObj;\r
243                                 if(index >= 0 && index < Items.Count)\r
244                                         Items[index].Selected = true;\r
245                         }\r
246                 }\r
247 \r
248                 public virtual void ClearSelection()\r
249                 {\r
250                         for(int i=0; i < Items.Count; i++)\r
251                         {\r
252                                 Items[i].Selected = false;\r
253                         }\r
254                 }\r
255 \r
256                 protected override void LoadViewState(object savedState)\r
257                 {\r
258                         //Order: BaseClass, Items (Collection), Indices\r
259                         if(savedState != null && savedState is Triplet)\r
260                         {\r
261                                 Triplet state = (Triplet)savedState;\r
262                                 base.LoadViewState(state.First);\r
263                                 Items.LoadViewState(state.Second);\r
264                                 object indices = state.Third;\r
265                                 if(indices != null)\r
266                                 {\r
267                                         Select((ArrayList)indices);\r
268                                 }\r
269                         }\r
270                 }\r
271 \r
272                 protected override void OnDataBinding(EventArgs e)\r
273                 {\r
274                         base.OnDataBinding(e);\r
275                         IEnumerable ds = DataSourceHelper.GetResolvedDataSource (DataSource, DataMember);\r
276 \r
277                         if(ds != null) {\r
278                                 string dtf = DataTextField;\r
279                                 string dvf = DataValueField;\r
280                                 string dtfs = DataTextFormatString;\r
281                                 if (dtfs.Length == 0)\r
282                                         dtfs = "{0}";\r
283 \r
284                                 Items.Clear();\r
285 \r
286                                 bool useProperties = (dtf.Length > 0 && dvf.Length > 0);\r
287 \r
288                                 foreach (object current in ds) {\r
289                                         ListItem li = new ListItem();\r
290                                         if (!useProperties){\r
291                                                 li.Text  = String.Format (dtfs, current);\r
292                                                 li.Value = current.ToString ();\r
293                                                 Items.Add (li);\r
294                                                 continue;\r
295                                         }\r
296 \r
297                                         object o;\r
298                                         if (dtf.Length > 0) {\r
299                                                 o = DataBinder.GetPropertyValue (current, dtf, null);\r
300                                                 li.Text = o.ToString ();\r
301                                         }\r
302 \r
303                                         if (dvf.Length > 0) {\r
304                                                 o = DataBinder.GetPropertyValue (current, dvf, null);\r
305                                                 li.Value = o.ToString ();\r
306                                         }\r
307 \r
308                                         Items.Add(li);\r
309                                 }\r
310                         }\r
311 \r
312                         if (cachedSelectedIndex != -1) {\r
313                                 SelectedIndex = cachedSelectedIndex;\r
314                                 cachedSelectedIndex = -1;\r
315                         }\r
316                 }\r
317 \r
318                 protected virtual void OnSelectedIndexChanged(EventArgs e)\r
319                 {\r
320                         if(Events!=null)\r
321                                 {\r
322                                         EventHandler eh = (EventHandler)(Events[SelectedIndexChangedEvent]);\r
323                                         if(eh!=null)\r
324                                                 eh(this, e);\r
325                                 }\r
326                 }\r
327 \r
328                 protected override void OnPreRender (EventArgs e)\r
329                 {\r
330                         base.OnPreRender(e);\r
331                 }\r
332 \r
333                 protected override object SaveViewState()\r
334                 {\r
335                         //Order: BaseClass, Items (Collection), Indices\r
336                         object vs = base.SaveViewState();\r
337                         object itemSvs = Items.SaveViewState();\r
338                         object indices = null;\r
339                         if (SaveSelectedIndicesViewState)\r
340                                 indices = SelectedIndices;\r
341 \r
342                         if (vs != null || itemSvs != null || indices != null)\r
343                                 return new Triplet(vs, itemSvs, indices);\r
344 \r
345                         return null;\r
346                 }\r
347 \r
348                 protected override void TrackViewState()\r
349                 {\r
350                         base.TrackViewState();\r
351                         Items.TrackViewState();\r
352                 }\r
353 \r
354                 private bool SaveSelectedIndicesViewState {\r
355                         get {\r
356                                 if (Events[SelectedIndexChangedEvent] == null && Enabled && Visible) {\r
357                                         Type t = GetType();\r
358                                         // If I am a derivative, let it take of storing the selected indices.\r
359                                         if (t == typeof(DropDownList) || t == typeof(ListBox) ||\r
360                                             t == typeof(CheckBoxList) || t == typeof(RadioButtonList))\r
361                                                 return false;\r
362                                 }\r
363                                 return true;\r
364                         }\r
365                 }\r
366         }\r
367 }\r