Fixed PrepareControlHierarchyForItem().
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / ListControl.cs
index 50ea816aabb53aa26596833cd0f62b17a258a979..d2571e6205c065982ce15cdee32085d22fe4c829 100644 (file)
@@ -1,38 +1,61 @@
-/**\r
- * Namespace: System.Web.UI.WebControls\r
- * Class:     ListControl\r
- *\r
- * Author:  Gaurav Vaish\r
- * Maintainer: gvaish@iitk.ac.in\r
- * Contact: <my_scripts2001@yahoo.com>, <gvaish@iitk.ac.in>\r
- * Implementation: yes\r
- * Status:  100%\r
- *\r
- * (C) Gaurav Vaish (2001)\r
- */\r
+//
+// System.Web.UI.WebControls.ListControl.cs
+//
+// Authors:
+//   Gaurav Vaish (gvaish@iitk.ac.in)
+//   Andreas Nahr (ClassDevelopment@A-SoftTech.com)
+//
+// (C) Gaurav Vaish (2002)
+// (C) 2003 Andreas Nahr
+//
 \r
 using System;\r
 using System.Collections;\r
-using System.ComponentModel;\r
+using System.ComponentModel;
+using System.ComponentModel.Design;\r
 using System.Web;\r
 using System.Web.UI;\r
-using System.Web.Utils;\r
+using System.Web.Util;\r
 \r
 namespace System.Web.UI.WebControls\r
 {\r
-       public class ListControl: WebControl\r
+       [DefaultEvent("SelectedIndexChanged")]\r
+       #if !NET_1_2
+       [DefaultProperty("DataSource")]
+       #endif\r
+       [Designer ("System.Web.UI.Design.WebControls.ListControlDesigner, " + Consts.AssemblySystem_Design, typeof (IDesigner))]\r
+       [DataBindingHandler("System.Web.UI.Design.ListControlDataBindingHandler, " + Consts.AssemblySystem_Design)]\r
+       [ParseChildren(true, "Items")]\r
+       public abstract class ListControl : 
+               #if NET_1_2
+                       DataBoundControl
+               #else
+                       WebControl
+               #endif\r
        {\r
                private static readonly object SelectedIndexChangedEvent = new object();\r
-\r
-               private object             dataSource;\r
+
+               #if !NET_1_2\r
+               private object             dataSource;
+               #endif
+               \r
                private ListItemCollection items;\r
 \r
                private int cachedSelectedIndex = -1;\r
-               \r
+               private string cachedSelectedValue;
+
+               #if !NET_1_2\r
                public ListControl(): base(HtmlTextWriterTag.Select)\r
                {\r
-               }\r
-               \r
+               }
+               #else
+               protected override HtmlTextWriterTag TagKey {
+                       get { return HtmlTextWriterTag.Select; }
+               }
+               #endif\r
+
+               [WebCategory ("Action")]
+               [WebSysDescription ("Raised when the selected index entry has changed.")]\r
                public event EventHandler SelectedIndexChanged\r
                {\r
                        add\r
@@ -44,7 +67,9 @@ namespace System.Web.UI.WebControls
                                Events.RemoveHandler(SelectedIndexChangedEvent, value);\r
                        }\r
                }\r
-               \r
+
+               [DefaultValue (false), WebCategory ("Behavior")]
+               [WebSysDescription ("The control automatically posts back after changing the text.")]\r
                public virtual bool AutoPostBack\r
                {\r
                        get\r
@@ -59,7 +84,10 @@ namespace System.Web.UI.WebControls
                                ViewState["AutoPostBack"] = value;\r
                        }\r
                }\r
-               \r
+
+               #if !NET_1_2
+               [DefaultValue (""), WebCategory ("Data")]
+               [WebSysDescription ("The name of the table that is used for binding when a DataSource is specified.")]\r
                public virtual string DataMember\r
                {\r
                        get\r
@@ -74,7 +102,11 @@ namespace System.Web.UI.WebControls
                                ViewState["DataMember"] = value;\r
                        }\r
                }\r
