* roottypes.cs: Rename from tree.cs.
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / DataList.cs
index 38cfcf8f19f94dce84c7d105dacd7d36b1793db9..39aa0b005f2d436b440fc2e318013697da4e71ae 100644 (file)
@@ -1,14 +1,10 @@
 //
 // System.Web.UI.WebControls.DataList.cs
 //
-// Authors:
-//   Gaurav Vaish (gvaish@iitk.ac.in)
-//   Andreas Nahr (ClassDevelopment@A-SoftTech.com)
+// Author:
+//     Sebastien Pouliot  <sebastien@ximian.com>
 //
-// (C) Gaurav Vaish (2002)
-// (C) 2003 Andreas Nahr
-//
-
+// 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
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-using System;
 using System.Collections;
 using System.ComponentModel;
-using System.ComponentModel.Design;
-using System.Web;
-using System.Web.UI;
+using System.Globalization;
+using System.Security.Permissions;
 using System.Web.Util;
 
-namespace System.Web.UI.WebControls
-{
+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
-       [Designer("System.Web.UI.Design.WebControls.DataListDesigner, " + Consts.AssemblySystem_Design, typeof (IDesigner))]
-       [Editor ("System.Web.UI.Design.WebControls.DataListComponentEditor, " + Consts.AssemblySystem_Design, typeof (ComponentEditor))]
-       public class DataList: BaseDataList, INamingContainer, IRepeatInfoUser
-       {
+       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";
 
-               static readonly object CancelCommandEvent = new object ();
-               static readonly object DeleteCommandEvent = new object ();
-               static readonly object EditCommandEvent   = new object ();
-               static readonly object ItemCommandEvent   = new object ();
-               static readonly object ItemCreatedEvent   = new object ();
-               static readonly object ItemDataBoundEvent = new object ();
-               static readonly object UpdateCommandEvent = new object ();
-
-               TableItemStyle alternatingItemStyle;
-               TableItemStyle editItemStyle;
-               TableItemStyle footerStyle;
-               TableItemStyle headerStyle;
-               TableItemStyle itemStyle;
-               TableItemStyle selectedItemStyle;
-               TableItemStyle separatorStyle;
-
-               ITemplate alternatingItemTemplate;
-               ITemplate editItemTemplate;
-               ITemplate footerTemplate;
-               ITemplate headerTemplate;
-               ITemplate itemTemplate;
-               ITemplate selectedItemTemplate;
-               ITemplate separatorTemplate;
-
-               ArrayList itemsArray;
-               DataListItemCollection items;
-
-               bool extractTemplateRows;
-               
+
+               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;
+               private TableItemStyle footerStyle;
+               private TableItemStyle headerStyle;
+               private TableItemStyle itemStyle;
+               private TableItemStyle selectedItemStyle;
+               private TableItemStyle separatorStyle;
+
+               private ITemplate alternatingItemTemplate;
+               private ITemplate editItemTemplate;
+               private ITemplate footerTemplate;
+               private ITemplate headerTemplate;
+               private ITemplate itemTemplate;
+               private ITemplate selectedItemTemplate;
+               private ITemplate separatorTemplate;
+
+               private DataListItemCollection items;
+               private ArrayList list;
+               private int idx;
+
 #if NET_2_0
-               int selectedIndex = -1;
-#endif
+               private int editIndex;
+               private int selectedIndex;
 
                public DataList ()
                {
+                       editIndex = -1;
+                       selectedIndex = -1;
+                       idx = -1;
                }
+#else
+               public DataList ()
+               {
+                       idx = -1;
+               }
+#endif
+
 
                [DefaultValue (null)]
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
                [NotifyParentProperty (true)]
-               [WebCategory ("Style")]
                [PersistenceMode (PersistenceMode.InnerProperty)]
-               [WebSysDescription ("The style applied to alternating items.")]
+               [WebSysDescription ("")]
+               [WebCategory ("Style")]
                public virtual TableItemStyle AlternatingItemStyle {
                        get {
                                if (alternatingItemStyle == null) {
                                        alternatingItemStyle = new TableItemStyle ();
-                                       if (IsTrackingViewState)
+                                       if (IsTrackingViewState) {
                                                alternatingItemStyle.TrackViewState ();
+                                       }
                                }
-
                                return alternatingItemStyle;
                        }
                }
@@ -112,46 +122,42 @@ namespace System.Web.UI.WebControls
                [DefaultValue (null)]
                [TemplateContainer (typeof (DataListItem))]
                [PersistenceMode (PersistenceMode.InnerProperty)]
-               [WebSysDescription ("The template used for alternating items.")]
+               [WebSysDescription ("")]
+               [WebCategory ("Style")]
                public virtual ITemplate AlternatingItemTemplate {
                        get { return alternatingItemTemplate; }
                        set { alternatingItemTemplate = value; }
                }
 
                [DefaultValue (-1)]
+               [WebSysDescription ("")]
                [WebCategory ("Misc")]
-               [WebSysDescription ("The index of the item shown in edit mode.")]
                public virtual int EditItemIndex {
                        get {
                                object o = ViewState ["EditItemIndex"];
-                               if (o != null)
-                                       return (int) o;
-
-                               return -1;
+                               return (o == null) ? -1 : (int) o;
                        }
-
                        set {
                                if (value < -1)
-                                        throw new ArgumentOutOfRangeException("value");
-                                
-                               ViewState ["EditItemIndex"] = value; 
+                                       throw new ArgumentOutOfRangeException ("EditItemIndex", "< -1");
+                               ViewState ["EditItemIndex"] = value;
                        }
                }
 
                [DefaultValue (null)]
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
                [NotifyParentProperty (true)]
-               [WebCategory ("Style")]
                [PersistenceMode (PersistenceMode.InnerProperty)]
-               [WebSysDescription ("The style applied to items in edit mode.")]
+               [WebSysDescription ("")]
+               [WebCategory ("Style")]
                public virtual TableItemStyle EditItemStyle {
                        get {
                                if (editItemStyle == null) {
                                        editItemStyle = new TableItemStyle ();
-                                       if (IsTrackingViewState)
+                                       if (IsTrackingViewState) {
                                                editItemStyle.TrackViewState ();
+                                       }
                                }
-
                                return editItemStyle;
                        }
                }
@@ -160,41 +166,38 @@ namespace System.Web.UI.WebControls
                [DefaultValue (null)]
                [TemplateContainer (typeof (DataListItem))]
                [PersistenceMode (PersistenceMode.InnerProperty)]
-               [WebSysDescription ("The template used for items in edit mode.")]
+               [WebSysDescription ("")]
+               [WebCategory ("Style")]
                public virtual ITemplate EditItemTemplate {
                        get { return editItemTemplate; }
                        set { editItemTemplate = value; }
                }
 
-
-               [DefaultValue (false), WebCategory ("Misc")]
-               [WebSysDescription ("Extract rows in the template.")]
+               [DefaultValue (false)]
+               [WebSysDescription ("")]
+               [WebCategory ("Misc")]
                public virtual bool ExtractTemplateRows {
                        get {
                                object o = ViewState ["ExtractTemplateRows"];
-                               if (o != null)
-                                       return (bool) o;
-
-                               return false;
+                               return (o == null) ? false : (bool) o;
                        }
-
                        set { ViewState ["ExtractTemplateRows"] = value; }
                }
 
                [DefaultValue (null)]
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
                [NotifyParentProperty (true)]
-               [WebCategory ("Style")]
                [PersistenceMode (PersistenceMode.InnerProperty)]
-               [WebSysDescription ("The style applied to the footer.")]
+               [WebSysDescription ("")]
+               [WebCategory ("Style")]
                public virtual TableItemStyle FooterStyle {
                        get {
                                if (footerStyle == null) {
                                        footerStyle = new TableItemStyle ();
-                                       if (IsTrackingViewState)
+                                       if (IsTrackingViewState) {
                                                footerStyle.TrackViewState ();
+                                       }
                                }
-
                                return footerStyle;
                        }
                }
@@ -203,36 +206,43 @@ namespace System.Web.UI.WebControls
                [DefaultValue (null)]
                [TemplateContainer (typeof (DataListItem))]
                [PersistenceMode (PersistenceMode.InnerProperty)]
-               [WebSysDescription ("The template used for the footer.")]
+               [WebSysDescription ("")]
+               [WebCategory ("Style")]
                public virtual ITemplate FooterTemplate {
                        get { return footerTemplate; }
                        set { footerTemplate = value; }
                }
 
+               // yes! they do NOT match in fx1.1
                [DefaultValue (GridLines.None)]
                public override GridLines GridLines {
                        get {
-                               if (ControlStyleCreated)
-                                       return base.GridLines;
-                               return GridLines.None;
+                               if (!ControlStyleCreated) {
+#if NET_2_0
+                                       return GridLines.None;
+#else
+                                       return GridLines.Both;
+#endif
+                               }
+                               return TableStyle.GridLines;
                        }
-                       set { base.GridLines = value; }
+                       set { TableStyle.GridLines = value; }
                }
 
                [DefaultValue (null)]
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
                [NotifyParentProperty (true)]
-               [WebCategory ("Style")]
                [PersistenceMode (PersistenceMode.InnerProperty)]
-               [WebSysDescription ("The style applied to the header.")]
+               [WebSysDescription ("")]
+               [WebCategory ("Style")]
                public virtual TableItemStyle HeaderStyle {
                        get {
                                if (headerStyle == null) {
                                        headerStyle = new TableItemStyle ();
-                                       if (IsTrackingViewState)
+                                       if (IsTrackingViewState) {
                                                headerStyle.TrackViewState ();
+                                       }
                                }
-
                                return headerStyle;
                        }
                }
@@ -241,7 +251,8 @@ namespace System.Web.UI.WebControls
                [DefaultValue (null)]
                [TemplateContainer (typeof (DataListItem))]
                [PersistenceMode (PersistenceMode.InnerProperty)]
-               [WebSysDescription ("The template used for the header.")]
+               [WebSysDescription ("")]
+               [WebCategory ("Style")]
                public virtual ITemplate HeaderTemplate {
                        get { return headerTemplate; }
                        set { headerTemplate = value; }
@@ -249,17 +260,12 @@ namespace System.Web.UI.WebControls
 
                [Browsable (false)]
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
-               [WebSysDescription ("A colletion containing all items.")]
+               [WebSysDescription ("")]
+               [WebCategory ("Style")]
                public virtual DataListItemCollection Items {
                        get {
-                               if (items == null) {
-                                       if (itemsArray == null) {
-                                               EnsureChildControls ();
-                                               itemsArray = new ArrayList ();
-                                       }
-                                       items = new DataListItemCollection (itemsArray);
-                               }
-
+                               if (items == null)
+                                       items = new DataListItemCollection (ItemList);
                                return items;
                        }
                }
@@ -267,17 +273,17 @@ namespace System.Web.UI.WebControls
                [DefaultValue (null)]
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
                [NotifyParentProperty (true)]
-               [WebCategory ("Style")]
                [PersistenceMode (PersistenceMode.InnerProperty)]
-               [WebSysDescription ("The style applied to items.")]
+               [WebSysDescription ("")]
+               [WebCategory ("Style")]
                public virtual TableItemStyle ItemStyle {
                        get {
                                if (itemStyle == null) {
                                        itemStyle = new TableItemStyle ();
-                                       if (IsTrackingViewState)
+                                       if (IsTrackingViewState) {
                                                itemStyle.TrackViewState ();
+                                       }
                                }
-
                                return itemStyle;
                        }
                }
@@ -286,153 +292,104 @@ namespace System.Web.UI.WebControls
                [DefaultValue (null)]
                [TemplateContainer (typeof (DataListItem))]
                [PersistenceMode (PersistenceMode.InnerProperty)]
-               [WebSysDescription ("The template used for items.")]
+               [WebSysDescription ("")]
+               [WebCategory ("Style")]
                public virtual ITemplate ItemTemplate {
                        get { return itemTemplate; }
                        set { itemTemplate = value; }
                }
 
-
-#if !NET_2_0
+#if ONLY_1_1
                [Bindable (true)]
 #endif
-               [DefaultValue (0), WebCategory ("Layout")]
-               [WebSysDescription ("The number of columns that should be used.")]
+               [DefaultValue (0)]
+               [WebSysDescription ("")]
+               [WebCategory ("Layout")]
                public virtual int RepeatColumns {
                        get {
                                object o = ViewState ["RepeatColumns"];
-                               if (o != null)
-                                       return (int) o;
-
-                               return 0;
+                               return (o == null) ? 0 : (int) o;
                        }
-                       set {
+                       set { 
                                if (value < 0)
                                        throw new ArgumentOutOfRangeException ("value", "RepeatColumns value has to be 0 for 'not set' or > 0.");
-
-                               ViewState ["RepeatColumns"] = value;
+                               
+                               ViewState ["RepeatColumns"] = value; 
                        }
                }
 
-#if !NET_2_0
+#if ONLY_1_1
                [Bindable (true)]
 #endif
-               [DefaultValue (RepeatDirection.Vertical), WebCategory ("Layout")]
-               [WebSysDescription ("Which direction should be used when filling the columns.")]
+               [DefaultValue (RepeatDirection.Vertical)]
+               [WebSysDescription ("")]
+               [WebCategory ("Layout")]
                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 ArgumentOutOfRangeException ("value", "Only valid enumeration members are allowed");
-
-                               ViewState ["RepeatDirection"] = value;
+                               return (o == null) ? RepeatDirection.Vertical : (RepeatDirection) o;
                        }
+                       set { ViewState ["RepeatDirection"] = value; }
                }
 
-#if !NET_2_0
+#if ONLY_1_1
                [Bindable (true)]
 #endif
-               [DefaultValue (RepeatLayout.Table), WebCategory ("Layout")]
-               [WebSysDescription ("The type of layout - mechanism that is used.")]
+               [DefaultValue (RepeatLayout.Table)]
+               [WebSysDescription ("")]
+               [WebCategory ("Layout")]
                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 ArgumentOutOfRangeException ("value", "Only valid enumeration members are allowed");
-
-                               ViewState ["RepeatLayout"] = value;
+                               return (o == null) ? RepeatLayout.Table : (RepeatLayout) o;
                        }
+                       set { ViewState ["RepeatLayout"] = value; }
                }
 
