2 // System.Web.UI.WebControls.ListControl.cs
5 // Gaurav Vaish (gvaish@iitk.ac.in)
6 // Andreas Nahr (ClassDevelopment@A-SoftTech.com)
8 // (C) Gaurav Vaish (2002)
9 // (C) 2003 Andreas Nahr
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 using System
.Collections
;
35 using System
.ComponentModel
;
36 using System
.ComponentModel
.Design
;
39 using System
.Web
.Util
;
41 namespace System
.Web
.UI
.WebControls
43 [DefaultEvent("SelectedIndexChanged")]
45 [DefaultProperty("DataSource")]
47 [Designer ("System.Web.UI.Design.WebControls.ListControlDesigner, " + Consts
.AssemblySystem_Design
, typeof (IDesigner
))]
48 [DataBindingHandler("System.Web.UI.Design.ListControlDataBindingHandler, " + Consts
.AssemblySystem_Design
)]
49 [ParseChildren(true, "Items")]
50 public abstract class ListControl
:
57 private static readonly object SelectedIndexChangedEvent
= new object();
60 private object dataSource
;
63 private ListItemCollection items
;
65 private int cachedSelectedIndex
= -1;
66 private string cachedSelectedValue
;
69 public ListControl(): base(HtmlTextWriterTag
.Select
)
73 protected override HtmlTextWriterTag TagKey
{
74 get { return HtmlTextWriterTag.Select; }
78 [WebCategory ("Action")]
79 [WebSysDescription ("Raised when the selected index entry has changed.")]
80 public event EventHandler SelectedIndexChanged
84 Events
.AddHandler(SelectedIndexChangedEvent
, value);
88 Events
.RemoveHandler(SelectedIndexChangedEvent
, value);
92 [DefaultValue (false), WebCategory ("Behavior")]
93 [WebSysDescription ("The control automatically posts back after changing the text.")]
94 public virtual bool AutoPostBack
98 object o
= ViewState
["AutoPostBack"];
105 ViewState
["AutoPostBack"] = value;
110 [DefaultValue (""), WebCategory ("Data")]
111 [WebSysDescription ("The name of the table that is used for binding when a DataSource is specified.")]
112 public virtual string DataMember
116 object o
= ViewState
["DataMember"];
123 ViewState
["DataMember"] = value;
128 [DefaultValue (null), Bindable (true), WebCategory ("Data")]
129 [DesignerSerializationVisibility (DesignerSerializationVisibility
.Hidden
)]
130 [WebSysDescription ("The DataSource that is used for data-binding.")]
131 public virtual object DataSource
139 if(value == null || value is IListSource
|| value is IEnumerable
) {
143 throw new ArgumentException(HttpRuntime
.FormatResourceString(ID
, "Invalid DataSource Type"));
148 [DefaultValue (""), WebCategory ("Data")]
149 [WebSysDescription ("The field in the datatable that provides the text entry.")]
150 public virtual string DataTextField
154 object o
= ViewState
["DataTextField"];
161 ViewState
["DataTextField"] = value;
165 [DefaultValue (""), WebCategory ("Data")]
166 [WebSysDescription ("Specifies a formatting rule for the texts that are returned.")]
167 public virtual string DataTextFormatString
171 object o
= ViewState
["DataTextFormatString"];
178 ViewState
["DataTextFormatString"] = value;
182 [DefaultValue (""), WebCategory ("Data")]
183 [WebSysDescription ("The field in the datatable that provides the entry value.")]
184 public virtual string DataValueField
188 object o
= ViewState
["DataValueField"];
195 ViewState
["DataValueField"] = value;
199 [DefaultValue (null), MergableProperty (false), WebCategory ("Misc")]
200 [PersistenceMode (PersistenceMode
.InnerDefaultProperty
)]
201 [WebSysDescription ("A collection of all items contained in this list.")]
202 public virtual ListItemCollection Items
208 items
= new ListItemCollection();
209 if(IsTrackingViewState
)
211 items
.TrackViewState();
218 [DefaultValue (0), Bindable (true), WebCategory ("Misc")]
219 [Browsable (false), DesignerSerializationVisibility (DesignerSerializationVisibility
.Hidden
)]
220 [WebSysDescription ("The index number of the currently selected ListItem.")]
221 public virtual int SelectedIndex
224 ListItemCollection items
= Items
;
225 int last
= items
.Count
;
226 for (int i
= 0; i
< last
; i
++) {
227 if (items
[i
].Selected
)
233 if (Items
.Count
== 0)
235 cachedSelectedIndex
= value;
238 if ((value < -1) || (value >= Items
.Count
))
239 throw new ArgumentOutOfRangeException ();
243 Items
[value].Selected
= true;
247 [DefaultValue (null), WebCategory ("Misc")]
248 [Browsable (false), DesignerSerializationVisibility (DesignerSerializationVisibility
.Hidden
)]
249 [WebSysDescription ("The currently selected ListItem.")]
250 public virtual ListItem SelectedItem
254 int idx
= SelectedIndex
;
263 [DefaultValue (""), Bindable (true), WebCategory ("Misc")]
264 [Browsable (false), DesignerSerializationVisibility (DesignerSerializationVisibility
.Hidden
)]
265 [WebSysDescription ("The value of the currently selected ListItem.")]
266 public virtual string SelectedValue
{
268 int idx
= SelectedIndex
;
272 return Items
[idx
].Value
;
276 ListItem item
= null;
279 if (Items
.Count
> 0) {
280 item
= Items
.FindByValue (value);
282 throw new ArgumentOutOfRangeException ("value");
284 cachedSelectedValue
= value;
291 item
.Selected
= true;
296 internal virtual ArrayList SelectedIndices
300 ArrayList si
= new ArrayList();
301 for(int i
=0; i
< Items
.Count
; i
++)
303 if(Items
[i
].Selected
)
310 internal void Select(ArrayList indices
)
313 foreach(object intObj
in indices
)
315 int index
= (int)intObj
;
316 if(index
>= 0 && index
< Items
.Count
)
317 Items
[index
].Selected
= true;
321 public virtual void ClearSelection()
323 for(int i
=0; i
< Items
.Count
; i
++)
325 Items
[i
].Selected
= false;
329 protected override void LoadViewState(object savedState
)
331 //Order: BaseClass, Items (Collection), Indices
332 if(savedState
!= null && savedState
is Triplet
)
334 Triplet state
= (Triplet
)savedState
;
335 base.LoadViewState(state
.First
);
336 Items
.LoadViewState(state
.Second
);
337 object indices
= state
.Third
;
340 Select((ArrayList
)indices
);
346 protected override void PerformDataBinding ()
348 base.PerformDataBinding ();
349 IEnumerable ds
= GetResolvedDataSource ();
351 protected override void OnDataBinding(EventArgs e
)
353 base.OnDataBinding(e
);
354 IEnumerable ds
= DataSourceHelper
.GetResolvedDataSource (DataSource
, DataMember
);
357 string dtf
= DataTextField
;
358 string dvf
= DataValueField
;
359 string dtfs
= DataTextFormatString
;
360 if (dtfs
.Length
== 0)
365 bool dontUseProperties
= (dtf
.Length
== 0 && dvf
.Length
== 0);
367 foreach (object current
in ds
) {
368 ListItem li
= new ListItem();
369 if (dontUseProperties
){
370 li
.Text
= String
.Format (dtfs
, current
);
371 li
.Value
= current
.ToString ();
377 if (dtf
.Length
> 0) {
378 o
= DataBinder
.GetPropertyValue (current
, dtf
, dtfs
);
379 li
.Text
= o
.ToString ();
382 if (dvf
.Length
> 0) {
383 o
= DataBinder
.GetPropertyValue (current
, dvf
, null);
384 li
.Value
= o
.ToString ();
391 if (cachedSelectedValue
!= null) {
392 int index
= Items
.FindByValueInternal (cachedSelectedValue
);
394 throw new ArgumentOutOfRangeException("value");
396 if (cachedSelectedIndex
!= -1 && cachedSelectedIndex
!= index
)
397 throw new ArgumentException(HttpRuntime
.FormatResourceString(
398 "Attributes_mutually_exclusive", "Selected Index", "Selected Value"));
400 SelectedIndex
= index
;
401 cachedSelectedIndex
= -1;
402 cachedSelectedValue
= null;
406 if (cachedSelectedIndex
!= -1) {
407 SelectedIndex
= cachedSelectedIndex
;
408 cachedSelectedIndex
= -1;
412 protected virtual void OnSelectedIndexChanged(EventArgs e
)
416 EventHandler eh
= (EventHandler
)(Events
[SelectedIndexChangedEvent
]);
422 protected override void OnPreRender (EventArgs e
)
427 protected override object SaveViewState()
429 //Order: BaseClass, Items (Collection), Indices
430 object vs
= base.SaveViewState();
431 object itemSvs
= Items
.SaveViewState();
432 object indices
= null;
433 if (SaveSelectedIndicesViewState
)
434 indices
= SelectedIndices
;
436 if (vs
!= null || itemSvs
!= null || indices
!= null)
437 return new Triplet(vs
, itemSvs
, indices
);
442 protected override void TrackViewState()
444 base.TrackViewState();
445 Items
.TrackViewState();
448 private bool SaveSelectedIndicesViewState
{
450 if (Events
[SelectedIndexChangedEvent
] == null && Enabled
&& Visible
) {
452 // If I am a derivative, let it take of storing the selected indices.
453 if (t
== typeof(DropDownList
) || t
== typeof(ListBox
) ||
454 t
== typeof(CheckBoxList
) || t
== typeof(RadioButtonList
))