* PagedDataSource.cs (PrivateICollectionEnumerator.MoveNext):
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / Repeater.cs
index fa2ad43a5503240890b9c035ddd92a34f72a9564..21cd3184efc64173eb1aeb23113a1ac7fd439b42 100644 (file)
@@ -1,27 +1,29 @@
-/**\r
- * Namespace: System.Web.UI.WebControls\r
- * Class:     Repeater\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:  90%\r
- *\r
- * (C) Gaurav Vaish (2002)\r
- */\r
+//
+// System.Web.UI.WebControls.Repeater.cs
+//
+// Authors:
+//   Gaurav Vaish (gvaish@iitk.ac.in)
+//   Gonzalo Paniagua Javier (gonzalo@ximian.com)
+//   Andreas Nahr (ClassDevelopment@A-SoftTech.com)
+//
+// (c) 2002 Ximian, Inc. (http://www.ximian.com)
+// (C) Gaurav Vaish (2002)
+// (C) 2003 Andreas Nahr
+//
 \r
 using System;\r
 using System.Collections;\r
 using System.Web;\r
 using System.Web.UI;\r
-using System.ComponentModel;\r
+using System.Web.Util;\r
+using System.ComponentModel;
+using System.ComponentModel.Design;\r
 \r
 namespace System.Web.UI.WebControls\r
 {\r
        [DefaultEvent("ItemCommand")]\r
        [DefaultProperty("DataSource")]\r
-       //[Designer("??")]\r
+       [Designer ("System.Web.UI.Design.WebControls.RepeaterDesigner, " + Consts.AssemblySystem_Design, typeof (IDesigner))]\r
        [ParseChildren(true)]\r
        [PersistChildren(false)]\r
        public class Repeater : Control, INamingContainer\r
@@ -45,7 +47,9 @@ namespace System.Web.UI.WebControls
                public Repeater(): base()\r
                {\r
                }\r
-\r
+
+               [WebCategory ("Action")]
+               [WebSysDescription ("Raised when a command is executed in the DataList.")]\r
                public event RepeaterCommandEventHandler ItemCommand\r
                {\r
                        add\r
@@ -57,7 +61,9 @@ namespace System.Web.UI.WebControls
                                Events.RemoveHandler(ItemCommandEvent, value);\r
                        }\r
                }\r
-\r
+
+               [WebCategory ("Behavior")]
+               [WebSysDescription ("Raised when an item gets created.")]\r
                public event RepeaterItemEventHandler ItemCreated\r
                {\r
                        add\r
@@ -69,7 +75,9 @@ namespace System.Web.UI.WebControls
                                Events.RemoveHandler(ItemCreatedEvent, value);\r
                        }\r
                }\r
-\r
+
+               [WebCategory ("Behavior")]
+               [WebSysDescription ("Raised when an item gets data-bound.")]\r
                public event RepeaterItemEventHandler ItemDataBound\r
                {\r
                        add\r
@@ -81,7 +89,10 @@ namespace System.Web.UI.WebControls
                                Events.RemoveHandler(ItemDataBoundEvent, value);\r
                        }\r
                }\r
-\r
+
+               [DefaultValue (null), Browsable (false), PersistenceMode (PersistenceMode.InnerProperty)]
+               [TemplateContainer (typeof (RepeaterItem))]
+               [WebSysDescription ("The template that is used to create an alternating item.")]\r
                public virtual ITemplate AlternatingItemTemplate\r
                {\r
                        get\r
@@ -102,7 +113,9 @@ namespace System.Web.UI.WebControls
                                return base.Controls;\r
                        }\r
                }\r
-\r
+
+               [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
@@ -119,7 +132,10 @@ 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
@@ -127,11 +143,19 @@ namespace System.Web.UI.WebControls
                                return dataSource;\r
                        }\r
                        set\r
-                       {\r
+                       {
+                               if (!(value is IListSource) && !(value is IEnumerable))
+                                       throw new ArgumentException ("An invalid data source is being used for " +
+                                               ID + ". A valid data source must implement either " +
+                                               "IListSource or IEnumerable.");
+                               
                                dataSource = value;\r
                        }\r
                }\r