-               [DefaultValue (-1), Bindable (true)]
-               [WebSysDescription ("The currently selected item index number.")]
+               [Bindable (true)]
+               [DefaultValue (-1)]
+               [WebSysDescription ("")]
+               [WebCategory ("Layout")]
                public virtual int SelectedIndex {
                        get {
-#if NET_2_0
-                               return selectedIndex;
-#else
                                object o = ViewState ["SelectedIndex"];
-                               if (o != null)
-                                       return (int) o;
-
-                               return -1;
-#endif
+                               return (o == null) ? -1 : (int) o;
                        }
                        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;
-#if NET_2_0
-                               selectedIndex = value;
-#else
+                                       throw new ArgumentOutOfRangeException ("SelectedIndex", "< -1");
                                ViewState ["SelectedIndex"] = value;
-#endif
-                               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);
-                                               }
-                                       }
-                               }
                        }
                }
 
                [Browsable (false)]
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
-               [WebSysDescription ("The currently selected item.")]
+               [WebSysDescription ("")]
+               [WebCategory ("Layout")]
                public virtual DataListItem SelectedItem {
                        get {
-                               if (SelectedIndex == -1)
+                               if (SelectedIndex < 0)
                                        return null;
-
-                               return Items [SelectedIndex];
+                               if (SelectedIndex >= Items.Count)
+                                       throw new ArgumentOutOfRangeException ("SelectedItem", ">= Items.Count");
+                               return items [SelectedIndex];
                        }
                }
 
                [DefaultValue (null)]
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
                [NotifyParentProperty (true)]