-               \r
+
+
+               [DefaultValue (null), Bindable (true), WebCategory ("Data")]
+               [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
+               [WebSysDescription ("The DataSource that is used for data-binding.")]\r
                public virtual object DataSource\r
                {\r
                        get\r
@@ -83,18 +115,17 @@ namespace System.Web.UI.WebControls
                        }\r
                        set\r
                        {\r
-                               if(value != null)\r
-                               {\r
-                                       if(value is IListSource || value is IEnumerable)\r
-                                       {\r
-                                               dataSource = value;\r
-                                               return;\r
-                                       }\r
-                               }\r
-                               throw new ArgumentException(/*HttpRuntime.FormatResourceString(ID, "Invalid DataSource Type")*/);\r
+                               if(value == null || value is IListSource || value is IEnumerable) {
+                                       dataSource = value;
+                                       return;
+                               }
+                               throw new ArgumentException(HttpRuntime.FormatResourceString(ID, "Invalid DataSource Type"));\r
                        }\r
-               }\r
-               \r
+               }
+               #endif\r
+
+               [DefaultValue (""), WebCategory ("Data")]
+               [WebSysDescription ("The field in the datatable that provides the text entry.")]\r
                public virtual string DataTextField\r
                {\r
                        get\r
@@ -109,7 +140,9 @@ namespace System.Web.UI.WebControls
                                ViewState["DataTextField"] = value;\r
                        }\r
                }\r
-               \r
+
+               [DefaultValue (""), WebCategory ("Data")]
+               [WebSysDescription ("Specifies a formatting rule for the texts that are returned.")]\r
                public virtual string DataTextFormatString\r
                {\r
                        get\r
@@ -124,7 +157,9 @@ namespace System.Web.UI.WebControls
                                ViewState["DataTextFormatString"] = value;\r
                        }\r
                }\r
-               \r
+
+               [DefaultValue (""), WebCategory ("Data")]
+               [WebSysDescription ("The field in the datatable that provides the entry value.")]\r
                public virtual string DataValueField\r
                {\r
                        get\r
@@ -139,7 +174,10 @@ namespace System.Web.UI.WebControls
                                ViewState["DataValueField"] = value;\r
                        }\r
                }\r
-               \r
+
+               [DefaultValue (null), MergableProperty (false), WebCategory ("Misc")]
+               [PersistenceMode (PersistenceMode.InnerDefaultProperty)]
+               [WebSysDescription ("A collection of all items contained in this list.")]\r
                public virtual ListItemCollection Items\r
                {\r
                        get\r
@@ -149,42 +187,86 @@ namespace System.Web.UI.WebControls
                                        items = new ListItemCollection();\r
                                        if(IsTrackingViewState)\r
                                        {\r
-                                               //items.TrackViewState();\r
+                                               items.TrackViewState();\r
                                        }\r
                                }\r
                                return items;\r
                        }\r
                }\r