-\r
+
+               [DefaultValue (null), Browsable (false), PersistenceMode (PersistenceMode.InnerProperty)]
+               [TemplateContainer (typeof (RepeaterItem))]
+               [WebSysDescription ("The template that is used to create a footer.")]\r
                public virtual ITemplate FooterTemplate\r
                {\r
                        get\r
@@ -143,7 +167,10 @@ namespace System.Web.UI.WebControls
                                footerTemplate = value;\r
                        }\r
                }\r
-\r
+
+               [DefaultValue (null), Browsable (false), PersistenceMode (PersistenceMode.InnerProperty)]
+               [TemplateContainer (typeof (RepeaterItem))]
+               [WebSysDescription ("The template that is used to create a header.")]\r
                public virtual ITemplate HeaderTemplate\r
                {\r
                        get\r
@@ -155,14 +182,17 @@ namespace System.Web.UI.WebControls
                                headerTemplate = value;\r
                        }\r
                }\r
-\r
+
+               [Browsable (false)]
+               [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
+               [WebSysDescription ("A collection containing all items.")]\r
                public virtual RepeaterItemCollection Items\r
                {\r
                        get\r
                        {\r
-                               if(items != null)\r
+                               if(items == null)\r
                                {\r
-                                       if(itemsArrayList != null)\r
+                                       if(itemsArrayList == null)\r
                                        {\r
                                                EnsureChildControls();\r
                                        }\r
@@ -171,7 +201,10 @@ namespace System.Web.UI.WebControls
                                return items;\r
                        }\r
                }\r
-\r
+
+               [DefaultValue (null), Browsable (false), PersistenceMode (PersistenceMode.InnerProperty)]
+               [TemplateContainer (typeof (RepeaterItem))]
+               [WebSysDescription ("The template that is used to create an item.")]\r
                public virtual ITemplate ItemTemplate\r
                {\r
                        get\r
@@ -183,7 +216,10 @@ namespace System.Web.UI.WebControls
                                itemTemplate = value;\r
                        }\r
                }\r
-\r
+
+               [DefaultValue (null), Browsable (false), PersistenceMode (PersistenceMode.InnerProperty)]
+               [TemplateContainer (typeof (RepeaterItem))]
+               [WebSysDescription ("The template that is used to create a seperator.")]\r
                public virtual ITemplate SeparatorTemplate\r
                {\r
                        get\r
@@ -195,35 +231,121 @@ namespace System.Web.UI.WebControls
                                separatorTemplate = value;\r
                        }\r
                }\r
-\r
-               public override void DataBind()\r
+
+               public override void DataBind ()
+               {
+                       #if NET_1_2
+                       RequiresDataBinding = false;
+                       #endif
+                       OnDataBinding (EventArgs.Empty);
+               }
+
+               protected override void CreateChildControls()
+               {
+                       Controls.Clear ();
+                       if (ViewState[ITEMCOUNT] != null) {
+                               CreateControlHierarchy (false);
+                       } else {
+                               itemsArrayList = new ArrayList ();
+                               ClearChildViewState ();
+                       }
+               }
+
+               private RepeaterItem CreateItem (int itemIndex,\r
+                                                ListItemType itemType,\r
+                                                bool dataBind,\r
+                                                object dataItem)\r
                {\r
-                       OnDataBinding(EventArgs.Empty);\r
+                       RepeaterItem repeaterItem = new RepeaterItem (itemIndex, itemType);\r
+                       RepeaterItemEventArgs repeaterEventArgs = new RepeaterItemEventArgs (repeaterItem);\r
+                       InstantiateItem (repeaterItem);\r
+                       if (dataBind)\r
+                               repeaterItem.DataItem = dataItem;\r
+                       OnItemCreated (repeaterEventArgs);\r
+                       Controls.Add (repeaterItem);\r
+                       if (dataBind) {\r
+                               repeaterItem.DataBind ();\r
+                               OnItemDataBound (repeaterEventArgs);\r
+                               repeaterItem.DataItem = null;\r
+                       }\r
+                       return repeaterItem;\r
                }\r
 \r