-               [WebCategory ("Style")]
                [PersistenceMode (PersistenceMode.InnerProperty)]
-               [WebSysDescription ("The style used for the currently selected item.")]
+               [WebSysDescription ("")]
+               [WebCategory ("Style")]
                public virtual TableItemStyle SelectedItemStyle {
                        get {
                                if (selectedItemStyle == null) {
                                        selectedItemStyle = new TableItemStyle ();
-                                       if (IsTrackingViewState)
+                                       if (IsTrackingViewState) {
                                                selectedItemStyle.TrackViewState ();
+                                       }
                                }
-
                                return selectedItemStyle;
                        }
                }
@@ -441,7 +398,8 @@ namespace System.Web.UI.WebControls
                [DefaultValue (null)]
                [TemplateContainer (typeof (DataListItem))]
                [PersistenceMode (PersistenceMode.InnerProperty)]
-               [WebSysDescription ("The template used for currently selected items.")]
+               [WebSysDescription ("")]
+               [WebCategory ("Style")]
                public virtual ITemplate SelectedItemTemplate {
                        get { return selectedItemTemplate; }
                        set { selectedItemTemplate = value; }
@@ -450,17 +408,17 @@ namespace System.Web.UI.WebControls
                [DefaultValue (null)]
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
                [NotifyParentProperty (true)]
-               [WebCategory ("Style")]
                [PersistenceMode (PersistenceMode.InnerProperty)]
-               [WebSysDescription ("The style applied to separators.")]
+               [WebSysDescription ("")]
+               [WebCategory ("Style")]
                public virtual TableItemStyle SeparatorStyle {
                        get {
                                if (separatorStyle == null) {
                                        separatorStyle = new TableItemStyle ();
-                                       if (IsTrackingViewState)
+                                       if (IsTrackingViewState) {
                                                separatorStyle.TrackViewState ();
+                                       }
                                }
-
                                return separatorStyle;
                        }
                }
@@ -469,608 +427,712 @@ namespace System.Web.UI.WebControls
                [DefaultValue (null)]
                [TemplateContainer (typeof (DataListItem))]
                [PersistenceMode (PersistenceMode.InnerProperty)]
-               [WebSysDescription ("The template used for separators.")]
+               [WebSysDescription ("")]
+               [WebCategory ("Style")]
                public virtual ITemplate SeparatorTemplate {
                        get { return separatorTemplate; }
                        set { separatorTemplate = value; }
                }
 
-#if !NET_2_0
+#if ONLY_1_1
                [Bindable (true)]
 #endif
-               [DefaultValue (true), WebCategory ("Appearance")]
-               [WebSysDescription ("Display the header for the DataList.")]
-               public virtual bool ShowHeader {
+               [DefaultValue (true)]
+               [WebSysDescription ("")]
+               [WebCategory ("Appearance")]
+               public virtual bool ShowFooter {
                        get {
-                               object o = ViewState ["ShowHeader"];
-                               if (o != null)
-                                       return (bool) o;
-
-                               return true;
+                               object o = ViewState ["ShowFooter"];
+                               return (o == null) ? true : (bool) o;
                        }
-                       set { ViewState ["ShowHeader"] = value; }
+                       set { ViewState ["ShowFooter"] = value; }
                }
 
-#if !NET_2_0
+#if ONLY_1_1
                [Bindable (true)]
 #endif
-               [DefaultValue (true), WebCategory ("Appearance")]
-               [WebSysDescription ("Display the footer for the DataList.")]
-               public virtual bool ShowFooter {
+               [DefaultValue (true)]
+               [WebSysDescription ("")]
+               [WebCategory ("Appearance")]
+               public virtual bool ShowHeader {
                        get {
-                               object o = ViewState ["ShowFooter"];
-                               if (o != null)
-                                       return (bool) o;
-
-                               return true;
-                       }
-                       set
-                       {
-                               ViewState["ShowFooter"] = value;
+                               object o = ViewState ["ShowHeader"];
+                               return (o == null) ? true : (bool) o;
                        }
+                       set { ViewState ["ShowHeader"] = value; }
                }
 
-               [WebCategory ("Action")]
-               [WebSysDescription ("Raised when a cancel command is generated.")]
-               public event DataListCommandEventHandler CancelCommand {
-                       add { Events.AddHandler (CancelCommandEvent, value); }
-                       remove { Events.RemoveHandler (CancelCommandEvent, 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."));
 
-               [WebCategory ("Action")]
-               [WebSysDescription ("Raised when a delete command is generated.")]
-               public event DataListCommandEventHandler DeleteCommand {
-                       add { Events.AddHandler (DeleteCommandEvent, value); }
-                       remove { Events.RemoveHandler (DeleteCommandEvent, value); }
-               }
+                               if ((SelectedIndex >= 0) && (selectedIndex < DataKeys.Count)) {
+                                       return DataKeys [selectedIndex];
+                               }
 
-               [WebCategory ("Action")]
-               [WebSysDescription ("Raised when an edit command is generated.")]
-               public event DataListCommandEventHandler EditCommand {
-                       add { Events.AddHandler (EditCommandEvent, value); }
-                       remove { Events.RemoveHandler (EditCommandEvent, value); }
+                               return null;
+                       }
                }
 
-               [WebCategory ("Action")]
-               [WebSysDescription ("Raised when an item command is generated.")]
-               public event DataListCommandEventHandler ItemCommand {
-                       add { Events.AddHandler (ItemCommandEvent, value); }
-                       remove { Events.RemoveHandler (ItemCommandEvent, value); }
+               protected override HtmlTextWriterTag TagKey {
+                       get { return HtmlTextWriterTag.Table; }
                }
+#endif
 
-               [WebCategory ("Behavior")]
-               [WebSysDescription ("Raised when a new item is created.")]
-               public event DataListItemEventHandler ItemCreated {
-                       add { Events.AddHandler (ItemCreatedEvent, value); }
-                       remove { Events.RemoveHandler (ItemCreatedEvent, value); }
+               private TableStyle TableStyle {
+                       // this will throw an InvalidCasException just like we need
+                       get { return (TableStyle) ControlStyle; }
                }
-
-               [WebCategory ("Behavior")]
-               [WebSysDescription ("Raised when a item gets data-bound.")]
-               public event DataListItemEventHandler ItemDataBound {
-                       add { Events.AddHandler (ItemDataBoundEvent, value); }
-                       remove { Events.RemoveHandler (ItemDataBoundEvent, value); }
+               
+               private ArrayList ItemList {
+                       get {
+                               if (list == null)
+                                       list = new ArrayList ();
+                               return list;
+                       }
                }
 
-               [WebCategory ("Action")]
-               [WebSysDescription ("Raised when an update command is generated.")]
-               public event DataListCommandEventHandler UpdateCommand {
-                       add { Events.AddHandler (UpdateCommandEvent, value); }
-                       remove { Events.RemoveHandler (UpdateCommandEvent, value); }
+               void DoItem (int i, ListItemType t, object d, bool databind)
+               {
+                       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;
+                       }
                }
 
-               protected override Style CreateControlStyle ()
+               private void DoItemInLoop (int i, object d, bool databind, ListItemType type)
                {
-                       TableStyle retVal = new TableStyle (ViewState);
-                       retVal.CellSpacing = 0;
-                       return retVal;
+                       DoItem (i, type, d, databind);
+                       if (SeparatorTemplate != null)
+                               DoItem (i, ListItemType.Separator, null, databind);
+
                }
 
-               protected override void LoadViewState (object savedState)
+               protected override void CreateControlHierarchy (bool useDataSource)
                {
-                       if (savedState == null)
+                       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;
 
-                       object [] states = (object []) savedState;
-
-                       if (states [0] != null)
-                               base.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] = base.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;
+                       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;
                }
 
-               protected override void TrackViewState ()
+               protected override Style CreateControlStyle ()
                {
-                       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 ();
+#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
                }
 
-#if NET_2_0
-               protected override void OnInit (EventArgs e)
+               protected virtual DataListItem CreateItem (int itemIndex, ListItemType itemType)
                {
-                       Page.RegisterRequiresControlState (this);
-                       base.OnInit (e);
+                       return new DataListItem (itemIndex, itemType);
                }
-               
-               protected internal override void LoadControlState (object ob)
+
+               protected virtual void InitializeItem (DataListItem item)
                {
-                       if (ob == null) return;
-                       Pair state = (Pair) ob;
-                       base.LoadControlState (state.First);
+                       ITemplate t = null;
                        
-                       if (state.Second != null)
-                               SelectedIndex = (int) state.Second;
+                       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 internal override object SaveControlState ()
+
+               protected override void LoadViewState (object savedState)
                {
-                       object bstate = base.SaveControlState ();
-                       object mstate = SelectedIndex != -1 ? (object) SelectedIndex : null;
-                       
-                       if (bstate != null || mstate != null)
-                               return new Pair (bstate, mstate);
-                       else
-                               return null;
-               }
+                       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 override bool OnBubbleEvent (object source, EventArgs e)
                {
-                       if (!(e is DataListCommandEventArgs))
+                       DataListCommandEventArgs dlca = (e as DataListCommandEventArgs);
+                       if (dlca == null)
                                return false;
 
-                       DataListCommandEventArgs args = (DataListCommandEventArgs) e;
-                       OnItemCommand (args);
-                       string cmdName = args.CommandName.ToLower ();
-
-                       if (cmdName == "cancel") {
-                               OnCancelCommand (args);
-                       } else if (cmdName == "delete") {
-                               OnDeleteCommand (args);
-                       } else if (cmdName == "edit") {
-                               OnEditCommand (args);
-                       } else if (cmdName == "select") {
-                               SelectedIndex = args.Item.ItemIndex;
-                               OnSelectedIndexChanged (EventArgs.Empty);
-                       } else if (cmdName == "update") {
-                               OnUpdateCommand (args);
-                       }
+                       string cn = dlca.CommandName;
+                       CultureInfo inv = CultureInfo.InvariantCulture;
 
-                       return true;
+                       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;
                }
 
-               void InvokeCommandEvent (DataListCommandEventArgs args, object key)
-               {
-                       DataListCommandEventHandler dlceh = (DataListCommandEventHandler) Events [key];
-                       if (dlceh != null)
-                               dlceh (this, args);
-               }
-               
-               void InvokeItemEvent (DataListItemEventArgs args, object key)
-               {
-                       DataListItemEventHandler dlieh = (DataListItemEventHandler) Events [key];
-                       if (dlieh != null)
-                               dlieh (this, args);
-               }
-               
                protected virtual void OnCancelCommand (DataListCommandEventArgs e)
                {
-                       InvokeCommandEvent (e, CancelCommandEvent);
+                       DataListCommandEventHandler cancelCommand = (DataListCommandEventHandler) Events [cancelCommandEvent];
+                       if (cancelCommand != null)
+                               cancelCommand (this, e);
                }
 
                protected virtual void OnDeleteCommand (DataListCommandEventArgs e)
                {
-                       InvokeCommandEvent (e, DeleteCommandEvent);
+                       DataListCommandEventHandler deleteCommand = (DataListCommandEventHandler) Events [deleteCommandEvent];
+                       if (deleteCommand != null)
+                               deleteCommand (this, e);
                }
 
-               protected virtual void OnEditCommand (DataListCommandEventArgs e)
+               protected virtual void OnEditCommand (DataListCommandEventArgs e)
                {
-                       InvokeCommandEvent (e, EditCommandEvent);
+                       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)
                {
-                       InvokeCommandEvent (e, ItemCommandEvent);
+                       DataListCommandEventHandler itemCommand = (DataListCommandEventHandler) Events [itemCommandEvent];
+                       if (itemCommand != null)
+                               itemCommand (this, e);
                }
 
                protected virtual void OnItemCreated (DataListItemEventArgs e)
                {
-                       InvokeItemEvent (e, ItemCreatedEvent);
+                       DataListItemEventHandler itemCreated = (DataListItemEventHandler) Events [itemCreatedEvent];
+                       if (itemCreated != null)
+                               itemCreated (this, e);
                }
 
                protected virtual void OnItemDataBound (DataListItemEventArgs e)
                {
-                       InvokeItemEvent (e, ItemDataBoundEvent);
+                       DataListItemEventHandler itemDataBound = (DataListItemEventHandler) Events [itemDataBoundEvent];
+                       if (itemDataBound != null)
+                               itemDataBound (this, e);
                }
 
                protected virtual void OnUpdateCommand (DataListCommandEventArgs e)
                {
-                       InvokeCommandEvent (e, UpdateCommandEvent);
+                       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)
+                       if (style == null || false == ctrl.HasControls ())
                                return;
 
-                       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);
-#if NET_1_1
-                               templateTable.CaptionAlign = CaptionAlign;
-                               templateTable.Caption = Caption;
-#endif
-                               templateTable.RenderBeginTag (writer);
-                       } else {
-                               repeater.RepeatDirection = RepeatDirection;
-                               repeater.RepeatLayout = RepeatLayout;
-                               repeater.RepeatColumns = RepeatColumns;
-#if NET_1_1
-                               repeater.CaptionAlign = CaptionAlign;
-                               repeater.Caption = Caption;
-                               repeater.UseAccessibleHeader = UseAccessibleHeader;
-#endif
-                       }
-
-                       repeater.RenderRepeater (writer, this, ControlStyle, this);
-                       if (templateTable != null) {
-                               templateTable.RenderEndTag (writer);
-                       }
-               }
-
-               private DataListItem GetItem (ListItemType itemType, int repeatIndex)
-               {
-                       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) itemsArray [repeatIndex];
-                               break;
-                       case ListItemType.Separator:
-                               int index = 2 * repeatIndex + 1;
-                               if (headerTemplate != null)
-                                       index ++;
-                               retVal = (DataListItem) Controls [index];
-                               break;
+                       foreach (Control c in ctrl.Controls) {
+                               if (c is Table) {
+                                       Table tbl = (Table) c;
+                                       foreach (TableRow row in tbl.Rows)
+                                               row.MergeStyle (style);
+                               }
                        }
-                       return retVal;
                }
 
-               /// <summary>
-               /// Undocumented
-               /// </summary>
-               protected override void CreateControlHierarchy (bool useDataSource)
+               protected override void PrepareControlHierarchy ()
                {
-                       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 = GetResolvedDataSource ();
-                               if (source is ICollection) {
-                                       dkeys.Capacity = ((ICollection) source).Count;
-                                       itemsArray.Capacity = ((ICollection) source).Count;
-                               }
-                       }
+                       if (!HasControls () || Controls.Count == 0)
+                               return; // No one called CreateControlHierarchy() with DataSource != null
 
-                       int itemCount = 0;
-                       if (source != null) {
-                               int index = 0;
-                               int editIndex = EditItemIndex;
-                               int selIndex = SelectedIndex;
-                               string dataKey = DataKeyField;
-                               
-                               if (headerTemplate != null)
-                                       CreateItem (-1, ListItemType.Header, useDataSource, null);
-
-                               foreach (object current in source) {
-                                       if (useDataSource) {
-                                               try {
-                                                       dkeys.Add (DataBinder.GetPropertyValue (current, dataKey));
-                                               } catch {
-                                                       dkeys.Add (dkeys.Count);
+                       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;
                                                }
                                        }
 
-                                       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;
+                                       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);
                                        }
-
-                                       itemsArray.Add (CreateItem (index, type, useDataSource, current));
-                                       if (separatorTemplate != null)
-                                               CreateItem (index, ListItemType.Separator, useDataSource, null);
-                                       itemCount++;
-                                       index++;
+                                       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"] = (source != null ? itemCount : -1);
+#if NET_2_0
+               protected internal
+#else          
+               protected
+#endif         
+               override void RenderContents (HtmlTextWriter writer)
+               {
+                       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);
+                       }
                }
 
-               /// <summary>
-               /// Undocumented
-               /// </summary>
-               protected virtual DataListItem CreateItem (int itemIndex, ListItemType itemType)
+               protected override object SaveViewState ()
                {
-                       return new DataListItem (itemIndex, itemType);
+#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;
                }
 
-               private DataListItem CreateItem (int itemIndex, ListItemType itemType, bool dataBind, object dataItem)
+               protected override void TrackViewState ()
                {
-                       DataListItem retVal = CreateItem (itemIndex, itemType);
-                       DataListItemEventArgs e = new DataListItemEventArgs (retVal);
-                       InitializeItem (retVal);
-                       if (dataBind)
-                               retVal.DataItem = dataItem;
-               
-                       OnItemCreated (e);
-                       Controls.Add (retVal);
+                       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 ();
+               }
 
-                       if (dataBind) {
-                               retVal.DataBind ();
-                               OnItemDataBound (e);
-                               retVal.DataItem = null;
-                       }
 
-                       return retVal;
+               [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); }
                }
 
