* roottypes.cs: Rename from tree.cs.
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / DataList.cs
old mode 100755 (executable)
new mode 100644 (file)
index f73eba1..39aa0b0
@@ -1,42 +1,66 @@
-/**
- * Namespace: System.Web.UI.WebControls
- * Class:     DataList
- *
- * Author:  Gaurav Vaish
- * Maintainer: gvaish@iitk.ac.in
- * Contact: <my_scripts2001@yahoo.com>, <gvaish@iitk.ac.in>
- * Implementation: yes
- * Status:  70%
- *
- * (C) Gaurav Vaish (2001)
- */
-
-using System;
+//
+// System.Web.UI.WebControls.DataList.cs
+//
+// Author:
+//     Sebastien Pouliot  <sebastien@ximian.com>
+//
+// Copyright (C) 2005 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
 using System.Collections;
 using System.ComponentModel;
-using System.Web;
-using System.Web.UI;
+using System.Globalization;
+using System.Security.Permissions;
 using System.Web.Util;
 
-namespace System.Web.UI.WebControls
-{
-       //TODO: [Designer("??")]
-       //TODO: [Editor("??")]
-       public class DataList: BaseDataList, INamingContainer, IRepeatInfoUser
-       {
+namespace System.Web.UI.WebControls {
+
+       // CAS
+       [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
+       [AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
+       // attributes
+       [Designer ("System.Web.UI.Design.WebControls.DataListDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
+#if NET_2_0
+       [ControlValueProperty ("SelectedValue")]
+       [Editor ("System.Web.UI.Design.WebControls.DataListComponentEditor, " + Consts.AssemblySystem_Design, "System.ComponentModel.ComponentEditor, " + Consts.AssemblySystem)]
+#else
+       [Editor ("System.Web.UI.Design.WebControls.DataListComponentEditor, " + Consts.AssemblySystem_Design, typeof (System.ComponentModel.ComponentEditor))]
+#endif
+       public class DataList : BaseDataList, INamingContainer, IRepeatInfoUser {
+
                public const string CancelCommandName = "Cancel";
                public const string DeleteCommandName = "Delete";
-               public const string EditCommandName   = "Edit";
+               public const string EditCommandName = "Edit";
                public const string SelectCommandName = "Select";
                public const string UpdateCommandName = "Update";
 
-               private static readonly object CancelCommandEvent = new object();
-               private static readonly object DeleteCommandEvent = new object();
-               private static readonly object EditCommandEvent   = new object();
-               private static readonly object ItemCommandEvent   = new object();
-               private static readonly object ItemCreatedEvent   = new object();
-               private static readonly object ItemDataBoundEvent = new object();
-               private static readonly object UpdateCommandEvent = new object();
+
+               private static readonly object cancelCommandEvent = new object ();
+               private static readonly object deleteCommandEvent = new object ();
+               private static readonly object editCommandEvent = new object ();
+               private static readonly object itemCommandEvent = new object ();
+               private static readonly object itemCreatedEvent = new object ();
+               private static readonly object itemDataBoundEvent = new object ();
+               private static readonly object updateCommandEvent = new object ();
 
                private TableItemStyle alternatingItemStyle;
                private TableItemStyle editItemStyle;
@@ -53,926 +77,1062 @@ namespace System.Web.UI.WebControls
                private ITemplate itemTemplate;
                private ITemplate selectedItemTemplate;
                private ITemplate separatorTemplate;
-               private ITemplate separatorItemTemplate;
 
-               private ArrayList itemsArray;
                private DataListItemCollection items;
+               private ArrayList list;
+               private int idx;
 
-               private bool extractTemplateRows;
+#if NET_2_0
+               private int editIndex;
+               private int selectedIndex;
 
-               public DataList(): base()
+               public DataList ()
                {
+                       editIndex = -1;
+                       selectedIndex = -1;
+                       idx = -1;
                }
-
-               public virtual TableItemStyle AlternatingItemStyle
+#else
+               public DataList ()
                {
-                       get
-                       {
-                               if(alternatingItemStyle == null)
-                               {
-                                       alternatingItemStyle = new TableItemStyle();
-                                       if(IsTrackingViewState)
-                                               alternatingItemStyle.TrackViewState();
+                       idx = -1;
+               }
+#endif
+
+
+               [DefaultValue (null)]
+               [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
+               [NotifyParentProperty (true)]
+               [PersistenceMode (PersistenceMode.InnerProperty)]
+               [WebSysDescription ("")]
+               [WebCategory ("Style")]
+               public virtual TableItemStyle AlternatingItemStyle {
+                       get {
+                               if (alternatingItemStyle == null) {
+                                       alternatingItemStyle = new TableItemStyle ();
+                                       if (IsTrackingViewState) {
+                                               alternatingItemStyle.TrackViewState ();
+                                       }
                                }
                                return alternatingItemStyle;
                        }
                }
 
-               public virtual ITemplate AlternatingItemTemplate
-               {
-                       get
-                       {
-                               return alternatingItemTemplate;
-                       }
-                       set
-                       {
-                               alternatingItemTemplate = value;
-                       }
+               [Browsable (false)]
+               [DefaultValue (null)]
+               [TemplateContainer (typeof (DataListItem))]
+               [PersistenceMode (PersistenceMode.InnerProperty)]
+               [WebSysDescription ("")]
+               [WebCategory ("Style")]
+               public virtual ITemplate AlternatingItemTemplate {
+                       get { return alternatingItemTemplate; }
+                       set { alternatingItemTemplate = value; }
                }
 
-               public virtual int EditItemIndex
-               {
-                       get
-                       {
-                               object o = ViewState["EditItemIndex"];
-                               if(o != null)
-                                       return (int)o;
-                               return -1;
+               [DefaultValue (-1)]
+               [WebSysDescription ("")]
+               [WebCategory ("Misc")]
+               public virtual int EditItemIndex {
+                       get {
+                               object o = ViewState ["EditItemIndex"];
+                               return (o == null) ? -1 : (int) o;
                        }
-                       set
-                       {
-                               ViewState["EditItemIndex"] = value;
+                       set {
+                               if (value < -1)
+                                       throw new ArgumentOutOfRangeException ("EditItemIndex", "< -1");
+                               ViewState ["EditItemIndex"] = value;
                        }
                }
 
-               public virtual TableItemStyle EditItemStyle
-               {
-                       get
-                       {
-                               if(editItemStyle == null)
-                               {
-                                       editItemStyle = new TableItemStyle();
-                                       if(IsTrackingViewState)
-                                               editItemStyle.TrackViewState();
+               [DefaultValue (null)]
+               [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
+               [NotifyParentProperty (true)]
+               [PersistenceMode (PersistenceMode.InnerProperty)]
+               [WebSysDescription ("")]
+               [WebCategory ("Style")]
+               public virtual TableItemStyle EditItemStyle {
+                       get {
+                               if (editItemStyle == null) {
+                                       editItemStyle = new TableItemStyle ();
+                                       if (IsTrackingViewState) {
+                                               editItemStyle.TrackViewState ();
+                                       }
                                }
                                return editItemStyle;
                        }
                }
 
-               public virtual ITemplate EditItemTemplate
-               {
-                       get
-                       {
-                               return editItemTemplate;
-                       }
-                       set
-                       {
-                               editItemTemplate = value;
-                       }
+               [Browsable (false)]
+               [DefaultValue (null)]
+               [TemplateContainer (typeof (DataListItem))]
+               [PersistenceMode (PersistenceMode.InnerProperty)]
+               [WebSysDescription ("")]
+               [WebCategory ("Style")]
+               public virtual ITemplate EditItemTemplate {
+                       get { return editItemTemplate; }
+                       set { editItemTemplate = value; }
                }
 
-               public virtual bool ExtractTemplateRows
-               {
-                       get
-                       {
-                               object o = ViewState["ExtractTemplateRows"];
-                               if(o != null)
-                                       return (bool)o;
-                               return false;
-                       }
-                       set
-                       {
-                               ViewState["ExtractTemplateRows"] = value;
+               [DefaultValue (false)]
+               [WebSysDescription ("")]
+               [WebCategory ("Misc")]
+               public virtual bool ExtractTemplateRows {
+                       get {
+                               object o = ViewState ["ExtractTemplateRows"];
+                               return (o == null) ? false : (bool) o;
                        }
+                       set { ViewState ["ExtractTemplateRows"] = value; }
                }
 
-               public virtual TableItemStyle FooterStyle
-               {
-                       get
-                       {
-                               if(footerStyle == null)
-                               {
-                                       footerStyle = new TableItemStyle();
-                                       if(IsTrackingViewState)
-                                               footerStyle.TrackViewState();
+               [DefaultValue (null)]
+               [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
+               [NotifyParentProperty (true)]
+               [PersistenceMode (PersistenceMode.InnerProperty)]
+               [WebSysDescription ("")]
+               [WebCategory ("Style")]
+               public virtual TableItemStyle FooterStyle {
+                       get {
+                               if (footerStyle == null) {
+                                       footerStyle = new TableItemStyle ();
+                                       if (IsTrackingViewState) {
+                                               footerStyle.TrackViewState ();
+                                       }
                                }
                                return footerStyle;
                        }
                }
 
-               public virtual ITemplate FooterTemplate
-               {
-                       get
-                       {
-                               return footerTemplate;
-                       }
-                       set
-                       {
-                               footerTemplate = value;
-                       }
+               [Browsable (false)]
+               [DefaultValue (null)]
+               [TemplateContainer (typeof (DataListItem))]
+               [PersistenceMode (PersistenceMode.InnerProperty)]
+               [WebSysDescription ("")]
+               [WebCategory ("Style")]
+               public virtual ITemplate FooterTemplate {
+                       get { return footerTemplate; }
+                       set { footerTemplate = value; }
                }
 
-               public override GridLines GridLines
-               {
-                       get
-                       {
-                               return GridLines;
-                       }
-                       set
-                       {
-                               GridLines = value;
+               // yes! they do NOT match in fx1.1
+               [DefaultValue (GridLines.None)]
+               public override GridLines GridLines {
+                       get {
+                               if (!ControlStyleCreated) {
+#if NET_2_0
+                                       return GridLines.None;
+#else
+                                       return GridLines.Both;
+#endif
+                               }
+                               return TableStyle.GridLines;
                        }
+                       set { TableStyle.GridLines = value; }
                }
 
-               public virtual TableItemStyle HeaderStyle
-               {
-                       get
-                       {
-                               if(headerStyle == null)
-                               {
-                                       headerStyle = new TableItemStyle();
-                                       if(IsTrackingViewState)
-                                               headerStyle.TrackViewState();
+               [DefaultValue (null)]
+               [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
+               [NotifyParentProperty (true)]
+               [PersistenceMode (PersistenceMode.InnerProperty)]
+               [WebSysDescription ("")]
+               [WebCategory ("Style")]
+               public virtual TableItemStyle HeaderStyle {
+                       get {
+                               if (headerStyle == null) {
+                                       headerStyle = new TableItemStyle ();
+                                       if (IsTrackingViewState) {
+                                               headerStyle.TrackViewState ();
+                                       }
                                }
                                return headerStyle;
                        }
                }
 
-               public virtual ITemplate HeaderTemplate
-               {
-                       get
-                       {
-                               return headerTemplate;
-                       }
-                       set
-                       {
-                               headerTemplate = value;
-                       }
+               [Browsable (false)]
+               [DefaultValue (null)]
+               [TemplateContainer (typeof (DataListItem))]
+               [PersistenceMode (PersistenceMode.InnerProperty)]
+               [WebSysDescription ("")]
+               [WebCategory ("Style")]
+               public virtual ITemplate HeaderTemplate {
+                       get { return headerTemplate; }
+                       set { headerTemplate = value; }
                }
 
-               public virtual DataListItemCollection Items
-               {
-                       get
-                       {
-                               if(items == null)
-                               {
-                                       if(itemsArray == null)
-                                       {
-                                               EnsureChildControls();
-                                               itemsArray = new ArrayList();
-                                       }
-                                       items = new DataListItemCollection(itemsArray);
-                               }
+               [Browsable (false)]
+               [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
+               [WebSysDescription ("")]
+               [WebCategory ("Style")]
+               public virtual DataListItemCollection Items {
+                       get {
+                               if (items == null)
+                                       items = new DataListItemCollection (ItemList);
                                return items;
                        }
                }
 
-               public virtual TableItemStyle ItemStyle
-               {
-                       get
-                       {
-                               if(itemStyle == null)
-                               {
-                                       itemStyle = new TableItemStyle();
-                                       if(IsTrackingViewState)
-                                               itemStyle.TrackViewState();
+               [DefaultValue (null)]
+               [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
+               [NotifyParentProperty (true)]
+               [PersistenceMode (PersistenceMode.InnerProperty)]
+               [WebSysDescription ("")]
+               [WebCategory ("Style")]
+               public virtual TableItemStyle ItemStyle {
+                       get {
+                               if (itemStyle == null) {
+                                       itemStyle = new TableItemStyle ();
+                                       if (IsTrackingViewState) {
+                                               itemStyle.TrackViewState ();
+                                       }
                                }
                                return itemStyle;
                        }
                }
 
-               public virtual ITemplate ItemTemplate
-               {
-                       get
-                       {
-                               return itemTemplate;
-                       }
-                       set
-                       {
-                               itemTemplate = value;
-                       }
+               [Browsable (false)]
+               [DefaultValue (null)]
+               [TemplateContainer (typeof (DataListItem))]
+               [PersistenceMode (PersistenceMode.InnerProperty)]
+               [WebSysDescription ("")]
+               [WebCategory ("Style")]
+               public virtual ITemplate ItemTemplate {
+                       get { return itemTemplate; }
+                       set { itemTemplate = value; }
                }
 
-               public virtual int RepeatColumns
-               {
-                       get
-                       {
-                               object o = ViewState["RepeatColumns"];
-                               if(o != null)
-                                       return (int)o;
-                               return 0;
-                       }
-                       set
-                       {
-                               if(value < 0)
-                                       throw new ArgumentOutOfRangeException("value");
-                               ViewState["RepeatColumns"] = value;
+#if ONLY_1_1
+               [Bindable (true)]
+#endif
+               [DefaultValue (0)]
+               [WebSysDescription ("")]
+               [WebCategory ("Layout")]
+               public virtual int RepeatColumns {
+                       get {
+                               object o = ViewState ["RepeatColumns"];
+                               return (o == null) ? 0 : (int) o;
+                       }
+                       set { 
+                               if (value < 0)
+                                       throw new ArgumentOutOfRangeException ("value", "RepeatColumns value has to be 0 for 'not set' or > 0.");
+                               
+                               ViewState ["RepeatColumns"] = value; 
                        }
                }
 
-               public virtual RepeatDirection RepeatDirection
-               {
-                       get
-                       {
-                               object o = ViewState["RepeatDirection"];
-                               if(o != null)
-                                       return (RepeatDirection)o;
-                               return RepeatDirection.Vertical;
-                       }
-                       set
-                       {
-                               if(!Enum.IsDefined(typeof(RepeatDirection), value))
-                                       throw new ArgumentException();
-                               ViewState["RepeatDirection"] = value;
-                       }
+#if ONLY_1_1
+               [Bindable (true)]
+#endif
+               [DefaultValue (RepeatDirection.Vertical)]
+               [WebSysDescription ("")]
+               [WebCategory ("Layout")]
+               public virtual RepeatDirection RepeatDirection {
+                       get {
+                               object o = ViewState ["RepeatDirection"];
+                               return (o == null) ? RepeatDirection.Vertical : (RepeatDirection) o;
+                       }
+                       set { ViewState ["RepeatDirection"] = value; }
                }
 
-               public virtual RepeatLayout RepeatLayout
-               {
-                       get
-                       {
-                               object o = ViewState["RepeatLayout"];
-                               if(o != null)
-                                       return (RepeatLayout)o;
-                               return RepeatLayout.Table;
-                       }
-                       set
-                       {
-                               if(!Enum.IsDefined(typeof(RepeatLayout), value))
-                                       throw new ArgumentException();
-                               ViewState["RepeatLayout"] = value;
-                       }
+#if ONLY_1_1
+               [Bindable (true)]
+#endif
+               [DefaultValue (RepeatLayout.Table)]
+               [WebSysDescription ("")]
+               [WebCategory ("Layout")]
+               public virtual RepeatLayout RepeatLayout {
+                       get {
+                               object o = ViewState ["RepeatLayout"];
+                               return (o == null) ? RepeatLayout.Table : (RepeatLayout) o;
+                       }
+                       set { ViewState ["RepeatLayout"] = value; }
                }
 
-               public virtual int SelectedIndex
-               {
-                       get
-                       {
-                               object o = ViewState["SelectedIndex"];
-                               if(o != null)
-                                       return (int)o;
-                               return -1;
-                       }
-                       set
-                       {
-                               //FIXME: Looks like a bug in Microsoft's specs.
-                               // Exception is missing in document. I haven't tested the case
-                               // But I think exception should follow
-                               if(value < -1)
-                                       throw new ArgumentOutOfRangeException("value");
-                               int prevSel = SelectedIndex;
-                               ViewState["SelectedIndex"] = value;
-                               DataListItem prevSelItem;
-                               ListItemType liType;
-                               if(itemsArray != null)
-                               {
-                                       if(prevSel >= 0 && prevSel < itemsArray.Count)
-                                       {
-                                               prevSelItem = (DataListItem)itemsArray[prevSel];
-                                               if(prevSelItem.ItemType != ListItemType.EditItem)
-                                               {
-                                                       liType = ( (prevSel % 2) == 0 ? ListItemType.AlternatingItem : ListItemType.Item );
-                                                       prevSelItem.SetItemType(liType);
-                                               }
-                                       }
-                                       if(value >= 0 && value < itemsArray.Count)
-                                       {
-                                               prevSelItem = (DataListItem) itemsArray[value];
-                                               if(prevSelItem.ItemType != ListItemType.EditItem)
-                                               {
-                                                       prevSelItem.SetItemType(ListItemType.SelectedItem);
-                                               }
-                                       }
-                               }
+               [Bindable (true)]
+               [DefaultValue (-1)]
+               [WebSysDescription ("")]
+               [WebCategory ("Layout")]
+               public virtual int SelectedIndex {
+                       get {
+                               object o = ViewState ["SelectedIndex"];
+                               return (o == null) ? -1 : (int) o;
+                       }
+                       set {
+                               if (value < -1)
+                                       throw new ArgumentOutOfRangeException ("SelectedIndex", "< -1");
+                               ViewState ["SelectedIndex"] = value;
                        }
                }
 
-               public virtual DataListItem SelectedItem
-               {
-                       get
-                       {
-                               if(SelectedIndex == -1)
+               [Browsable (false)]
+               [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
+               [WebSysDescription ("")]
+               [WebCategory ("Layout")]
+               public virtual DataListItem SelectedItem {
+                       get {
+                               if (SelectedIndex < 0)
                                        return null;
-                               return Items[SelectedIndex];
+                               if (SelectedIndex >= Items.Count)
+                                       throw new ArgumentOutOfRangeException ("SelectedItem", ">= Items.Count");
+                               return items [SelectedIndex];
                        }
                }
 
-               public virtual TableItemStyle SelectedItemStyle
-               {
-                       get
-                       {
-                               if(selectedItemStyle == null)
-                               {
-                                       selectedItemStyle = new TableItemStyle();
-                                       if(IsTrackingViewState)
-                                               selectedItemStyle.TrackViewState();
+               [DefaultValue (null)]
+               [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
+               [NotifyParentProperty (true)]
+               [PersistenceMode (PersistenceMode.InnerProperty)]
+               [WebSysDescription ("")]
+               [WebCategory ("Style")]
+               public virtual TableItemStyle SelectedItemStyle {
+                       get {
+                               if (selectedItemStyle == null) {
+                                       selectedItemStyle = new TableItemStyle ();
+                                       if (IsTrackingViewState) {
+                                               selectedItemStyle.TrackViewState ();
+                                       }
                                }
                                return selectedItemStyle;
                        }
                }
 
-               public virtual ITemplate SelectedItemTemplate
-               {
-                       get
-                       {
-                               return selectedItemTemplate;
-                       }
-                       set
-                       {
-                               selectedItemTemplate = value;
-                       }
+               [Browsable (false)]
+               [DefaultValue (null)]
+               [TemplateContainer (typeof (DataListItem))]
+               [PersistenceMode (PersistenceMode.InnerProperty)]
+               [WebSysDescription ("")]
+               [WebCategory ("Style")]
+               public virtual ITemplate SelectedItemTemplate {
+                       get { return selectedItemTemplate; }
+                       set { selectedItemTemplate = value; }
                }
 
-               public virtual TableItemStyle SeparatorStyle
-               {
-                       get
-                       {
-                               if(separatorStyle == null)
-                               {
-                                       separatorStyle = new TableItemStyle();
-                                       if(IsTrackingViewState)
-                                               separatorStyle.TrackViewState();
+               [DefaultValue (null)]
+               [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
+               [NotifyParentProperty (true)]
+               [PersistenceMode (PersistenceMode.InnerProperty)]
+               [WebSysDescription ("")]
+               [WebCategory ("Style")]
+               public virtual TableItemStyle SeparatorStyle {
+                       get {
+                               if (separatorStyle == null) {
+                                       separatorStyle = new TableItemStyle ();
+                                       if (IsTrackingViewState) {
+                                               separatorStyle.TrackViewState ();
+                                       }
                                }
                                return separatorStyle;
                        }
                }
 
-               public virtual ITemplate SeparatorTemplate
-               {
-                       get
-                       {
-                               return separatorTemplate;
-                       }
-                       set
-                       {
-                               separatorTemplate = value;
-                       }
+               [Browsable (false)]
+               [DefaultValue (null)]
+               [TemplateContainer (typeof (DataListItem))]
+               [PersistenceMode (PersistenceMode.InnerProperty)]
+               [WebSysDescription ("")]
+               [WebCategory ("Style")]
+               public virtual ITemplate SeparatorTemplate {
+                       get { return separatorTemplate; }
+                       set { separatorTemplate = value; }
                }
 
-               public virtual ITemplate SeparatorItemTemplate
-               {
-                       get
-                       {
-                               return separatorItemTemplate;
-                       }
-                       set
-                       {
-                               separatorItemTemplate = value;
-                       }
+#if ONLY_1_1
+               [Bindable (true)]
+#endif
+               [DefaultValue (true)]
+               [WebSysDescription ("")]
+               [WebCategory ("Appearance")]
+               public virtual bool ShowFooter {
+                       get {
+                               object o = ViewState ["ShowFooter"];
+                               return (o == null) ? true : (bool) o;
+                       }
+                       set { ViewState ["ShowFooter"] = value; }
                }
 
-               public virtual bool ShowHeader
-               {
-                       get
-                       {
-                               object o = ViewState["ShowHeader"];
-                               if(o!=null)
-                                       return (bool)o;
-                               return true;
-                       }
-                       set
-                       {
-                               ViewState["ShowHeader"] = value;
-                       }
+#if ONLY_1_1
+               [Bindable (true)]
+#endif
+               [DefaultValue (true)]
+               [WebSysDescription ("")]
+               [WebCategory ("Appearance")]
+               public virtual bool ShowHeader {
+                       get {
+                               object o = ViewState ["ShowHeader"];
+                               return (o == null) ? true : (bool) o;
+                       }
+                       set { ViewState ["ShowHeader"] = value; }
                }
 
-               public virtual bool ShowFooter
-               {
-                       get
-                       {
-                               object o = ViewState["ShowFooter"];
-                               if(o!=null)
-                                       return (bool)o;
-                               return true;
-                       }
-                       set
-                       {
-                               ViewState["ShowFooter"] = value;
+#if NET_2_0
+               [MonoTODO ("incomplete")]
+               [Browsable (false)]
+               public object SelectedValue {
+                       get {
+                               if (DataKeyField.Length == 0)
+                                       throw new InvalidOperationException (Locale.GetText ("No DataKeyField present."));
+
+                               if ((SelectedIndex >= 0) && (selectedIndex < DataKeys.Count)) {
+                                       return DataKeys [selectedIndex];
+                               }
+
+                               return null;
                        }
                }
 
-               public event DataListCommandEventHandler CancelCommand
-               {
-                       add
-                       {
-                               Events.AddHandler(CancelCommandEvent, value);
-                       }
-                       remove
-                       {
-                               Events.RemoveHandler(CancelCommandEvent, value);
-                       }
+               protected override HtmlTextWriterTag TagKey {
+                       get { return HtmlTextWriterTag.Table; }
                }
+#endif
 
-               public event DataListCommandEventHandler DeleteCommand
-               {
-                       add
-                       {
-                               Events.AddHandler(DeleteCommandEvent, value);
-                       }
-                       remove
-                       {
-                               Events.RemoveHandler(DeleteCommandEvent, value);
+               private TableStyle TableStyle {
+                       // this will throw an InvalidCasException just like we need
+                       get { return (TableStyle) ControlStyle; }
+               }
+               
+               private ArrayList ItemList {
+                       get {
+                               if (list == null)
+                                       list = new ArrayList ();
+                               return list;
                        }
                }
 
-               public event DataListCommandEventHandler EditCommand
+               void DoItem (int i, ListItemType t, object d, bool databind)
                {
-                       add
-                       {
-                               Events.AddHandler(EditCommandEvent, value);
-                       }
-                       remove
-                       {
-                               Events.RemoveHandler(EditCommandEvent, value);
+                       DataListItem itm = CreateItem (i, t);
+                       if (databind)
+                               itm.DataItem = d;
+                       DataListItemEventArgs e = new DataListItemEventArgs (itm);
+                       InitializeItem (itm);
+                       
+                       //
+                       // It is very important that this be called *before* data
+                       // binding. Otherwise, we won't save our state in the viewstate.
+                       //
+                       Controls.Add (itm);
+                       if (i != -1)
+                               ItemList.Add (itm);
+
+                       OnItemCreated (e);
+
+                       if (databind) {
+                               itm.DataBind ();
+                               OnItemDataBound (e);
+                               itm.DataItem = null;
                        }
                }
 
-               public event DataListCommandEventHandler ItemCommand
+               private void DoItemInLoop (int i, object d, bool databind, ListItemType type)
                {
-                       add
-                       {
-                               Events.AddHandler(ItemCommandEvent, value);
-                       }
-                       remove
-                       {
-                               Events.RemoveHandler(ItemCommandEvent, value);
-                       }
+                       DoItem (i, type, d, databind);
+                       if (SeparatorTemplate != null)
+                               DoItem (i, ListItemType.Separator, null, databind);
+
                }
 
-               public event DataListCommandEventHandler ItemCreated
+               protected override void CreateControlHierarchy (bool useDataSource)
                {
-                       add
-                       {
-                               Events.AddHandler(ItemCreatedEvent, value);
-                       }
-                       remove
-                       {
-                               Events.RemoveHandler(ItemCreatedEvent, value);
+                       Controls.Clear();
+
+                       IEnumerable ds = null;
+                       ArrayList keys = null;
+
+                       if (useDataSource) {
+                               idx = 0;
+#if NET_2_0
+                               if (IsBoundUsingDataSourceID)
+                                       ds = GetData();
+                               else
+#endif
+                               ds = DataSourceResolver.ResolveDataSource (DataSource, DataMember);
+                               keys = DataKeysArray;
+                               keys.Clear ();
+                       } else {
+                               idx = (int) ViewState ["Items"];
+                       }
+
+                       if ((ds == null) && (idx == 0))
+                               return;
+
+                       if (headerTemplate != null)
+                               DoItem (-1, ListItemType.Header, null, useDataSource);
+
+                       // items
+                       int selected_index = SelectedIndex;
+                       int edit_item_index = EditItemIndex;
+                       ListItemType type;
+                       if (ds != null) {
+                               string key = DataKeyField;
+                               foreach (object o in ds) {
+                                       if (useDataSource && key != "")
+                                               keys.Add (DataBinder.GetPropertyValue (o, key));
+                                       type = ListItemType.Item;
+                                       if (idx == edit_item_index) 
+                                               type = ListItemType.EditItem;
+                                       else if (idx == selected_index) 
+                                               type = ListItemType.SelectedItem;
+                                       else if (idx % 2 != 0) 
+                                               type = ListItemType.AlternatingItem;
+
+                                       DoItemInLoop (idx, o, useDataSource, type);
+                                       idx++;
+                               }
+                       } else {
+                               for (int i = 0; i < idx; i++) {
+                                       type = ListItemType.Item;
+                                       if (idx == edit_item_index) 
+                                               type = ListItemType.EditItem;
+                                       else if (idx == selected_index) 
+                                               type = ListItemType.SelectedItem;
+                                       else if (idx % 2 != 0) 
+                                               type = ListItemType.AlternatingItem;
+
+                                       DoItemInLoop (i, null, useDataSource, type);
+                               }
                        }
+
+                       if (footerTemplate != null)
+                               DoItem (-1, ListItemType.Footer, null, useDataSource);
+
+                       ViewState ["Items"] = idx;
                }
 
-               public event DataListCommandEventHandler ItemDataBound
+               protected override Style CreateControlStyle ()
                {
-                       add
-                       {
-                               Events.AddHandler(ItemDataBoundEvent, value);
-                       }
-                       remove
-                       {
-                               Events.RemoveHandler(ItemDataBoundEvent, value);
-                       }
+#if NET_2_0
+                       // not kept (directly) in the DataList ViewState
+                       return new TableStyle ();
+#else
+                       TableStyle tableStyle = new TableStyle (ViewState);
+                       tableStyle.CellSpacing = 0;
+                       return tableStyle;
+#endif
                }
 
-               public event DataListCommandEventHandler UpdateCommand
+               protected virtual DataListItem CreateItem (int itemIndex, ListItemType itemType)
                {
-                       add
-                       {
-                               Events.AddHandler(UpdateCommandEvent, value);
-                       }
-                       remove
-                       {
-                               Events.RemoveHandler(UpdateCommandEvent, value);
-                       }
+                       return new DataListItem (itemIndex, itemType);
                }
 
-               protected override Style CreateControlStyle()
+               protected virtual void InitializeItem (DataListItem item)
                {
-                       TableStyle retVal = new TableStyle(ViewState);
-                       retVal.CellSpacing = 0;
-                       return retVal;
+                       ITemplate t = null;
+                       
+                       switch (item.ItemType) {
+                       case ListItemType.Header:
+                               t = HeaderTemplate;
+                               break;
+                       case ListItemType.Footer:
+                               t = FooterTemplate;
+                               break;  
+                       case ListItemType.Separator:
+                               t = SeparatorTemplate;
+                               break;
+                       case ListItemType.Item:
+                       case ListItemType.AlternatingItem:
+                       case ListItemType.SelectedItem:
+                       case ListItemType.EditItem:
+                               int index = item.ItemIndex;
+                               if ((EditItemIndex == index) && (EditItemTemplate != null))
+                                       t = EditItemTemplate;
+                               else if ((SelectedIndex == index) && (SelectedItemTemplate != null))
+                                       t = SelectedItemTemplate;
+                               else if (((index & 1) == 0) || (alternatingItemTemplate == null))
+                                       t = ItemTemplate;
+                               else
+                                       t = alternatingItemTemplate;
+                               break;
+                       }
+
+                       if (t != null)
+                               t.InstantiateIn (item);
                }
 
-               protected override void LoadViewState(object savedState)
-               {
-                       object[] states;
-                       if(savedState != null && (states = (object[])savedState) != null)
-                       {
-                               if(states[0] != null)
-                                       LoadViewState(states[0]);
-                               if(states[1] != null)
-                                       alternatingItemStyle.LoadViewState(states[1]);
-                               if(states[2] != null)
-                                       editItemStyle.LoadViewState(states[2]);
-                               if(states[3] != null)
-                                       footerStyle.LoadViewState(states[3]);
-                               if(states[4] != null)
-                                       headerStyle.LoadViewState(states[4]);
-                               if(states[5] != null)
-                                       itemStyle.LoadViewState(states[5]);
-                               if(states[6] != null)
-                                       selectedItemStyle.LoadViewState(states[6]);
-                               if(states[7] != null)
-                                       separatorStyle.LoadViewState(states[7]);
-                       }
-               }
-               protected override object SaveViewState()
-               {
-                       object[] states = new object[8];
-                       states[0] = SaveViewState();
-                       states[1] = (alternatingItemStyle == null ? null : alternatingItemStyle.SaveViewState());
-                       states[2] = (editItemStyle == null        ? null : editItemStyle.SaveViewState());
-                       states[3] = (footerStyle == null          ? null : footerStyle.SaveViewState());
-                       states[4] = (headerStyle == null          ? null : headerStyle.SaveViewState());
-                       states[5] = (itemStyle == null            ? null : itemStyle.SaveViewState());
-                       states[6] = (selectedItemStyle == null    ? null : selectedItemStyle.SaveViewState());
-                       states[7] = (separatorStyle == null       ? null : separatorStyle.SaveViewState());
-                       return states;
-               }
-
-               protected override void TrackViewState()
+               protected override void LoadViewState (object savedState)
                {
-                       TrackViewState();
-                       if(alternatingItemStyle != null)
-                               alternatingItemStyle.TrackViewState();
-                       if(editItemStyle != null)
-                               editItemStyle.TrackViewState();
-                       if(footerStyle != null)
-                               footerStyle.TrackViewState();
-                       if(headerStyle != null)
-                               headerStyle.TrackViewState();
-                       if(itemStyle != null)
-                               itemStyle.TrackViewState();
-                       if(selectedItemStyle != null)
-                               selectedItemStyle.TrackViewState();
-                       if(separatorStyle != null)
-                               separatorStyle.TrackViewState();
-               }
-
-               protected override bool OnBubbleEvent(object source, EventArgs e)
-               {
-                       bool retVal = false;
-                       if(e is DataListCommandEventArgs)
-                       {
-                               DataListCommandEventArgs dlcea = (DataListCommandEventArgs)e;
-                               OnItemCommand(dlcea);
-                               retVal = true;
-                               if(String.Compare(dlcea.CommandName, "Cancel") == 0)
-                               {
-                                       OnCancelCommand(dlcea);
-                               }
-                               if(String.Compare(dlcea.CommandName, "Delete") == 0)
-                               {
-                                       OnDeleteCommand(dlcea);
-                               }
-                               if(String.Compare(dlcea.CommandName, "Edit") == 0)
-                               {
-                                       OnEditCommand(dlcea);
-                               }
-                               if(String.Compare(dlcea.CommandName, "Select") == 0)
-                               {
-                                       SelectedIndex = dlcea.Item.ItemIndex;
-                                       OnSelectedIndexChanged(EventArgs.Empty);
-                               }
-                               if(String.Compare(dlcea.CommandName, "Update") == 0)
-                               {
-                                       OnUpdateCommand(dlcea);
-                               }
-                       }
-                       return retVal;
+                       object[] state = (object[]) savedState;
+#if NET_2_0
+                       base.LoadViewState (state [8]);
+#else
+                       base.LoadViewState (state [0]);
+#endif
+                       if (state [1] != null)
+                               ItemStyle.LoadViewState (state [1]);
+                       if (state [2] != null)
+                               SelectedItemStyle.LoadViewState (state [2]);
+                       if (state [3] != null)
+                               AlternatingItemStyle.LoadViewState (state [3]);
+                       if (state [4] != null)
+                               EditItemStyle.LoadViewState (state [4]);
+                       if (state [5] != null)
+                               SeparatorStyle.LoadViewState (state [5]);
+                       if (state [6] != null)
+                               HeaderStyle.LoadViewState (state [6]);
+                       if (state [7] != null)
+                               FooterStyle.LoadViewState (state [7]);
                }
 
-               protected virtual void OnCancelCommand(DataListCommandEventArgs e)
+               protected override bool OnBubbleEvent (object source, EventArgs e)
                {
-                       if(Events != null)
-                       {
-                               DataListCommandEventHandler dlceh = (DataListCommandEventHandler)(Events[CancelCommandEvent]);
-                               if(dlceh != null)
-                                       dlceh(this, e);
+                       DataListCommandEventArgs dlca = (e as DataListCommandEventArgs);
+                       if (dlca == null)
+                               return false;
+
+                       string cn = dlca.CommandName;
+                       CultureInfo inv = CultureInfo.InvariantCulture;
+
+                       OnItemCommand (dlca);
+                       if (String.Compare (cn, CancelCommandName, true, inv) == 0) {
+                               OnCancelCommand (dlca);
+                               return true;
+                       } else if (String.Compare (cn, DeleteCommandName, true, inv) == 0) {
+                               OnDeleteCommand (dlca);
+                               return true;
+                       } else if (String.Compare (cn, EditCommandName, true, inv) == 0) {
+                               OnEditCommand (dlca);
+                               return true;
+                       } else if (String.Compare (cn, SelectCommandName, true, inv) == 0) {
+                               OnSelectedIndexChanged (dlca);
+                               return true;
+                       } else if (String.Compare (cn, UpdateCommandName, true, inv) == 0) {
+                               OnUpdateCommand (dlca);
+                               return true;
                        }
+                       return false;
                }
 
-               protected virtual void OnDeleteCommand(DataListCommandEventArgs e)
+               protected virtual void OnCancelCommand (DataListCommandEventArgs e)
                {
-                       if(Events != null)
-                       {
-                               DataListCommandEventHandler dlceh = (DataListCommandEventHandler)(Events[DeleteCommandEvent]);
-                               if(dlceh != null)
-                                       dlceh(this, e);
-                       }
+                       DataListCommandEventHandler cancelCommand = (DataListCommandEventHandler) Events [cancelCommandEvent];
+                       if (cancelCommand != null)
+                               cancelCommand (this, e);
                }
 
-               protected virtual void OnEditCommand(DataListCommandEventArgs e)
+               protected virtual void OnDeleteCommand (DataListCommandEventArgs e)
                {
-                       if(Events != null)
-                       {
-                               DataListCommandEventHandler dlceh = (DataListCommandEventHandler)(Events[EditCommandEvent]);
-                               if(dlceh != null)
-                                       dlceh(this, e);
-                       }
+                       DataListCommandEventHandler deleteCommand = (DataListCommandEventHandler) Events [deleteCommandEvent];
+                       if (deleteCommand != null)
+                               deleteCommand (this, e);
                }
 
-               protected virtual void OnItemCommand(DataListCommandEventArgs e)
+               protected virtual void OnEditCommand (DataListCommandEventArgs e)
                {
-                       if(Events != null)
-                       {
-                               DataListCommandEventHandler dlceh = (DataListCommandEventHandler)(Events[ItemCommandEvent]);
-                               if(dlceh != null)
-                                       dlceh(this, e);
-                       }
+                       DataListCommandEventHandler editCommand = (DataListCommandEventHandler) Events [editCommandEvent];
+                       if (editCommand != null)
+                               editCommand (this, e);
+               }
+#if NET_2_0
+               protected internal override void OnInit (EventArgs e)
+               {
+                       // EditItemIndex and SelectedIndex now use the Control State (i.e not the View State)
+                       Page.RegisterRequiresControlState (this);
+                       base.OnInit (e);
+               }
+#endif
+               protected virtual void OnItemCommand (DataListCommandEventArgs e)
+               {
+                       DataListCommandEventHandler itemCommand = (DataListCommandEventHandler) Events [itemCommandEvent];
+                       if (itemCommand != null)
+                               itemCommand (this, e);
                }
 
-               protected virtual void OnItemCreated(DataListItemEventArgs e)
+               protected virtual void OnItemCreated (DataListItemEventArgs e)
                {
-                       if(Events != null)
-                       {
-                               DataListItemEventHandler dlceh = (DataListItemEventHandler)(Events[ItemCreatedEvent]);
-                               if(dlceh != null)
-                                       dlceh(this, e);
-                       }
+                       DataListItemEventHandler itemCreated = (DataListItemEventHandler) Events [itemCreatedEvent];
+                       if (itemCreated != null)
+                               itemCreated (this, e);
                }
 
-               protected virtual void OnItemDataBound(DataListItemEventArgs e)
+               protected virtual void OnItemDataBound (DataListItemEventArgs e)
                {
-                       if(Events != null)
-                       {
-                               DataListItemEventHandler dlceh = (DataListItemEventHandler)(Events[ItemDataBoundEvent]);
-                               if(dlceh != null)
-                                       dlceh(this, e);
-                       }
+                       DataListItemEventHandler itemDataBound = (DataListItemEventHandler) Events [itemDataBoundEvent];
+                       if (itemDataBound != null)
+                               itemDataBound (this, e);
                }
 
-               protected virtual void OnUpdateCommand(DataListCommandEventArgs e)
+               protected virtual void OnUpdateCommand (DataListCommandEventArgs e)
                {
-                       if(Events != null)
-                       {
-                               DataListCommandEventHandler dlceh = (DataListCommandEventHandler)(Events[UpdateCommandEvent]);
-                               if(dlceh != null)
-                                       dlceh(this, e);
-                       }
+                       DataListCommandEventHandler updateCommand = (DataListCommandEventHandler) Events [updateCommandEvent];
+                       if (updateCommand != null)
+                               updateCommand (this, e);
                }
 
-               protected override void RenderContents(HtmlTextWriter writer)
+               void ApplyControlStyle (Control ctrl, Style style)
                {
-                       if(Controls.Count > 0)
-                       {
-                               RepeatInfo repeater       = new RepeatInfo();
-                               Table      templateTable  = null;
-                               if(extractTemplateRows)
-                               {
-                                       repeater.RepeatDirection = RepeatDirection.Vertical;
-                                       repeater.RepeatLayout    = RepeatLayout.Flow;
-                                       repeater.RepeatColumns   = 1;
-                                       repeater.OuterTableImplied = true;
-                                       
-                                       templateTable = new Table();
-                                       templateTable.ID = ClientID;
-                                       templateTable.CopyBaseAttributes(this);
-                                       templateTable.ApplyStyle(ControlStyle);
-                                       templateTable.RenderBeginTag(writer);
-                               } else
-                               {
-                                       repeater.RepeatDirection = RepeatDirection;
-                                       repeater.RepeatLayout    = RepeatLayout;
-                                       repeater.RepeatColumns   = RepeatColumns;
-                               }
-                               repeater.RenderRepeater(writer, this, ControlStyle, this);
-                               if(templateTable != null)
-                               {
-                                       templateTable.RenderEndTag(writer);
+                       if (style == null || false == ctrl.HasControls ())
+                               return;
+
+                       foreach (Control c in ctrl.Controls) {
+                               if (c is Table) {
+                                       Table tbl = (Table) c;
+                                       foreach (TableRow row in tbl.Rows)
+                                               row.MergeStyle (style);
                                }
                        }
                }
 
-               private DataListItem GetItem(ListItemType itemType, int repeatIndex)
+               protected override void PrepareControlHierarchy ()
                {
-                       DataListItem retVal = null;
-                       switch(itemType)
-                       {
-                               case ListItemType.Header: retVal = (DataListItem)Controls[0];
-                                                         break;
-                               case ListItemType.Footer: retVal = (DataListItem)Controls[Controls.Count - 1];
-                                                         break;
-                               case ListItemType.Item:   goto case ListItemType.EditItem;
-                               case ListItemType.AlternatingItem: goto case ListItemType.EditItem;
-                               case ListItemType.SelectedItem: goto case ListItemType.EditItem;
-                               case ListItemType.EditItem: retVal = (DataListItem)Controls[repeatIndex];
-                                                          break;
-                               case ListItemType.Separator: int index = 2 * repeatIndex + 1;
-                                                            if(headerTemplate != null)
-                                                               index ++;
-                                                            retVal = (DataListItem)Controls[index];
-                                                            break;
-                       }
-                       return retVal;
-               }
-
-               /// <summary>
-               /// Undocumented
-               /// </summary>
-               protected override void CreateControlHierarchy(bool useDataSource)
-               {
-                       IEnumerable source = null;
-                       ArrayList          dkeys   = DataKeysArray;
-                       if(itemsArray != null)
-                               itemsArray.Clear();
-                       else
-                               itemsArray = new ArrayList();
-                       extractTemplateRows = ExtractTemplateRows;
-                       if(!useDataSource)
-                       {
-                               int count = (int)ViewState["_!ItemCount"];
-                               if(count != -1)
-                               {
-                                       source = new DataSourceInternal(count);
-                                       itemsArray.Capacity = count;
-                               }
-                       } else
-                       {
-                               dkeys.Clear();
-                               source = DataSourceHelper.GetResolvedDataSource(DataSource, DataMember);
-                               if(source != null && source is ICollection)
-                               {
-                                       dkeys.Capacity = ((ICollection)source).Count;
-                                       itemsArray.Capacity = ((ICollection)source).Count;
-                               }
-                       }
-                       IEnumerator listEnumerator = null;
-                       int         itemCount      = 0;
-                       if(source != null)
-                       {
-                               int index          = 0;
-                               int editIndex      = EditItemIndex;
-                               int selIndex       = SelectedIndex;
-                               string dataKey     = DataKeyField;
-                               
-                               bool useDB = (useDataSource ? (dataKey.Length != 0) : false);
-                               
-                               if(headerTemplate != null)
-                               {
-                                       CreateItem(-1, 0, useDataSource, null);
-                               }
-                               listEnumerator = source.GetEnumerator();
-                               try
-                               {
-                                       while(listEnumerator.MoveNext())
-                                       {
-                                               object current = listEnumerator.Current;
-                                               if(useDB)
-                                               {
-                                                       dkeys.Add(DataBinder.GetPropertyValue(current, dataKey));
-                                               }
-                                               ListItemType type = ListItemType.Item;
-                                               if(index == editIndex)
-                                               {
-                                                       type = ListItemType.EditItem;
-                                               } else if(index == selIndex)
-                                               {
-                                                       type = ListItemType.SelectedItem;
-                                               } else if((index % 2) != 0)
-                                               {
-                                                       type = ListItemType.AlternatingItem;
+                       if (!HasControls () || Controls.Count == 0)
+                               return; // No one called CreateControlHierarchy() with DataSource != null
+
+                       Style alt = null;
+                       foreach (DataListItem item in Controls) {
+                               switch (item.ItemType) {
+                               case ListItemType.Item:
+                                       item.MergeStyle (itemStyle);
+                                       ApplyControlStyle (item, itemStyle);
+                                       break;
+                               case ListItemType.AlternatingItem:
+                                       if (alt == null) {
+                                               if (alternatingItemStyle != null) {
+                                                       alt = new TableItemStyle ();
+                                                       alt.CopyFrom (itemStyle);
+                                                       alt.CopyFrom (alternatingItemStyle);
+                                               } else {
+                                                       alt = itemStyle;
                                                }
-                                               itemsArray.Add(CreateItem(index, type, useDataSource, current));
-                                               if(separatorTemplate != null)
-                                                       CreateItem(index, ListItemType.Separator, useDataSource, null);
-                                               itemCount++;
-                                               index++;
                                        }
-                               } finally
-                               {
-                                       if(listEnumerator is IDisposable)
-                                       {
-                                               ((IDisposable)listEnumerator).Dispose();
+
+                                       item.MergeStyle (alt);
+                                       ApplyControlStyle (item, alt);
+                                       break;
+                               case ListItemType.EditItem:
+                                       if (editItemStyle != null) {
+                                               item.MergeStyle (editItemStyle);
+                                               ApplyControlStyle (item, editItemStyle);
+                                       } else {
+                                               item.MergeStyle (itemStyle);
+                                               ApplyControlStyle (item, itemStyle);
+                                       }
+                                       break;
+                               case ListItemType.Footer:
+                                       if (!ShowFooter) {
+                                               item.Visible = false;
+                                               break;
+                                       }
+                                       if (footerStyle != null) {
+                                               item.MergeStyle (footerStyle);
+                                               ApplyControlStyle (item, footerStyle);
                                        }
+                                       break;
+                               case ListItemType.Header:
+                                       if (!ShowHeader) {
+                                               item.Visible = false;
+                                               break;
+                                       }
+                                       if (headerStyle != null) {
+                                               item.MergeStyle (headerStyle);
+                                               ApplyControlStyle (item, headerStyle);
+                                       }
+                                       break;
+                               case ListItemType.SelectedItem:
+                                       if (selectedItemStyle != null) {
+                                               item.MergeStyle (selectedItemStyle);
+                                               ApplyControlStyle (item, selectedItemStyle);
+                                       } else {
+                                               item.MergeStyle (itemStyle);
+                                               ApplyControlStyle (item, itemStyle);
+                                       }
+                                       break;
+                               case ListItemType.Separator:
+                                       if (separatorStyle != null) {
+                                               item.MergeStyle(separatorStyle);
+                                               ApplyControlStyle (item, separatorStyle);
+                                       }
+                                       else {
+                                               item.MergeStyle (itemStyle);
+                                               ApplyControlStyle (item, itemStyle);
+                                       }
+                                       break;
                                }
-                               if(footerTemplate != null)
-                                       CreateItem(-1, ListItemType.Footer, useDataSource, null);
-                       }
-                       if(useDataSource)
-                       {
-                               ViewState["_!ItemCount"] = (listEnumerator != null ? itemCount : -1);
                        }
                }
 
-               /// <summary>
-               /// Undocumented
-               /// </summary>
-               protected virtual DataListItem CreateItem(int itemIndex, ListItemType itemType)
+#if NET_2_0
+               protected internal
+#else          
+               protected
+#endif         
+               override void RenderContents (HtmlTextWriter writer)
                {
-                       return new DataListItem(itemIndex, itemType);
+                       if (Items.Count == 0)
+                               return;                 
+
+                       RepeatInfo ri = new RepeatInfo ();
+                       ri.RepeatColumns = RepeatColumns;
+                       ri.RepeatDirection = RepeatDirection;
+                       ri.RepeatLayout = RepeatLayout;
+                       ri.CaptionAlign = CaptionAlign;
+                       ri.Caption = Caption;
+                       ri.UseAccessibleHeader = UseAccessibleHeader;
+/*
+// debugging stuff that I prefer to keep for a while
+Console.WriteLine ("RepeatColumns {0}", ri.RepeatColumns);
+Console.WriteLine ("RepeatDirection {0}", ri.RepeatDirection);
+Console.WriteLine ("RepeatLayout {0}", ri.RepeatLayout);
+Console.WriteLine ("OuterTableImplied {0}", ExtractTemplateRows);
+Console.WriteLine ("IRepeatInfoUser.HasFooter {0}", (ShowFooter && (footerTemplate != null)));
+Console.WriteLine ("IRepeatInfoUser.HasHeader {0}", (ShowHeader && (headerTemplate != null)));
+Console.WriteLine ("IRepeatInfoUser.HasSeparators {0}", (separatorTemplate != null));
+Console.WriteLine ("IRepeatInfoUser.RepeatedItemCount {0}", Items.Count);
+for (int i=0; i < Items.Count; i++) {
+       DataListItem dli = Items [i];
+       Console.WriteLine ("{0}: Index {1}, Type {2}", i, dli.ItemIndex, dli.ItemType);
+}
+*/
+                       bool extract = ExtractTemplateRows;
+                       if (extract) {
+                               ri.OuterTableImplied = true;
+                               writer.AddAttribute (HtmlTextWriterAttribute.Id, ClientID);
+                               if (ControlStyleCreated) {
+                                       ControlStyle.AddAttributesToRender (writer);
+                               }
+                               writer.RenderBeginTag (HtmlTextWriterTag.Table);
+                               ri.RenderRepeater (writer, this, ControlStyle, this);
+                               writer.RenderEndTag ();
+                       } else {
+                               ri.RenderRepeater (writer, this, ControlStyle, this);
+                       }
                }
 
-               private DataListItem CreateItem(int itemIndex, ListItemType itemType, bool dataBind, object dataItem)
-               {
-                       DataListItem retVal = CreateItem(itemIndex, itemType);
-                       DataListItemEventArgs e = new DataListItemEventArgs(retVal);
-                       InitializeItem(retVal);
-                       if(dataBind)
-                       {
-                               retVal.DataItem = dataItem;
-                       }
-                       OnItemCreated(e);
-                       Controls.Add(retVal);
-                       if(dataBind)
-                       {
-                               retVal.DataBind();
-                               OnItemDataBound(e);
-                               retVal.DataItem = null;
-                       }
-                       return retVal;
-               }
-
-               /// <summary>
-               /// Undocumented
-               /// </summary>
-               [MonoTODO]
-               protected override void PrepareControlHierarchy()
+               protected override object SaveViewState ()
                {
+#if NET_2_0
+                       object[] state = new object [9];
+                       // FIXME: what's new in slot #0 ?
+                       state[8] = base.SaveViewState ();
+#else
+                       object[] state = new object [8];
+                       state[0] = base.SaveViewState ();
+#endif
+                       if (itemStyle != null)
+                               state [1] = itemStyle.SaveViewState ();
+                       if (selectedItemStyle != null)
+                               state [2] = selectedItemStyle.SaveViewState ();
+                       if (alternatingItemStyle != null)
+                               state [3] = alternatingItemStyle.SaveViewState ();
+                       if (editItemStyle != null)
+                               state [4] = editItemStyle.SaveViewState ();
+                       if (separatorStyle != null)
+                               state [5] = separatorStyle.SaveViewState ();
+                       if (headerStyle != null)
+                               state [6] = headerStyle.SaveViewState ();
+                       if (footerStyle != null)
+                               state [7] = footerStyle.SaveViewState ();
+                       return state;
                }
 
-               /// <summary>
-               /// Undocumented
-               /// </summary>
-               protected virtual void InitializeItem(DataListItem item)
-               {
-                       ListItemType type = item.ItemType;
-                       ITemplate    template = itemTemplate;
-                       switch(type)
-                       {
-                               case ListItemType.Header : template = headerTemplate;
-                                                          break;
-                               case ListItemType.Footer : template = footerTemplate;
-                                                          break;
-                               case ListItemType.AlternatingItem
-                                                        : if(alternatingItemTemplate != null)
-                                                               template = alternatingItemTemplate;
-                                                          break;
-                               case ListItemType.SelectedItem
-                                                        : if(selectedItemTemplate != null)
-                                                          {
-                                                               template = selectedItemTemplate;
-                                                               break;
-                                                          }
-                                                          if((item.ItemIndex % 2) != 0)
-                                                               goto case ListItemType.AlternatingItem;
-                                                          break;
-                               case ListItemType.EditItem
-                                                        : if(editItemTemplate != null)
-                                                          {
-                                                               template = editItemTemplate;
-                                                               break;
-                                                          }
-                                                          if(item.ItemIndex == SelectedIndex)
-                                                               goto case ListItemType.SelectedItem;
-                                                          if((item.ItemIndex % 2) != 0)
-                                                               goto case ListItemType.AlternatingItem;
-                                                          break;
-                               case ListItemType.Separator
-                                                        : template = separatorTemplate;
-                                                          break;
-                       }
-                       if(itemTemplate != null)
-                               itemTemplate.InstantiateIn(this);
-               }
-
-               bool IRepeatInfoUser.HasFooter
+               protected override void TrackViewState ()
                {
-                       get
-                       {
-                               return !(ShowFooter && footerTemplate!=null);
+                       base.TrackViewState ();
+                       if (alternatingItemStyle != null)
+                               alternatingItemStyle.TrackViewState ();
+                       if (editItemStyle != null)
+                               editItemStyle.TrackViewState ();
+                       if (footerStyle != null)
+                               footerStyle.TrackViewState ();
+                       if (headerStyle != null)
+                               headerStyle.TrackViewState ();
+                       if (itemStyle != null)
+                               itemStyle.TrackViewState ();
+                       if (selectedItemStyle != null)
+                               selectedItemStyle.TrackViewState ();
+                       if (separatorStyle != null)
+                               separatorStyle.TrackViewState ();
+               }
+
+
+               [WebSysDescription ("")]
+               [WebCategory ("Action")]
+               public event DataListCommandEventHandler CancelCommand {
+                       add { Events.AddHandler (cancelCommandEvent, value); }
+                       remove { Events.RemoveHandler (cancelCommandEvent, value); }
+               }
+
+               [WebSysDescription ("")]
+               [WebCategory ("Action")]
+               public event DataListCommandEventHandler DeleteCommand {
+                       add { Events.AddHandler (deleteCommandEvent, value); }
+                       remove { Events.RemoveHandler (deleteCommandEvent, value); }
+               }
+
+               [WebSysDescription ("")]
+               [WebCategory ("Action")]
+               public event DataListCommandEventHandler EditCommand {
+                       add { Events.AddHandler (editCommandEvent, value); }
+                       remove { Events.RemoveHandler (editCommandEvent, value); }
+               }
+
+               [WebSysDescription ("")]
+               [WebCategory ("Action")]
+               public event DataListCommandEventHandler ItemCommand {
+                       add { Events.AddHandler (itemCommandEvent, value); }
+                       remove { Events.RemoveHandler (itemCommandEvent, value); }
+               }
+
+               [WebSysDescription ("")]
+               [WebCategory ("Action")]
+               public event DataListItemEventHandler ItemCreated {
+                       add { Events.AddHandler (itemCreatedEvent, value); }
+                       remove { Events.RemoveHandler (itemCreatedEvent, value); }
+               }
+
+               [WebSysDescription ("")]
+               [WebCategory ("Action")]
+               public event DataListItemEventHandler ItemDataBound {
+                       add { Events.AddHandler (itemDataBoundEvent, value); }
+                       remove { Events.RemoveHandler (itemDataBoundEvent, value); }
+               }
+
+               [WebSysDescription ("")]
+               [WebCategory ("Action")]
+               public event DataListCommandEventHandler UpdateCommand {
+                       add { Events.AddHandler (updateCommandEvent, value); }
+                       remove { Events.RemoveHandler (updateCommandEvent, value); }
+               }
+
+
+               // IRepeatInfoUser support
+
+               bool IRepeatInfoUser.HasFooter {
+                       get { return (ShowFooter && (footerTemplate != null)); }
+               }
+
+               bool IRepeatInfoUser.HasHeader {
+                       get { return (ShowHeader && (headerTemplate != null)); }
+               }
+               
+               bool IRepeatInfoUser.HasSeparators {
+                       get { return (separatorTemplate != null); }
+               }
+
+               // don't include header, footer and separators in the count
+               int IRepeatInfoUser.RepeatedItemCount {
+                       get {
+                               if (idx == -1) {
+                                       object o = ViewState ["Items"];
+                                       idx = (o == null) ? 0 : (int) o;
+                               }
+                               return idx;
                        }
                }
 
-               bool IRepeatInfoUser.HasHeader
+               Style IRepeatInfoUser.GetItemStyle (ListItemType itemType, int repeatIndex)
                {
-                       get
-                       {
-                               return !(ShowHeader && headerTemplate!=null);
-                       }
+                       DataListItem item = null;
+                       switch (itemType) {
+                       case ListItemType.Header:
+                       case ListItemType.Footer:
+                               if (repeatIndex >= 0 && (!HasControls () || repeatIndex >= Controls.Count))
+                                       throw new ArgumentOutOfRangeException ();
+
+                               item = FindFirstItem (itemType);
+                               break;
+                       case ListItemType.Item:
+                       case ListItemType.AlternatingItem:
+                       case ListItemType.SelectedItem:
+                       case ListItemType.EditItem:
+                               if (repeatIndex >= 0 && (!HasControls () || repeatIndex >= Controls.Count))
+                                       throw new ArgumentOutOfRangeException ();
+
+                               item = FindBestItem (repeatIndex);
+                               break;
+                       case ListItemType.Separator:
+                               if (repeatIndex >= 0 && (!HasControls () || repeatIndex >= Controls.Count))
+                                       throw new ArgumentOutOfRangeException ();
+
+                               item = FindSpecificItem (itemType, repeatIndex);
+                               break;
+                       default:
+                               item = null;
+                               break;
+                       }
+
+                       if (item == null || item.ControlStyleCreated == false)
+                               return null;
+
+                       return item.ControlStyle;
                }
 
-               bool IRepeatInfoUser.HasSeparators
+               // Header and Footer don't have a "real" index (-1)
+               private DataListItem FindFirstItem (ListItemType itemType)
                {
-                       get
-                       {
-                               return (separatorItemTemplate!=null);
+                       for (int i = 0; i < Controls.Count; i++) {
+                               DataListItem item = (Controls [i] as DataListItem);
+                               if ((item != null) && (item.ItemType == itemType))
+                                       return item;
                        }
+                       return null;
                }
 
-               int IRepeatInfoUser.RepeatedItemCount
+               // Both Type and Index must match (e.g. Separator)
+               private DataListItem FindSpecificItem (ListItemType itemType, int repeatIndex)
                {
-                       get
-                       {
-                               if(itemsArray!=null)
-                                       return itemsArray.Count;
-                               return 0;
+                       for (int i = 0; i < Controls.Count; i++) {
+                               DataListItem item = (Controls [i] as DataListItem);
+                               if ((item != null) && (item.ItemType == itemType) && (item.ItemIndex == repeatIndex))
+                                       return item;
                        }
+                       return null;
                }
 
-               void IRepeatInfoUser.RenderItem(ListItemType itemType, int repeatIndex, RepeatInfo repeatInfo, HtmlTextWriter writer)
+               // we get call for Item even for AlternatingItem :(
+               private DataListItem FindBestItem (int repeatIndex)
                {
-                       DataListItem item = GetItem(itemType, repeatIndex);
-                       if(item!=null)
-                       {
-                               item.RenderItem(writer, extractTemplateRows, repeatInfo.RepeatLayout == RepeatLayout.Table);
+                       for (int i = 0; i < Controls.Count; i++) {
+                               DataListItem item = (Controls [i] as DataListItem);
+                               if ((item != null) && (item.ItemIndex == repeatIndex)) {
+                                       switch (item.ItemType) {
+                                       case ListItemType.Item:
+                                       case ListItemType.AlternatingItem:
+                                       case ListItemType.SelectedItem:
+                                       case ListItemType.EditItem:
+                                               return item;
+                                       default:
+                                               return null;
+                                       }
+                               }
                        }
+                       return null;
                }
 
-               Style IRepeatInfoUser.GetItemStyle(ListItemType itemType, int repeatIndex)
+               void IRepeatInfoUser.RenderItem (ListItemType itemType, int repeatIndex, RepeatInfo repeatInfo, HtmlTextWriter writer)
                {
-                       if(GetItem(itemType, repeatIndex)!=null && ControlStyleCreated)
-                               return ControlStyle;
-                       return null;
+                       // if possible take the easy way out...
+                       if (!HasControls ())
+                               return;
+
+                       DataListItem item = null;
+                       switch (itemType) {
+                       case ListItemType.Header:
+                       case ListItemType.Footer:
+                               item = FindFirstItem (itemType);
+                               break;
+                       case ListItemType.Item:
+                       case ListItemType.AlternatingItem:
+                       case ListItemType.SelectedItem:
+                       case ListItemType.EditItem:
+                               item = FindBestItem (repeatIndex);
+                               break;
+                       case ListItemType.Separator:
+                               item = FindSpecificItem (itemType, repeatIndex);
+                               break;
+                       }
+
+                       if (item != null) {
+                               bool extract = ExtractTemplateRows;
+                               bool table = (RepeatLayout == RepeatLayout.Table);
+                               if (!table || extract) {
+                                       // sadly RepeatInfo doesn't support Style for RepeatLayout.Flow
+                                       Style s = (this as IRepeatInfoUser).GetItemStyle (itemType, repeatIndex);
+                                       if (s != null)
+                                               item.ControlStyle.CopyFrom (s);
+                               }
+//Console.WriteLine ("RenderItem #{0} type {1}", repeatIndex, itemType);
+                               item.RenderItem (writer, extract, table);
+                       } else {
+//Console.WriteLine ("Couldn't find #{0} type {1} out of {2} items / {3} controls", repeatIndex, itemType, Items.Count, Controls.Count);
+                       }
                }
        }
 }