2005-09-01 Chris Toshok <toshok@ximian.com>
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / ListControl.cs
1 //
2 // System.Web.UI.WebControls.ListControl.cs
3 //
4 // Authors:
5 //      Jackson Harper (jackson@ximian.com)
6 //
7 // (C) 2005 Novell, Inc (http://www.novell.com)
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28
29 using System;
30 using System.Drawing;
31 using System.Web.Util;
32 using System.Collections;
33 using System.Globalization;
34 using System.ComponentModel;
35 using System.Collections.Specialized;
36
37 namespace System.Web.UI.WebControls {
38
39         [DataBindingHandler("System.Web.UI.Design.WebControls.ListControlDataBindingHandler, " + Consts.AssemblySystem_Design)]
40         [DefaultEventAttribute ("SelectedIndexChanged")]
41 #if !NET_2_0
42         [DefaultPropertyAttribute ("DataSource")]
43 #endif
44         [Designer("System.Web.UI.Design.WebControls.ListControlDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
45 #if NET_2_0
46         [ControlValueProperty ("SelectedValue", null)]
47         [ParseChildrenAttribute (true, "Items", ChildControlType = typeof (Control))]
48 #else
49         [ParseChildrenAttribute (true, "Items")]
50 #endif  
51         public abstract class ListControl :
52 #if NET_2_0
53         DataBoundControl, IEditableTextControl, ITextControl
54 #else           
55         WebControl
56 #endif
57         {
58
59                 private static readonly object SelectedIndexChangedEvent = new object ();
60 #if NET_2_0
61                 private static readonly object TextChangedEvent = new object ();
62 #endif
63
64                 private object data_source;
65                 private ListItemCollection items;
66                 
67                 public ListControl () : base (HtmlTextWriterTag.Select)
68                 {
69                 }
70
71 #if NET_2_0
72                 [DefaultValue (false)]
73                 [Themeable (false)]
74                 [MonoTODO]
75                 [WebSysDescription ("")]
76                 [WebCategory ("Behavior")]
77                 public virtual bool AppendDataBoundItems
78                 {
79                         get {
80                                 return ViewState.GetBool ("AppendDataBoundItems", false);
81                         }
82                         set {
83                                 ViewState ["AppendDataBoundItems"] = value;
84                         }
85                 }
86 #endif          
87                 
88 #if NET_2_0
89                 [Themeable (false)]
90 #endif
91                 [DefaultValue(false)]
92                 [WebSysDescription ("")]
93                 [WebCategory ("Behavior")]
94                 public virtual bool AutoPostBack {
95                         get { return ViewState.GetBool ("AutoPostBack", false); }
96                         set { ViewState ["AutoPostBack"] = value; }
97                 }
98
99 #if ONLY_1_1
100                 [DefaultValue("")]
101                 [WebSysDescription ("")]
102                 [WebCategory ("Data")]
103                 public virtual string DataMember {
104                         get { return ViewState.GetString ("DataMember", String.Empty); }
105                         set { ViewState ["DataMember"] = value; }
106                 }
107
108                 [Bindable(true)]
109                 [DefaultValue(null)]
110                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
111                 [WebSysDescription ("")]
112                 [WebCategory ("Data")]
113                 public virtual object DataSource {
114                         get { return data_source; }
115                         set { data_source = value; }
116                 }
117 #endif          
118
119 #if NET_2_0
120                 [Themeable (false)]
121 #endif          
122                 [DefaultValue("")]
123                 [WebSysDescription ("")]
124                 [WebCategory ("Data")]
125                 public virtual string DataTextField {
126                         get { return ViewState.GetString ("DataTextField", String.Empty); }
127                         set { ViewState ["DataTextField"] = value; }
128                 }
129
130 #if NET_2_0
131                 [Themeable (false)]
132 #endif          
133                 [DefaultValue("")]
134                 [WebSysDescription ("")]
135                 [WebCategory ("Data")]
136                 public virtual string DataTextFormatString {
137                         get { return ViewState.GetString ("DataTextFormatString", String.Empty); }
138                         set { ViewState ["DataTextFormatString"] = value; }
139                 }
140
141 #if NET_2_0
142                 [Themeable (false)]
143 #endif          
144                 [DefaultValue("")]
145                 [WebSysDescription ("")]
146                 [WebCategory ("Data")]
147                 public virtual string DataValueField {
148                         get { return ViewState.GetString ("DataValueField", String.Empty); }
149                         set { ViewState ["DataValueField"] = value; }
150                 }
151
152 #if NET_2_0
153                 [Editor ("System.Web.UI.Design.WebControls.ListItemsCollectionEditor," + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
154 #endif          
155                 [DefaultValue(null)]
156                 [MergableProperty(false)]
157                 [PersistenceMode(PersistenceMode.InnerDefaultProperty)]
158                 [WebSysDescription ("")]
159                 [WebCategory ("Misc")]
160                 public virtual ListItemCollection Items {
161                         get {
162                                 if (items == null)
163                                         items = new ListItemCollection ();
164                                 return items;
165                         }
166                 }
167
168                 // I can't find this info stored in the viewstate anywhere
169                 // so it must be calculated on the fly.
170                 [Bindable(true)]
171                 [Browsable(false)]
172                 [DefaultValue(0)]
173                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
174 #if NET_2_0
175                 [Themeable (false)]
176 #endif          
177                 [WebSysDescription ("")]
178                 [WebCategory ("Misc")]
179                 public virtual int SelectedIndex {
180                         get {
181                                 if (items == null)
182                                         return -1;
183                                 for (int i = 0; i < items.Count; i++) {
184                                         if (items [i].Selected)
185                                                 return i;
186                                 }
187                                 return -1;
188                         }
189                         set {
190                                 ClearSelection ();
191                                 if (value == -1 || items == null)
192                                         return;
193                                 if (value < 0 || value >= Items.Count)
194                                         throw new ArgumentOutOfRangeException ("value");
195                                 items [value].Selected = true;
196                         }
197                 }
198
199                 [Browsable(false)]
200                 [DefaultValue(null)]
201                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
202                 [WebSysDescription ("")]
203                 [WebCategory ("Misc")]
204                 public virtual ListItem SelectedItem {
205                         get {
206                                 int si = SelectedIndex;
207                                 if (si == -1)
208                                         return null;
209                                 return Items [si];
210                         }
211                 }
212
213 #if NET_2_0
214                 [Bindable(true, BindingDirection.TwoWay)]
215                 [Themeable (false)]
216 #else           
217                 [Bindable(true)]
218 #endif          
219                 [Browsable(false)]
220                 [DefaultValue("")]
221                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
222                 [WebSysDescription ("")]
223                 [WebCategory ("Misc")]
224                 public virtual string SelectedValue {
225                         get {
226                                 int si = SelectedIndex;
227                                 if (si == -1)
228                                         return String.Empty;
229                                 return Items [si].Value;
230                         }
231                         set {
232                                 ClearSelection ();
233                                 for (int i = 0; i < Items.Count; i++) {
234                                         if (Items [i].Value == value)
235                                                 Items [i].Selected = true;
236                                 }
237                         }
238                 }
239
240 #if NET_2_0
241                 [Themeable (false)]
242                 [DefaultValue ("")]
243                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
244                 [Browsable (false)]
245                 [MonoTODO]
246                 [WebSysDescription ("")]
247                 [WebCategoryAttribute ("Behavior")]
248                 public virtual string Text 
249                 {
250                         get {
251                                 throw new NotImplementedException ();
252                         }
253                         set {
254                                 throw new NotImplementedException ();
255                         }
256                 }
257
258                 protected virtual new HtmlTextWriterTag TagKey
259                 {
260                         get {
261                                 return HtmlTextWriterTag.Select;
262                         }
263                 }
264
265                 protected override void AddAttributesToRender (HtmlTextWriter w)
266                 {
267                         base.AddAttributesToRender (w);
268                 }
269                 
270 #endif          
271
272                 public virtual void ClearSelection ()
273                 {
274                         if (items == null)
275                                 return;
276
277                         int count = Items.Count;
278                         for (int i = 0; i<count; i++)
279                                 items [i].Selected = false;
280                 }
281
282 #if NET_2_0
283                 [MonoTODO]
284                 protected internal override void LoadControlState (object savedState)
285                 {
286                         throw new NotImplementedException ();
287                 }
288 #endif          
289
290                 protected override void OnDataBinding (EventArgs e)
291                 {
292                         base.OnDataBinding (e);
293
294                         IEnumerable list = DataSourceResolver.ResolveDataSource (DataSource, DataMember);
295                         if (list == null)
296                                 return;
297
298                         Items.Clear ();
299
300                         foreach (object container in list) {
301                                 string text;
302                                 string value;
303
304                                 if (DataTextField != String.Empty) {
305                                         text = DataBinder.Eval (container,
306                                                         DataTextField).ToString ();
307                                 } else {
308                                         text = String.Empty;
309                                 }
310
311                                 if (DataValueField != String.Empty) {
312                                         value = DataBinder.Eval (container,
313                                                         DataValueField).ToString ();
314                                 } else {
315                                         value = text;
316                                 }
317
318                                 if (text == String.Empty) {
319                                         if (value != String.Empty)
320                                                 text = value;
321                                 } else if (DataTextFormatString != String.Empty) {
322                                         // Dont apply the format string if we don't actually 
323                                         // have a textfield
324                                         text = String.Format (DataTextFormatString, text);
325                                 }
326
327                                 ListItem item = new ListItem (text, value);
328                                 Items.Add (item);
329                         }
330                 }
331
332 #if NET_2_0
333                 [MonoTODO]
334                 protected internal override void OnInit (EventArgs e)
335                 {
336                         throw new NotImplementedException ();
337                 }
338 #endif          
339
340 #if NET_2_0
341                 protected internal
342 #else           
343                 protected
344 #endif          
345                 override void OnPreRender (EventArgs e)
346                 {
347                         base.OnPreRender (e);
348                 }
349
350 #if NET_2_0
351                 [MonoTODO]
352                 protected virtual void OnTextChanged (EventArgs e)
353                 {
354                         throw new NotImplementedException ();
355                 }
356
357                 [MonoTODO]
358                 protected internal override void PerformDataBinding (IEnumerable dataSource)
359                 {
360                         throw new NotImplementedException ();
361                 }
362
363                 [MonoTODO]
364                 protected override void PerformSelect ()
365                 {
366                         throw new NotImplementedException ();
367                 }
368
369                 [MonoTODO]
370                 protected internal override void RenderContents (HtmlTextWriter w)
371                 {
372                         throw new NotImplementedException ();
373                 }
374
375                 [MonoTODO]
376                 protected internal override object SaveControlState ()
377                 {
378                         throw new NotImplementedException ();
379                 }
380 #endif          
381
382                 protected override object SaveViewState ()
383                 {
384                         object first = null;
385                         object second = null;
386                         ArrayList selected = null;
387
388                         first = base.SaveViewState ();
389
390                         IStateManager manager = items as IStateManager;
391                         if (manager != null)
392                                 second = manager.SaveViewState ();
393
394                         if (items != null) {
395                                 selected = new ArrayList ();
396                                 int count = Items.Count;
397                                 for (int i = 0; i < count; i++) {
398                                         if (items [i].Selected)
399                                                 selected.Add (i);
400                                 }
401                         }
402
403                         if (first == null && second == null && selected == null)
404                                 return null;
405
406                         return new Triplet (first, second, selected);
407                 }
408
409                 protected override void LoadViewState (object savedState)
410                 {
411                         object first = null;
412                         object second = null;
413                         ArrayList indices = null;
414
415                         Triplet triplet = savedState as Triplet;
416                         if (triplet != null) {
417                                 first = triplet.First;
418                                 second = triplet.Second;
419                                 indices = triplet.Third as ArrayList;
420                         }
421
422                         base.LoadViewState (first);
423
424                         if (second != null) {
425                                 IStateManager manager = Items as IStateManager;
426                                 manager.LoadViewState (second);
427                         }
428
429                         if (indices != null) {
430                                 foreach (int index in indices)
431                                         Items [index].Selected = true;
432                         }
433                 }
434
435 #if NET_2_0
436                 [MonoTODO]
437                 protected void SetPostDataSelection (int selectedIndex)
438                 {
439                         throw new NotImplementedException ();
440                 }
441 #endif          
442
443                 protected override void TrackViewState ()
444                 {
445                         base.TrackViewState ();
446                         IStateManager manager = items as IStateManager;
447                         if (manager != null)
448                                 manager.TrackViewState ();
449                 }
450
451                 protected virtual void OnSelectedIndexChanged (EventArgs e)
452                 {
453                         EventHandler handler = (EventHandler) Events [SelectedIndexChangedEvent];
454                         if (handler != null)
455                                 handler (this, e);
456                 }
457
458 #if NET_2_0             
459                 protected internal virtual void VerifyMultiSelect ()
460                 {
461                 }
462 #endif          
463
464                 [WebSysDescription ("")]
465                 [WebCategory ("Action")]
466                 public event EventHandler SelectedIndexChanged {
467                         add { Events.AddHandler (SelectedIndexChangedEvent, value); }
468                         remove { Events.RemoveHandler (SelectedIndexChangedEvent, value); }
469                 }
470
471 #if NET_2_0
472                 /* sealed in the docs */
473                 public event EventHandler TextChanged {
474                         add {
475                                 Events.AddHandler (TextChangedEvent, value);
476                         }
477                         remove {
478                                 Events.RemoveHandler (TextChangedEvent, value);
479                         }
480                 }
481                 
482                 
483                 [MonoTODO]
484                 [Themeable (false)]
485                 [DefaultValue (false)]
486                 [WebSysDescription ("")]
487                 [WebCategory ("Behavior")]
488                 public virtual bool CausesValidation {
489                         get {
490                                 throw new NotImplementedException ();
491                         }
492                         set {
493                                 throw new NotImplementedException ();   
494                         }
495                 }
496
497                 [MonoTODO]
498                 [Themeable (false)]
499                 [DefaultValue ("")]
500                 [WebSysDescription ("")]
501                 [WebCategoryAttribute ("Behavior")]
502                 public virtual string ValidationGroup {
503                         get {
504                                 throw new NotImplementedException ();
505                         }
506                         set {
507                                 throw new NotImplementedException ();
508                         }
509                 }
510
511         
512 #endif
513         }
514 }
515