-               \r
+
+               [DefaultValue (0), Bindable (true), WebCategory ("Misc")]
+               [Browsable (false), DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
+               [WebSysDescription ("The index number of the currently selected ListItem.")]\r
                public virtual int SelectedIndex\r
                {\r
-                       get\r
-                       {\r
-                               object o = ViewState["SelectedIndex"];\r
-                               if(o!=null)\r
-                                       return (int)o;\r
+                       get {\r
+                               ListItemCollection items = Items;\r
+                               int last = items.Count;\r
+                               for (int i = 0; i < last; i++) {\r
+                                       if (items [i].Selected)\r
+                                               return i;\r
+                               }\r
                                return -1;\r
                        }\r
-                       set\r
-                       {\r
-                               if(value < -1 || value > Items.Count)\r
-                                       throw new ArgumentOutOfRangeException();\r
-                               ViewState["SelectedIndex"] = value;\r
+                       set {\r
+                               if (value < -1 || value > Items.Count)\r
+                                       throw new ArgumentOutOfRangeException ();\r
+\r
+                               ClearSelection ();\r
+                               if (value != -1)\r
+                                       Items [value].Selected = true;\r
                        }\r
                }\r
-               \r
+
+               [DefaultValue (null), WebCategory ("Misc")]
+               [Browsable (false), DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
+               [WebSysDescription ("The currently selected ListItem.")]\r
                public virtual ListItem SelectedItem\r
                {\r
                        get\r
                        {\r
-                               if(SelectedIndex > 0)\r
-                               {\r
-                                       return Items[SelectedIndex];\r
-                               }\r
-                               return null;\r
+                               int idx = SelectedIndex;\r
+                               if (idx < 0)\r
+                                       return null;\r
+\r
+                               return Items [idx];\r
                        }\r
                }\r
 \r
+#if NET_1_1
+               [DefaultValue (""), Bindable (true), WebCategory ("Misc")]
+               [Browsable (false), DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
+               [WebSysDescription ("The value of the currently selected ListItem.")]\r
+               public virtual string SelectedValue {\r
+                       get {\r
+                               int idx = SelectedIndex;\r
+                               if (idx == -1)\r
+                                       return "";\r
+\r
+                               return Items [idx].Value;\r
+                       }\r
+\r
+                       set {\r
+                               ListItem item = null;\r
+\r
+                               if (value != null) {\r
+                                       if (Items.Count > 0) {
+                                               item = Items.FindByValue (value);
+                                               if (item == null)
+                                                       throw new ArgumentOutOfRangeException ("value");
+                                       } else {
+                                               cachedSelectedValue = value;
+                                               return;
+                                       }
+                               }\r
+\r
+                               ClearSelection ();\r
+                               if (item != null)\r
+                                       item.Selected = true;\r
+                       }\r
+               }\r
+#endif\r
+               \r
                internal virtual ArrayList SelectedIndices\r
                {\r
                        get\r
@@ -193,17 +275,18 @@ namespace System.Web.UI.WebControls
                                for(int i=0; i < Items.Count; i++)\r
                                {\r
                                        if(Items[i].Selected)\r
-                                               ArrayList.Add(i);\r
+                                               si.Add(i);\r
                                }\r
                                return si;\r
                        }\r
                }\r
-               \r
+\r
                internal void Select(ArrayList indices)\r
                {\r
                        ClearSelection();\r
-                       foreach(int index in indices)\r
+                       foreach(object intObj in indices)\r
                        {\r
+                               int index = (int)intObj;\r
                                if(index >= 0 && index < Items.Count)\r
                                        Items[index].Selected = true;\r
                        }\r
@@ -216,7 +299,7 @@ namespace System.Web.UI.WebControls
                                Items[i].Selected = false;\r
                        }\r
                }\r
-               \r
+\r
                protected override void LoadViewState(object savedState)\r
                {\r
                        //Order: BaseClass, Items (Collection), Indices\r
@@ -232,50 +315,74 @@ namespace System.Web.UI.WebControls
                                }\r
                        }\r
                }\r
-               \r
+
+               #if NET_1_2
+               protected override void PerformDataBinding ()
+               {
+                       base.PerformDataBinding ();
+                       IEnumerable ds = GetResolvedDataSource ();
+               #else\r
                protected override void OnDataBinding(EventArgs e)\r
                {\r
                        base.OnDataBinding(e);\r
-                       IEnumerable resolvedData = DataSourceHelper.GetResolvedDataSource(DataSource, DataMember);\r
-                       if(resolvedData != null)\r
-                       {\r
-                               string dataTextField = DataTextField;\r
-                               string dataValueField = DataValueField;\r
+                       IEnumerable ds = DataSourceHelper.GetResolvedDataSource (DataSource, DataMember);
+               #endif\r
+                       if(ds != null) {\r
+                               string dtf = DataTextField;\r
+                               string dvf = DataValueField;\r
+                               string dtfs = DataTextFormatString;\r
+                               if (dtfs.Length == 0)\r
+                                       dtfs = "{0}";\r
+\r
                                Items.Clear();\r
-                               ICollection rdsCollection = resolvedDataSource as ICollection;\r
-                               if(rdsCollection != null)\r
-                               {\r
-                                       Items.Capacity = rdsCollection.Count;\r
-                               }\r
-                               bool valid = ( (dataTextField.Length >= 0) && (dataValueField.Length >=0) );\r
-                               foreach(IEnumerable current in resolvedDataSource.GetEnumerator())\r
-                               {\r
+\r
+                               bool dontUseProperties = (dtf.Length == 0 && dvf.Length == 0);\r
+\r
+                               foreach (object current in ds) {\r
                                        ListItem li = new ListItem();\r
-                                       if(valid)\r
-                                       {\r
-                                               if(dataTextField.Length >= 0)\r
-                                               {\r
-                                                       li.Text = DataBinder.GetPropertyValue(current, dataTextField, null);\r
-                                               }\r
-                                               if(dataValueField.Length >= 0)\r
-                                               {\r
-                                                       li.Value = DataBinder.GetPropertyValue(current, dataValueField, null);\r
-                                               }\r
-                                       } else\r
-                                       {\r
-                                               li.Text  = dataTextField.ToString();\r
-                                               li.Value = dataValueField.ToString();\r
+                                       if (dontUseProperties){\r
+                                               li.Text  = String.Format (dtfs, current);\r
+                                               li.Value = current.ToString ();\r
+                                               Items.Add (li);\r
+                                               continue;\r
+                                       }\r
+\r
+                                       object o;\r
+                                       if (dtf.Length > 0) {\r
+                                               o = DataBinder.GetPropertyValue (current, dtf, dtfs);\r
+                                               li.Text = o.ToString ();\r
                                        }\r
+\r
+                                       if (dvf.Length > 0) {\r
+                                               o = DataBinder.GetPropertyValue (current, dvf, null);\r
+                                               li.Value = o.ToString ();\r
+                                       }\r
+\r
                                        Items.Add(li);\r
                                }\r
                        }\r
-                       if(cachedSelectedIndex != -1)\r
-                       {\r
+
+                       if (cachedSelectedValue != null) {
+                               int index = Items.FindByValueInternal (cachedSelectedValue);
+                               if (index == -1)
+                                       throw new ArgumentOutOfRangeException("value");
+
+                               if (cachedSelectedIndex != -1 && cachedSelectedIndex != index)
+                                       throw new ArgumentException(HttpRuntime.FormatResourceString(
+                                               "Attributes_mutually_exclusive", "Selected Index", "Selected Value"));
+
+                               SelectedIndex = index;
+                               cachedSelectedIndex = -1;
+                               cachedSelectedValue = null;
+                               return;
+                       }
+
+                       if (cachedSelectedIndex != -1) {\r
                                SelectedIndex = cachedSelectedIndex;\r
                                cachedSelectedIndex = -1;\r
                        }\r
                }\r
-               \r
+\r
                protected virtual void OnSelectedIndexChanged(EventArgs e)\r
                {\r
                        if(Events!=null)\r
@@ -285,38 +392,40 @@ namespace System.Web.UI.WebControls
                                                eh(this, e);\r
                                }\r
                }\r
-               \r
+\r
+               protected override void OnPreRender (EventArgs e)\r
+               {\r
+                       base.OnPreRender(e);\r
+               }\r
+\r
                protected override object SaveViewState()\r
                {\r
                        //Order: BaseClass, Items (Collection), Indices\r
                        object vs = base.SaveViewState();\r
                        object itemSvs = Items.SaveViewState();\r
                        object indices = null;\r
-                       if(SaveSelectedIndicesViewState)\r
+                       if (SaveSelectedIndicesViewState)\r
                                indices = SelectedIndices;\r
-                       if(vs!= null && itemSvs != null && indices != null)\r
-                       {\r
+\r
+                       if (vs != null || itemSvs != null || indices != null)\r
                                return new Triplet(vs, itemSvs, indices);\r
-                       }\r
+\r
                        return null;\r
                }\r
-               \r
-               protected ovrride void TrackViewState()\r
+\r
+               protected override void TrackViewState()\r
                {\r
                        base.TrackViewState();\r
                        Items.TrackViewState();\r
                }\r
-               \r
-               private bool SaveSelectedIndicesViewState\r
-               {\r
-                       get\r
-                       {\r
-                               if( Events[SelectedIndexChangedEvent] != null && Enabled && Visible)\r
-                               {\r
+\r
+               private bool SaveSelectedIndicesViewState {\r
+                       get {\r
+                               if (Events[SelectedIndexChangedEvent] == null && Enabled && Visible) {\r
                                        Type t = GetType();\r
                                        // If I am a derivative, let it take of storing the selected indices.\r
-                                       // Why should I bother.\r
-                                       if(t == typeof(DropDownList) || t == typeof(ListBox) || t == typeof(CheckBoxList) || t == typeof(RadioButtonList))\r
+                                       if (t == typeof(DropDownList) || t == typeof(ListBox) ||\r
+                                           t == typeof(CheckBoxList) || t == typeof(RadioButtonList))\r
                                                return false;\r
                                }\r
                                return true;\r