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 using System.Collections;
\r
14 using System.ComponentModel;
15 using System.ComponentModel.Design;
\r
17 using System.Web.UI;
\r
18 using System.Web.Util;
\r
20 namespace System.Web.UI.WebControls
\r
22 [DefaultEvent("SelectedIndexChanged")]
\r
24 [DefaultProperty("DataSource")]
26 [Designer ("System.Web.UI.Design.WebControls.ListControlDesigner, " + Consts.AssemblySystem_Design, typeof (IDesigner))]
\r
27 [DataBindingHandler("System.Web.UI.Design.ListControlDataBindingHandler, " + Consts.AssemblySystem_Design)]
\r
28 [ParseChildren(true, "Items")]
\r
29 public abstract class ListControl :
36 private static readonly object SelectedIndexChangedEvent = new object();
\r
39 private object dataSource;
42 private ListItemCollection items;
\r
44 private int cachedSelectedIndex = -1;
\r
45 private string cachedSelectedValue;
48 public ListControl(): base(HtmlTextWriterTag.Select)
\r
52 protected override HtmlTextWriterTag TagKey {
53 get { return HtmlTextWriterTag.Select; }
57 [WebCategory ("Action")]
58 [WebSysDescription ("Raised when the selected index entry has changed.")]
\r
59 public event EventHandler SelectedIndexChanged
\r
63 Events.AddHandler(SelectedIndexChangedEvent, value);
\r
67 Events.RemoveHandler(SelectedIndexChangedEvent, value);
\r
71 [DefaultValue (false), WebCategory ("Behavior")]
72 [WebSysDescription ("The control automatically posts back after changing the text.")]
\r
73 public virtual bool AutoPostBack
\r
77 object o = ViewState["AutoPostBack"];
\r
84 ViewState["AutoPostBack"] = value;
\r
89 [DefaultValue (""), WebCategory ("Data")]
90 [WebSysDescription ("The name of the table that is used for binding when a DataSource is specified.")]
\r
91 public virtual string DataMember
\r
95 object o = ViewState["DataMember"];
\r
98 return String.Empty;
\r
102 ViewState["DataMember"] = value;
\r
107 [DefaultValue (null), Bindable (true), WebCategory ("Data")]
108 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
109 [WebSysDescription ("The DataSource that is used for data-binding.")]
\r
110 public virtual object DataSource
\r
118 if(value == null || value is IListSource || value is IEnumerable) {
122 throw new ArgumentException(HttpRuntime.FormatResourceString(ID, "Invalid DataSource Type"));
\r
127 [DefaultValue (""), WebCategory ("Data")]
128 [WebSysDescription ("The field in the datatable that provides the text entry.")]
\r
129 public virtual string DataTextField
\r
133 object o = ViewState["DataTextField"];
\r
136 return String.Empty;
\r
140 ViewState["DataTextField"] = value;
\r
144 [DefaultValue (""), WebCategory ("Data")]
145 [WebSysDescription ("Specifies a formatting rule for the texts that are returned.")]
\r
146 public virtual string DataTextFormatString
\r
150 object o = ViewState["DataTextFormatString"];
\r
153 return String.Empty;
\r
157 ViewState["DataTextFormatString"] = value;
\r
161 [DefaultValue (""), WebCategory ("Data")]
162 [WebSysDescription ("The field in the datatable that provides the entry value.")]
\r
163 public virtual string DataValueField
\r
167 object o = ViewState["DataValueField"];
\r
170 return String.Empty;
\r
174 ViewState["DataValueField"] = value;
\r
178 [DefaultValue (null), MergableProperty (false), WebCategory ("Misc")]
179 [PersistenceMode (PersistenceMode.InnerDefaultProperty)]
180 [WebSysDescription ("A collection of all items contained in this list.")]
\r
181 public virtual ListItemCollection Items
\r
187 items = new ListItemCollection();
\r
188 if(IsTrackingViewState)
\r
190 items.TrackViewState();
\r
197 [DefaultValue (0), Bindable (true), WebCategory ("Misc")]
198 [Browsable (false), DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
199 [WebSysDescription ("The index number of the currently selected ListItem.")]
\r
200 public virtual int SelectedIndex
\r
203 ListItemCollection items = Items;
\r
204 int last = items.Count;
\r
205 for (int i = 0; i < last; i++) {
\r
206 if (items [i].Selected)
\r
212 if (Items.Count == 0)
\r
214 cachedSelectedIndex = value;
\r
217 if ((value < -1) || (value >= Items.Count))
\r
218 throw new ArgumentOutOfRangeException ();
\r
222 Items [value].Selected = true;
\r
226 [DefaultValue (null), WebCategory ("Misc")]
227 [Browsable (false), DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
228 [WebSysDescription ("The currently selected ListItem.")]
\r
229 public virtual ListItem SelectedItem
\r
233 int idx = SelectedIndex;
\r
237 return Items [idx];
\r
242 [DefaultValue (""), Bindable (true), WebCategory ("Misc")]
243 [Browsable (false), DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
244 [WebSysDescription ("The value of the currently selected ListItem.")]
\r
245 public virtual string SelectedValue {
\r
247 int idx = SelectedIndex;
\r
251 return Items [idx].Value;
\r
255 ListItem item = null;
\r
257 if (value != null) {
\r
258 if (Items.Count > 0) {
259 item = Items.FindByValue (value);
261 throw new ArgumentOutOfRangeException ("value");
263 cachedSelectedValue = value;
270 item.Selected = true;
\r
275 internal virtual ArrayList SelectedIndices
\r
279 ArrayList si = new ArrayList();
\r
280 for(int i=0; i < Items.Count; i++)
\r
282 if(Items[i].Selected)
\r
289 internal void Select(ArrayList indices)
\r
292 foreach(object intObj in indices)
\r
294 int index = (int)intObj;
\r
295 if(index >= 0 && index < Items.Count)
\r
296 Items[index].Selected = true;
\r
300 public virtual void ClearSelection()
\r
302 for(int i=0; i < Items.Count; i++)
\r
304 Items[i].Selected = false;
\r
308 protected override void LoadViewState(object savedState)
\r
310 //Order: BaseClass, Items (Collection), Indices
\r
311 if(savedState != null && savedState is Triplet)
\r
313 Triplet state = (Triplet)savedState;
\r
314 base.LoadViewState(state.First);
\r
315 Items.LoadViewState(state.Second);
\r
316 object indices = state.Third;
\r
317 if(indices != null)
\r
319 Select((ArrayList)indices);
\r
325 protected override void PerformDataBinding ()
327 base.PerformDataBinding ();
328 IEnumerable ds = GetResolvedDataSource ();
330 protected override void OnDataBinding(EventArgs e)
\r
332 base.OnDataBinding(e);
\r
333 IEnumerable ds = DataSourceHelper.GetResolvedDataSource (DataSource, DataMember);
336 string dtf = DataTextField;
\r
337 string dvf = DataValueField;
\r
338 string dtfs = DataTextFormatString;
\r
339 if (dtfs.Length == 0)
\r
344 bool dontUseProperties = (dtf.Length == 0 && dvf.Length == 0);
\r
346 foreach (object current in ds) {
\r
347 ListItem li = new ListItem();
\r
348 if (dontUseProperties){
\r
349 li.Text = String.Format (dtfs, current);
\r
350 li.Value = current.ToString ();
\r
356 if (dtf.Length > 0) {
\r
357 o = DataBinder.GetPropertyValue (current, dtf, dtfs);
\r
358 li.Text = o.ToString ();
\r
361 if (dvf.Length > 0) {
\r
362 o = DataBinder.GetPropertyValue (current, dvf, null);
\r
363 li.Value = o.ToString ();
\r
370 if (cachedSelectedValue != null) {
371 int index = Items.FindByValueInternal (cachedSelectedValue);
373 throw new ArgumentOutOfRangeException("value");
375 if (cachedSelectedIndex != -1 && cachedSelectedIndex != index)
376 throw new ArgumentException(HttpRuntime.FormatResourceString(
377 "Attributes_mutually_exclusive", "Selected Index", "Selected Value"));
379 SelectedIndex = index;
380 cachedSelectedIndex = -1;
381 cachedSelectedValue = null;
385 if (cachedSelectedIndex != -1) {
\r
386 SelectedIndex = cachedSelectedIndex;
\r
387 cachedSelectedIndex = -1;
\r
391 protected virtual void OnSelectedIndexChanged(EventArgs e)
\r
395 EventHandler eh = (EventHandler)(Events[SelectedIndexChangedEvent]);
\r
401 protected override void OnPreRender (EventArgs e)
\r
403 base.OnPreRender(e);
\r
406 protected override object SaveViewState()
\r
408 //Order: BaseClass, Items (Collection), Indices
\r
409 object vs = base.SaveViewState();
\r
410 object itemSvs = Items.SaveViewState();
\r
411 object indices = null;
\r
412 if (SaveSelectedIndicesViewState)
\r
413 indices = SelectedIndices;
\r
415 if (vs != null || itemSvs != null || indices != null)
\r
416 return new Triplet(vs, itemSvs, indices);
\r
421 protected override void TrackViewState()
\r
423 base.TrackViewState();
\r
424 Items.TrackViewState();
\r
427 private bool SaveSelectedIndicesViewState {
\r
429 if (Events[SelectedIndexChangedEvent] == null && Enabled && Visible) {
\r
430 Type t = GetType();
\r
431 // If I am a derivative, let it take of storing the selected indices.
\r
432 if (t == typeof(DropDownList) || t == typeof(ListBox) ||
\r
433 t == typeof(CheckBoxList) || t == typeof(RadioButtonList))
\r