-               /// <summary>
-               /// Undocumented
-               /// </summary>
-               protected override void PrepareControlHierarchy ()
-               {
-                       if (Controls.Count == 0)
-                               return;
+               [WebSysDescription ("")]
+               [WebCategory ("Action")]
+               public event DataListCommandEventHandler EditCommand {
+                       add { Events.AddHandler (editCommandEvent, value); }
+                       remove { Events.RemoveHandler (editCommandEvent, value); }
+               }
 
-                       Style defaultStyle = null;
-                       Style rowStyle = null;
+               [WebSysDescription ("")]
+               [WebCategory ("Action")]
+               public event DataListCommandEventHandler ItemCommand {
+                       add { Events.AddHandler (itemCommandEvent, value); }
+                       remove { Events.RemoveHandler (itemCommandEvent, value); }
+               }
 
-                       if (alternatingItemStyle != null) {
-                               defaultStyle = new TableItemStyle ();
-                               defaultStyle.CopyFrom (itemStyle);
-                               defaultStyle.CopyFrom (alternatingItemStyle);
-                       } else {
-                               defaultStyle = itemStyle;
-                       }
+               [WebSysDescription ("")]
+               [WebCategory ("Action")]
+               public event DataListItemEventHandler ItemCreated {
+                       add { Events.AddHandler (itemCreatedEvent, value); }
+                       remove { Events.RemoveHandler (itemCreatedEvent, value); }
+               }
 
-                       foreach (DataListItem current in Controls) {
-                               rowStyle = null;
-                               switch (current.ItemType) {
-                               case ListItemType.Header:
-                                       if (headerStyle != null)
-                                               rowStyle = headerStyle;
-                                       break;
-                               case ListItemType.Footer:
-                                       if (footerStyle != null)
-                                               rowStyle = footerStyle;
-                                       break;
-                               case ListItemType.Separator:
-                                       rowStyle = separatorStyle;
-                                       break;
-                               case ListItemType.Item:
-                                       rowStyle = itemStyle;
-                                       break;
-                               case ListItemType.AlternatingItem:
-                                       rowStyle = defaultStyle;
-                                       break;
-                               case ListItemType.SelectedItem:
-                                       rowStyle = new TableItemStyle ();
-                                       if ((current.ItemIndex % 2) == 0) {
-                                               rowStyle.CopyFrom (itemStyle);
-                                       } else {
-                                               rowStyle.CopyFrom (defaultStyle);
-                                       }
-                                       rowStyle.CopyFrom (selectedItemStyle);
-                                       break;
-                               case ListItemType.EditItem:
-                                       rowStyle = new TableItemStyle ();
-                                       if ((current.ItemIndex % 2) == 0) {
-                                               rowStyle.CopyFrom (itemStyle);
-                                       } else {
-                                               rowStyle.CopyFrom (defaultStyle);
-                                       }
+               [WebSysDescription ("")]
+               [WebCategory ("Action")]
+               public event DataListItemEventHandler ItemDataBound {
+                       add { Events.AddHandler (itemDataBoundEvent, value); }
+                       remove { Events.RemoveHandler (itemDataBoundEvent, value); }
+               }
 
-                                       if (current.ItemIndex == SelectedIndex)
-                                               rowStyle.CopyFrom (selectedItemStyle);
+               [WebSysDescription ("")]
+               [WebCategory ("Action")]
+               public event DataListCommandEventHandler UpdateCommand {
+                       add { Events.AddHandler (updateCommandEvent, value); }
+                       remove { Events.RemoveHandler (updateCommandEvent, value); }
+               }
 
-                                       rowStyle.CopyFrom (editItemStyle);
-                                       break;
-                               }
 
-                               if (rowStyle == null)
-                                       continue;
+               // IRepeatInfoUser support
 
-                               if (!extractTemplateRows) {
-                                       current.MergeStyle (rowStyle);
-                                       continue;
-                               }
-                               
-                               if (current.HasControls ()) {
-                                       int len = current.Controls.Count;
-                                       for (int i = 0 ; i < len ; i++) {
-                                               Control currentCtrl = current.Controls [i];
-                                               if (!(currentCtrl is Table))
-                                                       continue;
-
-                                               foreach (TableRow cRow in ((Table) currentCtrl).Rows)
-                                                       cRow.MergeStyle (rowStyle);
-                                       }
+               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;
                        }
                }
 
-               /// <summary>
-               /// Undocumented
-               /// </summary>
-               protected virtual void InitializeItem (DataListItem item)
+               Style IRepeatInfoUser.GetItemStyle (ListItemType itemType, int repeatIndex)
                {
-                       ListItemType type = item.ItemType;
-                       ITemplate template = itemTemplate;
-
-                       switch (type) {
+                       DataListItem item = null;
+                       switch (itemType) {
                        case ListItemType.Header:
-                               template = headerTemplate;
-                               break;
                        case ListItemType.Footer:
-                               template = footerTemplate;
+                               if (repeatIndex >= 0 && (!HasControls () || repeatIndex >= Controls.Count))
+                                       throw new ArgumentOutOfRangeException ();
+
+                               item = FindFirstItem (itemType);
                                break;
+                       case ListItemType.Item:
                        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 (repeatIndex >= 0 && (!HasControls () || repeatIndex >= Controls.Count))
+                                       throw new ArgumentOutOfRangeException ();
 
-                               if (item.ItemIndex == SelectedIndex)
-                                       goto case ListItemType.SelectedItem;
-
-                               if ((item.ItemIndex % 2) != 0)
-                                       goto case ListItemType.AlternatingItem;
+                               item = FindBestItem (repeatIndex);
                                break;
                        case ListItemType.Separator:
-                               template = separatorTemplate;
+                               if (repeatIndex >= 0 && (!HasControls () || repeatIndex >= Controls.Count))
+                                       throw new ArgumentOutOfRangeException ();
+
+                               item = FindSpecificItem (itemType, repeatIndex);
+                               break;
+                       default:
+                               item = null;
                                break;
                        }
 
-                       if (template != null)
-                               template.InstantiateIn (item);
-               }
-
-               bool IRepeatInfoUser.HasFooter {
-                       get { return (ShowFooter && footerTemplate != null); }
-               }
+                       if (item == null || item.ControlStyleCreated == false)
+                               return null;
 
-               bool IRepeatInfoUser.HasHeader {
-                       get { return (ShowHeader && headerTemplate != null); }
+                       return item.ControlStyle;
                }
 
-               bool IRepeatInfoUser.HasSeparators {
-                       get { return (separatorTemplate != null); }
+               // Header and Footer don't have a "real" index (-1)
+               private DataListItem FindFirstItem (ListItemType itemType)
+               {
+                       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 {
-                       get {
-                               if (itemsArray != null)
-                                       return itemsArray.Count;
-
-                               return 0;
+               // Both Type and Index must match (e.g. Separator)
+               private DataListItem FindSpecificItem (ListItemType itemType, int repeatIndex)
+               {
+                       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)
                {
-                       DataListItem item = GetItem (itemType, repeatIndex);
-                       if (item == null || !item.ControlStyleCreated)
-                               return null;
+                       // if possible take the easy way out...
+                       if (!HasControls ())
+                               return;
 
-                       return item.ControlStyle;
+                       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);
+                       }
                }
        }
 }
-