Merge pull request #2916 from ludovic-henry/fix-40306
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / BaseDataList.cs
index 02a27c347a2e37990bbdbb378f03f1e4ce699605..178c576e6b39ec53e8647b691dc93fe027519bea 100644 (file)
@@ -4,7 +4,7 @@
 // Author:
 //     Sebastien Pouliot  <sebastien@ximian.com>
 //
-// Copyright (C) 2005 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2005-2010 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
@@ -30,8 +30,8 @@ using System.Collections;
 using System.ComponentModel;
 using System.Security.Permissions;
 
-namespace System.Web.UI.WebControls {
-
+namespace System.Web.UI.WebControls
+{
        // CAS
        [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
        [AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
@@ -39,20 +39,19 @@ namespace System.Web.UI.WebControls {
        [DefaultEvent ("SelectedIndexChanged")]
        [DefaultProperty ("DataSource")]
        [Designer ("System.Web.UI.Design.WebControls.BaseDataListDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
-       public abstract class BaseDataList : WebControl {
+       public abstract class BaseDataList : WebControl 
+       {
+               static readonly object selectedIndexChangedEvent = new object ();
 
-               private static readonly object selectedIndexChangedEvent = new object ();
+               DataKeyCollection keycoll;
+               object source;
 
-               private DataKeyCollection keycoll;
-               private object source;
-#if NET_2_0
-               //private string dataSourceId;
+               //string dataSourceId;
                IDataSource boundDataSource = null;
-               private bool initialized;
-               private bool requiresDataBinding;
-               private DataSourceSelectArguments selectArguments;
-               private IEnumerable data;
-#endif
+               bool initialized;
+               bool requiresDataBinding;
+               DataSourceSelectArguments selectArguments;
+               IEnumerable data;
 
                protected BaseDataList ()
                {
@@ -60,13 +59,11 @@ namespace System.Web.UI.WebControls {
 
 
                [DefaultValue ("")]
-#if NET_2_0
                [Localizable (true)]
-#endif
                [WebSysDescription ("")]
                [WebCategory ("Accessibility")]
                public virtual string Caption {
-                       get { return ViewState.GetString ("Caption", ""); }
+                       get { return ViewState.GetString ("Caption", String.Empty); }
                        set {
                                if (value == null)
                                        ViewState.Remove ("Caption");
@@ -86,9 +83,6 @@ namespace System.Web.UI.WebControls {
                        }
                }
 
-#if ONLY_1_1
-               [Bindable (true)]
-#endif
                [DefaultValue (-1)]
                [WebSysDescription("")]
                [WebCategory("Layout")]
@@ -101,9 +95,6 @@ namespace System.Web.UI.WebControls {
                        set { TableStyle.CellPadding = value; }
                }
 
-#if ONLY_1_1
-               [Bindable (true)]
-#endif
                [DefaultValue (0)]
                [WebSysDescription("")]
                [WebCategory("Layout")]
@@ -124,14 +115,12 @@ namespace System.Web.UI.WebControls {
                }
 
                [DefaultValue ("")]
-#if NET_2_0
                [Themeable (false)]
-#endif
                [MonoTODO ("incomplete")]
                [WebSysDescription("")]
                [WebCategory("Data")]
                public virtual string DataKeyField {
-                       get { return ViewState.GetString ("DataKeyField", ""); }
+                       get { return ViewState.GetString ("DataKeyField", String.Empty); }
                        set {
                                if (value == null)
                                        ViewState.Remove ("DataKeyField");
@@ -164,61 +153,47 @@ namespace System.Web.UI.WebControls {
                }
 
                [DefaultValue ("")]
-#if NET_2_0
                [Themeable (false)]
-#endif
                [WebSysDescription("")]
                [WebCategory("Data")]
                public string DataMember {
-                       get { return ViewState.GetString ("DataMember", ""); }
+                       get { return ViewState.GetString ("DataMember", String.Empty); }
                        set {
                                if (value == null)
                                        ViewState.Remove ("DataMember");
                                else
                                        ViewState ["DataMember"] = value;
-#if NET_2_0
-                               if (!Initialized)
-                                       OnDataPropertyChanged ();
-#endif
+                               OnDataPropertyChanged ();
                        }
                }
 
                [Bindable (true)]
                [DefaultValue (null)]
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
-#if NET_2_0
                [Themeable (false)]
-#endif
                [WebSysDescription("")]
                [WebCategory("Data")]
-               public virtual object DataSource {
+                       public virtual object DataSource {
                        get { return source; }
                        set {
                                if ((value == null) || (value is IEnumerable) || (value is IListSource)) {
-#if NET_2_0
-// FIXME - can't duplicate in a test case ? LAMESPEC ?
-// can't duplicate in a test case
-//                                     if ((dataSourceId != null) && (dataSourceId.Length != 0))
-//                                             throw new HttpException (Locale.GetText ("DataSourceID is already set."));
+                                       // FIXME - can't duplicate in a test case ? LAMESPEC ?
+                                       // can't duplicate in a test case
+                                       // if ((dataSourceId != null) && (dataSourceId.Length != 0))
+                                       //      throw new HttpException (Locale.GetText ("DataSourceID is already set."));
 
                                        source = value;
 
-                                       if (!Initialized)
-                                               OnDataPropertyChanged ();
-#else
-                                       source = value;
-#endif
+                                       OnDataPropertyChanged ();
+
                                } else {
                                        string msg = Locale.GetText ("Invalid data source. This requires an object implementing {0} or {1}.",
-                                               "IEnumerable", "IListSource");
+                                                                    "IEnumerable", "IListSource");
                                        throw new ArgumentException (msg);
                                }
                        }
                }
 
-#if ONLY_1_1
-               [Bindable (true)]
-#endif
                [DefaultValue (GridLines.Both)]
                [WebSysDescription("")]
                [WebCategory("Appearance")]
@@ -231,9 +206,6 @@ namespace System.Web.UI.WebControls {
                        set { TableStyle.GridLines = value; }
                }
 
-#if ONLY_1_1
-               [Bindable (true)]
-#endif
                [Category ("Layout")]
                [DefaultValue (HorizontalAlign.NotSet)]
                [WebSysDescription("")]
@@ -251,12 +223,12 @@ namespace System.Web.UI.WebControls {
                        get { return ViewState.GetBool ("UseAccessibleHeader", false); }
                        set { ViewState ["UseAccessibleHeader"] = value; }
                }
-#if NET_2_0
+
                [DefaultValue ("")]
                [IDReferenceProperty (typeof (DataSourceControl))]
                [Themeable (false)]
                public virtual string DataSourceID {
-                       get { return ViewState.GetString ("DataSourceID", ""); }
+                       get { return ViewState.GetString ("DataSourceID", String.Empty); }
                        set {
                                // LAMESPEC ? this is documented as an HttpException in beta2
                                if (source != null)
@@ -264,8 +236,7 @@ namespace System.Web.UI.WebControls {
 
                                ViewState ["DataSourceID"] = value;
 
-                               if (!Initialized)
-                                       OnDataPropertyChanged ();
+                               OnDataPropertyChanged ();
                        }
                }
 
@@ -291,8 +262,10 @@ namespace System.Web.UI.WebControls {
                                return selectArguments;
                        }
                }
-#endif
-               private TableStyle TableStyle {
+               public override bool SupportsDisabledAttribute {
+                       get { return RenderingCompatibilityLessThan40; }
+               }
+               TableStyle TableStyle {
                        // this will throw an InvalidCasException just like we need
                        get { return (TableStyle) ControlStyle; }
                }
@@ -304,20 +277,16 @@ namespace System.Web.UI.WebControls {
                }
 
                // see Kothari, page 435
-#if NET_2_0
-               protected internal
-#else          
-               protected
-#endif         
-               override void CreateChildControls ()
+               protected internal override void CreateChildControls ()
                {
                        // We are recreating the children from viewstate
                        if (HasControls ())
-                               Controls.Clear();
+                               base.Controls.Clear();
 
-                       // If presents, build the children from the viewstate
-                       if (ViewState ["Items"] != null)
+                       if (IsDataBound)
                                CreateControlHierarchy (false);
+                       else if (RequiresDataBinding)
+                               EnsureDataBound ();
                }
 
                protected abstract void CreateControlHierarchy (bool useDataSource);
@@ -342,8 +311,10 @@ namespace System.Web.UI.WebControls {
                        // Indicate that child controls have been created, preventing
                        // CreateChildControls from getting called.
                        ChildControlsCreated = true;    
+                       RequiresDataBinding = false;
+                       IsDataBound = true;
                }
-#if NET_2_0
+
                protected virtual DataSourceSelectArguments CreateDataSourceSelectArguments ()
                {
                        return DataSourceSelectArguments.Empty;
@@ -356,7 +327,7 @@ namespace System.Web.UI.WebControls {
                                DataBind ();
                }
 
-               private void SelectCallback (IEnumerable data)
+               void SelectCallback (IEnumerable data)
                {
                        this.data = data;
                }
@@ -373,15 +344,25 @@ namespace System.Web.UI.WebControls {
                        dsv.Select (SelectArguments, new DataSourceViewSelectCallback (SelectCallback));
                        return data;
                }
-#endif
+
+               bool IsDataBound {
+                       get {
+                               return ViewState.GetBool ("_DataBound", false);
+                       }
+                       set {
+                               ViewState ["_DataBound"] = value;
+                       }
+               }
 
                protected override void OnDataBinding (EventArgs e)
                {
                        base.OnDataBinding (e);
                }
-#if NET_2_0
+
                protected virtual void OnDataPropertyChanged ()
                {
+                       if (Initialized)
+                               RequiresDataBinding = true;
                }
 
                protected virtual void OnDataSourceViewChanged (object sender, EventArgs e)
@@ -392,18 +373,41 @@ namespace System.Web.UI.WebControls {
                protected internal override void OnInit (EventArgs e)
                {
                        base.OnInit (e);
-               }
+                       Page page = Page;
+                       if (page != null) {
+                               page.PreLoad += new EventHandler (OnPagePreLoad);
 
+                               if (!IsViewStateEnabled && page.IsPostBack)
+                                       RequiresDataBinding = true;
+                       }
+               }
+               
+               void OnPagePreLoad (object sender, EventArgs e)
+               {
+                       if (!Initialized)
+                               Initialize ();
+               }
+               
                protected internal override void OnLoad (EventArgs e)
                {
-                       if ((Page != null) && !Page.IsPostBack)
-                               RequiresDataBinding = true;
+                       if (!Initialized)
+                               Initialize ();
+
+                       base.OnLoad (e);
+               }
+               
+               void Initialize ()
+               {
+                       Page page = Page;
+                       if (page != null) {
+                               if (!page.IsPostBack || (IsViewStateEnabled && !IsDataBound))
+                                       RequiresDataBinding = true;
+                       }
 
                        if (IsBoundUsingDataSourceID)
                                ConnectToDataSource ();
 
                        initialized = true;
-                       base.OnLoad (e);
                }
 
                protected internal override void OnPreRender (EventArgs e)
@@ -411,7 +415,7 @@ namespace System.Web.UI.WebControls {
                        EnsureDataBound ();
                        base.OnPreRender (e);
                }
-#endif
+
                protected virtual void OnSelectedIndexChanged (EventArgs e)
                {
                        EventHandler selectedIndexChanged = (EventHandler) Events [selectedIndexChangedEvent];
@@ -421,12 +425,7 @@ namespace System.Web.UI.WebControls {
 
                protected abstract void PrepareControlHierarchy ();
 
-#if NET_2_0
-               protected internal
-#else          
-               protected
-#endif         
-               override void Render (HtmlTextWriter writer)
+               protected internal override void Render (HtmlTextWriter writer)
                {
                        PrepareControlHierarchy ();
                        // don't call base class or RenderBegin|EndTag
@@ -434,7 +433,6 @@ namespace System.Web.UI.WebControls {
                        RenderContents (writer);
                }
 
-
                [WebSysDescription("")]
                [WebCategory("Action")]
                public event EventHandler SelectedIndexChanged {
@@ -442,7 +440,6 @@ namespace System.Web.UI.WebControls {
                        remove { Events.RemoveHandler (selectedIndexChangedEvent, value); }
                }
 
-
                static public bool IsBindableType (Type type)
                {
                        // I can't believe how many NRE are possible in System.Web
@@ -450,28 +447,27 @@ namespace System.Web.UI.WebControls {
                                throw new NullReferenceException ();
 
                        switch (Type.GetTypeCode (type)) {
-                       case TypeCode.Boolean:
-                       case TypeCode.Byte:
-                       case TypeCode.SByte:
-                       case TypeCode.Int16:
-                       case TypeCode.UInt16:
-                       case TypeCode.Int32:
-                       case TypeCode.UInt32:
-                       case TypeCode.Int64:
-                       case TypeCode.UInt64:
-                       case TypeCode.Char:
-                       case TypeCode.Double:
-                       case TypeCode.Single:
-                       case TypeCode.DateTime:
-                       case TypeCode.Decimal:
-                       case TypeCode.String:
-                               return true;
-                       default:
-                               return false;
+                               case TypeCode.Boolean:
+                               case TypeCode.Byte:
+                               case TypeCode.SByte:
+                               case TypeCode.Int16:
+                               case TypeCode.UInt16:
+                               case TypeCode.Int32:
+                               case TypeCode.UInt32:
+                               case TypeCode.Int64:
+                               case TypeCode.UInt64:
+                               case TypeCode.Char:
+                               case TypeCode.Double:
+                               case TypeCode.Single:
+                               case TypeCode.DateTime:
+                               case TypeCode.Decimal:
+                               case TypeCode.String:
+                                       return true;
+                               default:
+                                       return false;
                        }
                }
 
-#if NET_2_0
                void ConnectToDataSource ()
                {
                        if (NamingContainer != null)
@@ -487,6 +483,5 @@ namespace System.Web.UI.WebControls {
                        DataSourceView dsv = boundDataSource.GetView (String.Empty);
                        dsv.DataSourceViewChanged += new EventHandler (OnDataSourceViewChanged);
                }
-#endif
        }
 }