Page.Validate() is called when CausesValidation=true
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / DataBoundControl.cs
index c841a7a6df86ffd0473638fe092600eb8939bb89..9c64bd432f7cefd8abf950c98860e818eacecfc2 100644 (file)
@@ -36,10 +36,15 @@ using System.Collections.Specialized;
 using System.Text;
 using System.Web.Util;
 using System.ComponentModel;
+using System.Security.Permissions;
 
 namespace System.Web.UI.WebControls {
 
-       [DesignerAttribute ("System.Web.UI.Design.WebControls.HierarchicalDataBoundControlDesigner, System.Design, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.ComponentModel.Design.IDesigner")]
+       // CAS
+       [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
+       [AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
+       // attributes
+       [DesignerAttribute ("System.Web.UI.Design.WebControls.DataBoundControlDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
        public abstract class DataBoundControl : BaseDataBoundControl
        {
                DataSourceSelectArguments selectArguments;
@@ -48,11 +53,30 @@ namespace System.Web.UI.WebControls {
                protected DataBoundControl ()
                {
                }
+
+               /* Used for controls that used to inherit from
+                * WebControl, so the tag can propagate upwards
+                */
+               internal DataBoundControl (HtmlTextWriterTag tag) : base (tag)
+               {
+               }
+               
                
-               protected IDataSource GetDataSource ()
+               protected virtual IDataSource GetDataSource ()
                {
                        if (IsBoundUsingDataSourceID) {
-                               Control ctrl = NamingContainer.FindControl (DataSourceID);
+                               Control namingContainer;
+                               Control ctrl = null;
+
+                               namingContainer = NamingContainer;
+                               
+                               while (namingContainer != null) {
+                                       ctrl = namingContainer.FindControl (DataSourceID);
+                                       if (ctrl != null)
+                                               break;
+                                       namingContainer = namingContainer.NamingContainer;
+                               }
+
                                if (ctrl == null)
                                        throw new HttpException (string.Format ("A control with ID '{0}' could not be found.", DataSourceID));
                                if (!(ctrl is IDataSource))
@@ -71,7 +95,7 @@ namespace System.Web.UI.WebControls {
                        throw new HttpException (string.Format ("Unexpected data source type: {0}", DataSource.GetType()));
                }
                
-               protected DataSourceView GetData ()
+               protected virtual DataSourceView GetData ()
                {
                        if (currentView == null)
                                UpdateViewData ();
@@ -121,18 +145,16 @@ namespace System.Web.UI.WebControls {
                                view.DataSourceViewChanged += new EventHandler (OnDataSourceViewChanged);
                }
                
-               // should be `internal protected' (why, oh WHY did they do that !?!)
-               protected override void OnLoad (EventArgs e)
+               protected internal override void OnLoad (EventArgs e)
                {
-                       if (IsBoundUsingDataSourceID && (!Page.IsPostBack || !EnableViewState))
+                       if (!Page.IsPostBack || (IsViewStateEnabled && !IsDataBound))
                                RequiresDataBinding = true;
 
                        base.OnLoad(e);
                }
                
-               protected virtual void PerformDataBinding (IEnumerable data)
+               protected internal virtual void PerformDataBinding (IEnumerable data)
                {
-                       OnDataBinding (EventArgs.Empty);
                }
 
                protected override void ValidateDataSource (object dataSource)
@@ -145,44 +167,42 @@ namespace System.Web.UI.WebControls {
                [ThemeableAttribute (false)]
                [DefaultValueAttribute ("")]
                [WebCategoryAttribute ("Data")]
-               public string DataMember
-               {
-                       get {
-                               object o = ViewState["DataMember"];
-                               if(o!=null)
-                                       return (string)o;
-                               return String.Empty;
-                       }
-                       set {
-                               ViewState["DataMember"] = value;
-                       }
+               public virtual string DataMember {
+                       get { return ViewState.GetString ("DataMember", ""); }
+                       set { ViewState["DataMember"] = value; }
                }
 
-           [IDReferencePropertyAttribute (typeof(HierarchicalDataSourceControl))]
+               [IDReferencePropertyAttribute (typeof(DataSourceControl))]
                public override string DataSourceID {
-                       get {
-                               object o = ViewState ["DataSourceID"];
-                               if (o != null)
-                                       return (string)o;
-                               
-                               return String.Empty;
-                       }
+                       get { return ViewState.GetString ("DataSourceID", ""); }
                        set {
                                ViewState ["DataSourceID"] = value;
                                base.DataSourceID = value;
                        }
                }
                
+               // 
+               // See DataBoundControl.MarkAsDataBound msdn doc for the code example
+               // 
                protected override void PerformSelect ()
                {
+                       // Call OnDataBinding here if bound to a data source using the
+                       // DataSource property (instead of a DataSourceID), because the
+                       // databinding statement is evaluated before the call to GetData.       
+                       if (!IsBoundUsingDataSourceID)
+                               OnDataBinding (EventArgs.Empty);
+
                        DataSourceView view = GetData ();
-                       if (view != null)
+                       if (view != null) {
                                view.Select (SelectArguments, new DataSourceViewSelectCallback (OnSelect));
+                               MarkAsDataBound ();
+                       }
                }
                
                void OnSelect (IEnumerable data)
                {
                        PerformDataBinding (data);
+                       OnDataBound (EventArgs.Empty);
                }
                
                protected virtual DataSourceSelectArguments CreateDataSourceSelectArguments ()
@@ -197,6 +217,21 @@ namespace System.Web.UI.WebControls {
                                return selectArguments;
                        }
                }
+
+               bool IsDataBound {
+                       get {
+                               object dataBound = ViewState ["DataBound"];
+                               return dataBound != null ? (bool) dataBound : false;
+                       }
+                       set {
+                               ViewState ["DataBound"] = value;
+                       }
+               }
+
+               protected void MarkAsDataBound ()
+               {
+                       IsDataBound = true;
+               }
        }
 }
 #endif