-               protected override void CreateChildControls()\r
+               private void InstantiateItem (RepeaterItem item)\r
                {\r
-                       Controls.Clear();\r
-                       if(ViewState[ITEMCOUNT] != null)\r
-                       {\r
-                               CreateControlHierarchy(false);\r
-                       } else\r
-                       {\r
-                               itemsArrayList = new ArrayList();\r
+                       ITemplate template;\r
+                       switch (item.ItemType) {\r
+                               case ListItemType.Header:\r
+                                       template = this.headerTemplate;\r
+                                       break;\r
+                               case ListItemType.Footer:\r
+                                       template = this.footerTemplate;\r
+                                       break;\r
+                               case ListItemType.Item:\r
+                                       template = this.itemTemplate;\r
+                                       break;\r
+                               case ListItemType.AlternatingItem:\r
+                                       template = (alternatingItemTemplate != null ? this.alternatingItemTemplate : itemTemplate);\r
+                                       break;\r
+                               case ListItemType.Separator:\r
+                                       template = this.separatorTemplate;\r
+                                       break;\r
+                               default:\r
+                                       throw new HttpException ("Unknown ListItemType: " + item.ItemType);\r
                        }\r
-                       ClearChildViewState();\r
-               }\r
 \r
-               /// <summary>\r
-               /// Undocumented\r
-               /// </summary>\r
-               [MonoTODO]\r
-               protected void CreateControlHierarchy(bool useDataSource)\r
-               {\r
-                       //TODO: Fille me up\r
-                       throw new NotImplementedException();\r
+                       template.InstantiateIn (item);\r
                }\r
-\r
+
+               protected virtual void CreateControlHierarchy (bool useDataSource)
+               {
+                       if (itemsArrayList != null) {
+                               itemsArrayList.Clear ();
+                       } else {
+                               itemsArrayList = new ArrayList ();
+                       }
+
+                       IEnumerable ds = null;
+                       if (useDataSource) {
+                               ds = GetResolvedDataSource ();
+                       } else {
+                               int itemCount  = (int) ViewState [ITEMCOUNT];
+                               if (itemCount != -1)
+                                       ds = new DataSourceInternal (itemCount);
+                       }
+
+                       if (headerTemplate != null)
+                               CreateItem (-1, ListItemType.Header, useDataSource, null);
+
+                       int index = 0;
+                       if (ds != null) {
+                               bool even = true;
+                               foreach (object item in ds){
+                                       if (separatorTemplate != null && index > 0)
+                                               CreateItem (index - 1, ListItemType.Separator,
+                                                           useDataSource, null);
+
+                                       RepeaterItem repeaterItem;
+                                       ListItemType lType;
+                                       if (!even)
+                                               lType = ListItemType.AlternatingItem;
+                                       else
+                                               lType = ListItemType.Item;
+
+                                       repeaterItem = CreateItem (index, lType, useDataSource, item);
+                                       itemsArrayList.Add (repeaterItem);
+                                       index++;
+                                       even = !even;
+                               }
+                       }
+
+                       if (footerTemplate != null)
+                               CreateItem (-1, ListItemType.Footer, useDataSource, null);
+
+                       if (useDataSource)
+                               ViewState [ITEMCOUNT] = (ds == null) ? -1 : index;
+               }
+
                protected override bool OnBubbleEvent(object sender, EventArgs e)\r
                {\r
                        bool retVal = false;\r
@@ -248,7 +370,8 @@ namespace System.Web.UI.WebControls
                {\r
                        if(Events != null)\r
                        {\r
-                               RepeaterCommandEventHandler rceh = (RepeaterCommandEventHandler)(((IDictionary) ViewState) [ItemCommandEvent]);\r
+                               RepeaterCommandEventHandler rceh = (RepeaterCommandEventHandler) \r
+                                                                       Events [ItemCommandEvent];\r
                                if(rceh != null)\r
                                {\r
                                        rceh(this, e);\r
@@ -260,7 +383,8 @@ namespace System.Web.UI.WebControls
                {\r
                        if(Events != null)\r
                        {\r
-                               RepeaterItemEventHandler rceh = (RepeaterItemEventHandler)(((IDictionary) ViewState) [ItemCreatedEvent]);\r
+                               RepeaterItemEventHandler rceh = (RepeaterItemEventHandler) \r
+                                                                       Events [ItemCreatedEvent];\r
                                if(rceh != null)\r
                                {\r
                                        rceh(this, e);\r
@@ -272,12 +396,119 @@ namespace System.Web.UI.WebControls
                {\r
                        if(Events != null)\r
                        {\r
-                               RepeaterItemEventHandler rceh = (RepeaterItemEventHandler)(((IDictionary) ViewState) [ItemDataBoundEvent]);\r
+                               RepeaterItemEventHandler rceh = (RepeaterItemEventHandler)\r
+                                                                       Events [ItemDataBoundEvent];\r
                                if(rceh != null)\r
                                {\r
                                        rceh(this, e);\r
                                }\r
                        }\r
                }\r
+\r
+               protected virtual RepeaterItem CreateItem (int itemIndex, ListItemType itemType)\r
+               {\r
+                       return new RepeaterItem (itemIndex, itemType);\r
+               }\r
+\r
+               protected virtual void InitializeItem (RepeaterItem item)\r
+               {\r
+                       InstantiateItem (item);\r
+               }
+               
+               #if NET_1_2
+
+                       
+                       // should be `internal protected' (why, oh WHY did they do that !?!)
+                       protected override void OnInit (EventArgs e)
+                       {
+                               base.OnInit(e);
+                               inited = true;
+                               if (!Page.IsPostBack)
+                                       RequiresDataBinding = true;
+                       }
+                       
+                       // should be `internal protected' (why, oh WHY did they do that !?!)
+                       protected override void OnLoad (EventArgs e)
+                       {
+                               IDataSource ds = GetDataSourceObject () as IDataSource;
+                               if (ds != null && DataSourceID != "")
+                                       ds.DataSourceChanged += new EventHandler (OnDataSourceChanged);
+                               
+                               base.OnLoad(e);
+                       }
+                       
+                       // should be `internal protected' (why, oh WHY did they do that !?!)
+                       protected override void OnPreRender (EventArgs e)
+                       {
+                               EnsureDataBound ();
+                               base.OnPreRender (e);
+                       }
+                               
+                       protected void EnsureDataBound ()
+                       {
+                               if (RequiresDataBinding && DataSourceID != "")
+                                       DataBind ();
+                       }
+                       
+                       protected virtual object GetDataSourceObject ()
+                       {
+                               if (DataSourceID != "")
+                                       return (IDataSource) NamingContainer.FindControl (DataSourceID);
+                               
+                               return DataSource;
+                       }
+                       
+                       protected virtual IEnumerable GetResolvedDataSource ()
+                       {
+                               if (DataSource != null && DataSourceID != "")
+                                       throw new HttpException ();
+                               
+                               IDataSource ds = this.GetDataSourceObject () as IDataSource;
+                               if (ds != null && DataSourceID != "")
+                                       return ds.GetView (DataMember).Select ();
+                               else if (DataSource != null)
+                                       return DataSourceHelper.GetResolvedDataSource (DataSource, DataMember);
+                               else
+                                       return null; 
+                       }
+                       
+                       protected void OnDataSourceChanged (object sender, EventArgs e)
+                       {
+                               RequiresDataBinding = true;
+                       }
+                       
+                       public virtual string DataSourceID {
+                               get {
+                                       object o = ViewState ["DataSourceID"];
+                                       if (o != null)
+                                               return (string)o;
+                                       
+                                       return String.Empty;
+                               }
+                               set {
+                                       if (inited)
+                                               RequiresDataBinding = true;
+                                       
+                                       ViewState ["DataSourceID"] = value;
+                               }
+                       }
+                       
+                       bool requiresDataBinding;
+                       protected bool RequiresDataBinding {
+                               get { return requiresDataBinding; }
+                               set { requiresDataBinding = value; }
+                       }
+                       
+                       protected bool inited;
+                               
+               #else
+                       IEnumerable GetResolvedDataSource ()
+                       {
+                               if (DataSource != null)
+                                       return DataSourceHelper.GetResolvedDataSource (DataSource, DataMember);
+                               else
+                                       return null; 
+                       }
+               #endif\r
        }\r
 }\r