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
23 [DefaultProperty("DataSource")]
\r
24 [Designer ("System.Web.UI.Design.WebControls.ListControlDesigner, " + Consts.AssemblySystem_Design, typeof (IDesigner))]
\r
25 [DataBindingHandler("System.Web.UI.Design.ListControlDataBindingHandler, " + Consts.AssemblySystem_Design)]
\r
26 [ParseChildren(true, "Items")]
\r
27 public abstract class ListControl: WebControl
\r
29 private static readonly object SelectedIndexChangedEvent = new object();
\r
31 private object dataSource;
\r
32 private ListItemCollection items;
\r
34 private int cachedSelectedIndex = -1;
\r
35 private string cachedSelectedValue;
37 public ListControl(): base(HtmlTextWriterTag.Select)
\r
41 [WebCategory ("Action")]
42 [WebSysDescription ("Raised when the selected index entry has changed.")]
\r
43 public event EventHandler SelectedIndexChanged
\r
47 Events.AddHandler(SelectedIndexChangedEvent, value);
\r
51 Events.RemoveHandler(SelectedIndexChangedEvent, value);
\r
55 [DefaultValue (false), WebCategory ("Behavior")]
56 [WebSysDescription ("The control automatically posts back after changing the text.")]
\r
57 public virtual bool AutoPostBack
\r
61 object o = ViewState["AutoPostBack"];
\r
68 ViewState["AutoPostBack"] = value;
\r
72 [DefaultValue (""), WebCategory ("Data")]
73 [WebSysDescription ("The name of the table that is used for binding when a DataSource is specified.")]
\r
74 public virtual string DataMember
\r
78 object o = ViewState["DataMember"];
\r
81 return String.Empty;
\r
85 ViewState["DataMember"] = value;
\r
90 [DefaultValue (null), Bindable (true), WebCategory ("Data")]
91 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
92 [WebSysDescription ("The DataSource that is used for data-binding.")]
\r
93 public virtual object DataSource
\r
101 if(value == null || value is IListSource || value is IEnumerable) {
105 throw new ArgumentException(HttpRuntime.FormatResourceString(ID, "Invalid DataSource Type"));
\r
109 [DefaultValue (""), WebCategory ("Data")]
110 [WebSysDescription ("The field in the datatable that provides the text entry.")]
\r
111 public virtual string DataTextField
\r
115 object o = ViewState["DataTextField"];
\r
118 return String.Empty;
\r
122 ViewState["DataTextField"] = value;
\r
126 [DefaultValue (""), WebCategory ("Data")]
127 [WebSysDescription ("Specifies a formatting rule for the texts that are returned.")]
\r
128 public virtual string DataTextFormatString
\r
132 object o = ViewState["DataTextFormatString"];
\r
135 return String.Empty;
\r
139 ViewState["DataTextFormatString"] = value;
\r
143 [DefaultValue (""), WebCategory ("Data")]
144 [WebSysDescription ("The field in the datatable that provides the entry value.")]
\r
145 public virtual string DataValueField
\r
149 object o = ViewState["DataValueField"];
\r
152 return String.Empty;
\r
156 ViewState["DataValueField"] = value;
\r
160 [DefaultValue (null), MergableProperty (false), WebCategory ("Misc")]
161 [PersistenceMode (PersistenceMode.InnerDefaultProperty)]
162 [WebSysDescription ("A collection of all items contained in this list.")]
\r
163 public virtual ListItemCollection Items
\r
169 items = new ListItemCollection();
\r
170 if(IsTrackingViewState)
\r
172 items.TrackViewState();
\r
179 [DefaultValue (0), Bindable (true), WebCategory ("Misc")]
180 [Browsable (false), DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
181 [WebSysDescription ("The index number of the currently selected ListItem.")]
\r
182 public virtual int SelectedIndex
\r
185 ListItemCollection items = Items;
\r
186 int last = items.Count;
\r
187 for (int i = 0; i < last; i++) {
\r
188 if (items [i].Selected)
\r
194 if (value < -1 || value > Items.Count)
\r
195 throw new ArgumentOutOfRangeException ();
\r
199 Items [value].Selected = true;
\r
203 [DefaultValue (null), WebCategory ("Misc")]
204 [Browsable (false), DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
205 [WebSysDescription ("The currently selected ListItem.")]
\r
206 public virtual ListItem SelectedItem
\r
210 int idx = SelectedIndex;
\r
214 return Items [idx];
\r
219 [DefaultValue (""), Bindable (true), WebCategory ("Misc")]
220 [Browsable (false), DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
221 [WebSysDescription ("The value of the currently selected ListItem.")]
\r
222 public virtual string SelectedValue {
\r
224 int idx = SelectedIndex;
\r
228 return Items [idx].Value;
\r
232 ListItem item = null;
\r
234 if (value != null) {
\r
235 if (Items.Count > 0) {
236 item = Items.FindByValue (value);
238 throw new ArgumentOutOfRangeException ("value");
240 cachedSelectedValue = value;
247 item.Selected = true;
\r
252 internal virtual ArrayList SelectedIndices
\r
256 ArrayList si = new ArrayList();
\r
257 for(int i=0; i < Items.Count; i++)
\r
259 if(Items[i].Selected)
\r
266 internal void Select(ArrayList indices)
\r
269 foreach(object intObj in indices)
\r
271 int index = (int)intObj;
\r
272 if(index >= 0 && index < Items.Count)
\r
273 Items[index].Selected = true;
\r
277 public virtual void ClearSelection()
\r
279 for(int i=0; i < Items.Count; i++)
\r
281 Items[i].Selected = false;
\r
285 protected override void LoadViewState(object savedState)
\r
287 //Order: BaseClass, Items (Collection), Indices
\r
288 if(savedState != null && savedState is Triplet)
\r
290 Triplet state = (Triplet)savedState;
\r
291 base.LoadViewState(state.First);
\r
292 Items.LoadViewState(state.Second);
\r
293 object indices = state.Third;
\r
294 if(indices != null)
\r
296 Select((ArrayList)indices);
\r
301 protected override void OnDataBinding(EventArgs e)
\r
303 base.OnDataBinding(e);
\r
304 IEnumerable ds = DataSourceHelper.GetResolvedDataSource (DataSource, DataMember);
\r
307 string dtf = DataTextField;
\r
308 string dvf = DataValueField;
\r
309 string dtfs = DataTextFormatString;
\r
310 if (dtfs.Length == 0)
\r
315 bool dontUseProperties = (dtf.Length == 0 && dvf.Length == 0);
\r
317 foreach (object current in ds) {
\r
318 ListItem li = new ListItem();
\r
319 if (dontUseProperties){
\r
320 li.Text = String.Format (dtfs, current);
\r
321 li.Value = current.ToString ();
\r
327 if (dtf.Length > 0) {
\r
328 o = DataBinder.GetPropertyValue (current, dtf, dtfs);
\r
329 li.Text = o.ToString ();
\r
332 if (dvf.Length > 0) {
\r
333 o = DataBinder.GetPropertyValue (current, dvf, null);
\r
334 li.Value = o.ToString ();
\r
341 if (cachedSelectedValue != null) {
342 int index = Items.FindByValueInternal (cachedSelectedValue);
344 throw new ArgumentOutOfRangeException("value");
346 if (cachedSelectedIndex != -1 && cachedSelectedIndex != index)
347 throw new ArgumentException(HttpRuntime.FormatResourceString(
348 "Attributes_mutually_exclusive", "Selected Index", "Selected Value"));
350 SelectedIndex = index;
351 cachedSelectedIndex = -1;
352 cachedSelectedValue = null;
356 if (cachedSelectedIndex != -1) {
\r
357 SelectedIndex = cachedSelectedIndex;
\r
358 cachedSelectedIndex = -1;
\r
362 protected virtual void OnSelectedIndexChanged(EventArgs e)
\r
366 EventHandler eh = (EventHandler)(Events[SelectedIndexChangedEvent]);
\r
372 protected override void OnPreRender (EventArgs e)
\r
374 base.OnPreRender(e);
\r
377 protected override object SaveViewState()
\r
379 //Order: BaseClass, Items (Collection), Indices
\r
380 object vs = base.SaveViewState();
\r
381 object itemSvs = Items.SaveViewState();
\r
382 object indices = null;
\r
383 if (SaveSelectedIndicesViewState)
\r
384 indices = SelectedIndices;
\r
386 if (vs != null || itemSvs != null || indices != null)
\r
387 return new Triplet(vs, itemSvs, indices);
\r
392 protected override void TrackViewState()
\r
394 base.TrackViewState();
\r
395 Items.TrackViewState();
\r
398 private bool SaveSelectedIndicesViewState {
\r
400 if (Events[SelectedIndexChangedEvent] == null && Enabled && Visible) {
\r
401 Type t = GetType();
\r
402 // If I am a derivative, let it take of storing the selected indices.
\r
403 if (t == typeof(DropDownList) || t == typeof(ListBox) ||
\r
404 t == typeof(CheckBoxList) || t == typeof(RadioButtonList))
\r