* Style.cs: fixed restoring FontInfo from ViewState
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / BaseDataList.cs
old mode 100755 (executable)
new mode 100644 (file)
index 6c30584..02a27c3
@@ -1,16 +1,10 @@
 //
 // System.Web.UI.WebControls.BaseDataList.cs
 //
-// Authors:
-//   Gaurav Vaish (gvaish@iitk.ac.in)
-//   Andreas Nahr (ClassDevelopment@A-SoftTech.com)
-//   Sanjay Gupta (gsanjay@novell.com)
+// Author:
+//     Sebastien Pouliot  <sebastien@ximian.com>
 //
-// (C) Gaurav Vaish (2001)
-// (C) 2003 Andreas Nahr
-// (C) 2004 Novell, Inc. (http://www.novell.com)
-//
-
+// Copyright (C) 2005 Novell, Inc (http://www.novell.com)
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-using System;
-using System.ComponentModel;
-using System.ComponentModel.Design;
 using System.Collections;
-using System.Web;
-using System.Web.UI;
-using System.Web.Util;
-
-namespace System.Web.UI.WebControls
-{
-       [DefaultEvent("SelectedIndexChanged")]
-       [DefaultProperty("DataSource")]
-       [Designer("System.Web.UI.Design.WebControls.BaseDataListDesigner, " + Consts.AssemblySystem_Design, typeof (IDesigner))]
-       public abstract class BaseDataList: WebControl
-       {
-               private  static readonly object SelectedIndexChangedEvent = new object();
-               internal static string          ItemCountViewStateKey     = "_!ItemCount";
-
-               private DataKeyCollection dataKeys;
-               private object            dataSource;
-               
+using System.ComponentModel;
+using System.Security.Permissions;
+
+namespace System.Web.UI.WebControls {
+
+       // CAS
+       [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
+       [AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
+       // attributes
+       [DefaultEvent ("SelectedIndexChanged")]
+       [DefaultProperty ("DataSource")]
+       [Designer ("System.Web.UI.Design.WebControls.BaseDataListDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
+       public abstract class BaseDataList : WebControl {
+
+               private static readonly object selectedIndexChangedEvent = new object ();
+
+               private DataKeyCollection keycoll;
+               private object source;
 #if NET_2_0
-               bool inited;
-               IDataSource currentSource;
-               DataSourceSelectArguments selectArguments = null;
-               bool requiresDataBinding;
+               //private string dataSourceId;
+               IDataSource boundDataSource = null;
+               private bool initialized;
+               private bool requiresDataBinding;
+               private DataSourceSelectArguments selectArguments;
+               private IEnumerable data;
 #endif
 
-               public BaseDataList() : base()
+               protected BaseDataList ()
                {
                }
 
-               public static bool IsBindableType(Type type)
-               {
-                       if(type.IsPrimitive || type == typeof(string) || type == typeof(DateTime) || type == typeof(Decimal))
-                               return true;
-                       return false;
-               }
 
-               public override ControlCollection Controls
-               {
-                       get
-                       {
-                               EnsureChildControls();
-                               return base.Controls;
+               [DefaultValue ("")]
+#if NET_2_0
+               [Localizable (true)]
+#endif
+               [WebSysDescription ("")]
+               [WebCategory ("Accessibility")]
+               public virtual string Caption {
+                       get { return ViewState.GetString ("Caption", ""); }
+                       set {
+                               if (value == null)
+                                       ViewState.Remove ("Caption");
+                               else
+                                       ViewState ["Caption"] = value;
                        }
                }
 
-               public override void DataBind()
-               {
-                       #if NET_2_0
-                       RequiresDataBinding = false;
-                       #endif
-                       OnDataBinding(EventArgs.Empty);
-               }
+               [DefaultValue (TableCaptionAlign.NotSet)]
+               public virtual TableCaptionAlign CaptionAlign {
+                       get { return (TableCaptionAlign) ViewState.GetInt ("CaptionAlign", (int)TableCaptionAlign.NotSet); }
+                       set {
+                               if ((value < TableCaptionAlign.NotSet) || (value > TableCaptionAlign.Right))
+                                       throw new ArgumentOutOfRangeException (Locale.GetText ("Invalid TableCaptionAlign value."));
 
-               [WebCategory("Action")]
-               [WebSysDescription("BaseDataList_OnSelectedIndexChanged")]
-               public event EventHandler SelectedIndexChanged
-               {
-                       add
-                       {
-                               Events.AddHandler(SelectedIndexChangedEvent, value);
-                       }
-                       remove
-                       {
-                               Events.RemoveHandler(SelectedIndexChangedEvent, value);
+                               ViewState ["CaptionAlign"] = value;
                        }
                }
 
-#if !NET_2_0
-               [Bindable(true)]
+#if ONLY_1_1
+               [Bindable (true)]
 #endif
-               [DefaultValue(-1)]
+               [DefaultValue (-1)]
+               [WebSysDescription("")]
                [WebCategory("Layout")]
-               [WebSysDescription("BaseDataList_CellPadding")]
-               public virtual int CellPadding
-               {
-                       get
-                       {
-                               if(!ControlStyleCreated)
-                                       return -1;
-                               return ((TableStyle)ControlStyle).CellPadding;
-                       }
-                       set
-                       {
-                               ((TableStyle)ControlStyle).CellPadding = value;
+               public virtual int CellPadding {
+                       get {
+                               if (!ControlStyleCreated)
+                                       return -1; // default value
+                               return TableStyle.CellPadding;
                        }
+                       set { TableStyle.CellPadding = value; }
                }
 
-#if !NET_2_0
-               [Bindable(true)]
+#if ONLY_1_1
+               [Bindable (true)]
 #endif
-               [DefaultValue(-1)]
+               [DefaultValue (0)]
+               [WebSysDescription("")]
                [WebCategory("Layout")]
-               [WebSysDescription("BaseDataList_CellSpacing")]
-               public virtual int CellSpacing
-               {
-                       get
-                       {
-                               if(!ControlStyleCreated)
-                                       return -1;
-                               return ((TableStyle)ControlStyle).CellSpacing;
+               public virtual int CellSpacing {
+                       get {
+                               if (!ControlStyleCreated)
+                                       return 0; // default value
+                               return TableStyle.CellSpacing;
                        }
-                       set
-                       {
-                               ((TableStyle)ControlStyle).CellSpacing = value;
+                       set { TableStyle.CellSpacing = value; }
+               }
+
+               public override ControlCollection Controls {
+                       get {
+                               EnsureChildControls ();
+                               return base.Controls;
                        }
                }
 
+               [DefaultValue ("")]
 #if NET_2_0
-           [ThemeableAttribute (false)]
+               [Themeable (false)]
 #endif
-               [DefaultValue("")]
+               [MonoTODO ("incomplete")]
+               [WebSysDescription("")]
                [WebCategory("Data")]
-               [WebSysDescription("BaseDataList_DataKeyField")]
-               public virtual string DataKeyField
-               {
-                       get
-                       {
-                               object o = ViewState["DataKeyField"];
-                               if(o!=null)
-                                       return (string)o;
-                               return String.Empty;
-                       }
-                       set
-                       {
-                               ViewState["DataKeyField"] = value;
+               public virtual string DataKeyField {
+                       get { return ViewState.GetString ("DataKeyField", ""); }
+                       set {
+                               if (value == null)
+                                       ViewState.Remove ("DataKeyField");
+                               else
+                                       ViewState ["DataKeyField"] = value;
                        }
                }
 
-               [Browsable(true)]
-               [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
-               [WebSysDescription("BaseDataList_DataKeys")]
-               public DataKeyCollection DataKeys
-               {
-                       get
-                       {
-                               if( dataKeys==null )
-                                       dataKeys = new DataKeyCollection(DataKeysArray);
-                               return dataKeys;
+               [Browsable (false)]
+               [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
+               [WebSysDescription("")]
+               [WebCategory("Data")]
+               public DataKeyCollection DataKeys {
+                       get {
+                               if (keycoll == null)
+                                       keycoll = new DataKeyCollection (DataKeysArray);
+                               return keycoll;
+                       }
+               }
 
+               protected ArrayList DataKeysArray {
+                       get {
+                               ArrayList keys = (ArrayList) ViewState ["DataKeys"];
+                               if (keys == null) {
+                                       keys = new ArrayList ();
+                                       ViewState ["DataKeys"] = keys;
+                               }
+                               return keys;
                        }
                }
 
+               [DefaultValue ("")]
 #if NET_2_0
-           [ThemeableAttribute (false)]
+               [Themeable (false)]
 #endif
-               [DefaultValue("")]
+               [WebSysDescription("")]
                [WebCategory("Data")]
-               [WebSysDescription("BaseDataList_DataMember")]
-               public string DataMember
-               {
-                       get
-                       {
-                               object o = ViewState["DataMember"];
-                               if(o!=null)
-                                       return (string)o;
-                               return String.Empty;
-                       }
-                       set
-                       {
-                               ViewState["DataMember"] = value;
+               public string DataMember {
+                       get { return ViewState.GetString ("DataMember", ""); }
+                       set {
+                               if (value == null)
+                                       ViewState.Remove ("DataMember");
+                               else
+                                       ViewState ["DataMember"] = value;
+#if NET_2_0
+                               if (!Initialized)
+                                       OnDataPropertyChanged ();
+#endif
                        }
                }
 
+               [Bindable (true)]
+               [DefaultValue (null)]
+               [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
 #if NET_2_0
-           [ThemeableAttribute (false)]
+               [Themeable (false)]
 #endif
-               [Bindable(true)]
-               [DefaultValue(null)]
-               [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
+               [WebSysDescription("")]
                [WebCategory("Data")]
-               [WebSysDescription("BaseDataList_DataSource")]
                public virtual object DataSource {
-                       get {
-                               return dataSource;
-                       }
+                       get { return source; }
                        set {
-                               if (value == null || value is IListSource || value is IEnumerable) {
-                                       dataSource = value;
+                               if ((value == null) || (value is IEnumerable) || (value is IListSource)) {
 #if NET_2_0
-                                       if (inited) OnDataPropertyChanged ();
+// 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
                                } else {
-                                       throw new ArgumentException (HttpRuntime.FormatResourceString (
-                                                               "Invalid_DataSource_Type", ID));
+                                       string msg = Locale.GetText ("Invalid data source. This requires an object implementing {0} or {1}.",
+                                               "IEnumerable", "IListSource");
+                                       throw new ArgumentException (msg);
                                }
                        }
                }
 
-#if !NET_2_0
-               [Bindable(true)]
+#if ONLY_1_1
+               [Bindable (true)]
 #endif
-               [DefaultValue(GridLines.Both)]
+               [DefaultValue (GridLines.Both)]
+               [WebSysDescription("")]
                [WebCategory("Appearance")]
-               [WebSysDescription("BaseDataList_GridLines")]
-               public virtual GridLines GridLines
-               {
-                       get
-                       {
-                               if(ControlStyleCreated)
-                                       return ((TableStyle)ControlStyle).GridLines;
-                               return GridLines.Both;
+               public virtual GridLines GridLines {
+                       get {
+                               if (!ControlStyleCreated)
+                                       return GridLines.Both; // default value
+                               return TableStyle.GridLines;
                        }
-                       set
-                       {
-                               ((TableStyle)ControlStyle).GridLines = value;
+                       set { TableStyle.GridLines = value; }
+               }
+
+#if ONLY_1_1
+               [Bindable (true)]
+#endif
+               [Category ("Layout")]
+               [DefaultValue (HorizontalAlign.NotSet)]
+               [WebSysDescription("")]
+               public virtual HorizontalAlign HorizontalAlign {
+                       get {
+                               if (!ControlStyleCreated)
+                                       return HorizontalAlign.NotSet; // default value
+                               return TableStyle.HorizontalAlign;
                        }
+                       set { TableStyle.HorizontalAlign = value; }
+               }
+
+               [DefaultValue (false)]
+               public virtual bool UseAccessibleHeader {
+                       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", ""); }
+                       set {
+                               // LAMESPEC ? this is documented as an HttpException in beta2
+                               if (source != null)
+                                       throw new InvalidOperationException (Locale.GetText ("DataSource is already set."));
 
-               // LAMESPEC HorizontalAlign has a Category attribute, this should obviously be a WebCategory attribute
-               // but is defined incorrectly in the MS framework
+                               ViewState ["DataSourceID"] = value;
 
-#if !NET_2_0
-               [Bindable(true)]
-#endif
-               [DefaultValue(HorizontalAlign.NotSet)]
-               [Category("Layout")]
-               [WebSysDescription("BaseDataList_HorizontalAlign")]
-               public virtual HorizontalAlign HorizontalAlign
-               {
-                       get
-                       {
-                               if(ControlStyleCreated)
-                                       return ((TableStyle)ControlStyle).HorizontalAlign;
-                               return HorizontalAlign.NotSet;
+                               if (!Initialized)
+                                       OnDataPropertyChanged ();
                        }
-                       set
-                       {
-                               ((TableStyle)ControlStyle).HorizontalAlign = value;
+               }
+
+               protected bool Initialized {
+                       get { return initialized; }
+               }
+
+               // as documented in BaseDataBoundControl
+               protected bool IsBoundUsingDataSourceID {
+                       get { return (DataSourceID.Length != 0); }
+               }
+
+               // doc says ?automatically? called by ASP.NET
+               protected bool RequiresDataBinding {
+                       get { return requiresDataBinding; }
+                       set { requiresDataBinding = value; }
+               }
+
+               protected DataSourceSelectArguments SelectArguments {
+                       get {
+                               if (selectArguments == null)
+                                       selectArguments = CreateDataSourceSelectArguments ();
+                               return selectArguments;
                        }
                }
+#endif
+               private TableStyle TableStyle {
+                       // this will throw an InvalidCasException just like we need
+                       get { return (TableStyle) ControlStyle; }
+               }
+
 
-               protected ArrayList DataKeysArray
+               protected override void AddParsedSubObject (object obj)
                {
-                       get
-                       {
-                               object o = ViewState["DataKeys"];
-                               if(o == null)
-                               {
-                                       o = new ArrayList();
-                                       ViewState["DataKeys"] = o;
-                               }
-                               return (ArrayList)o;
-                       }
+                       // don't accept controls
                }
 
-               protected override void AddParsedSubObject(object o)
+               // see Kothari, page 435
+#if NET_2_0
+               protected internal
+#else          
+               protected
+#endif         
+               override void CreateChildControls ()
                {
-                       // Preventing literal controls from being added as children.
+                       // We are recreating the children from viewstate
+                       if (HasControls ())
+                               Controls.Clear();
+
+                       // If presents, build the children from the viewstate
+                       if (ViewState ["Items"] != null)
+                               CreateControlHierarchy (false);
                }
 
-               protected override void CreateChildControls()
+               protected abstract void CreateControlHierarchy (bool useDataSource);
+
+               // see Kothari, page 434
+               // see also: Control.DataBind on Fx 2.0 beta2 documentation
+               public override void DataBind ()
                {
-                       Controls.Clear();
-                       if(ViewState[ItemCountViewStateKey]!=null)
-                       {
-                               CreateControlHierarchy(false);
-                               ClearChildViewState();
-                       }
+                       // unlike most samples we don't call base.OnDataBinding
+                       // because we override it in this class
+                       OnDataBinding (EventArgs.Empty);
+
+                       // Clear, if required, then recreate the control hierarchy
+                       if (HasControls ())
+                               Controls.Clear ();
+                       if (HasChildViewState)
+                               ClearChildViewState ();
+                       if (!IsTrackingViewState)
+                               TrackViewState ();
+                       CreateControlHierarchy (true);
+
+                       // Indicate that child controls have been created, preventing
+                       // CreateChildControls from getting called.
+                       ChildControlsCreated = true;    
+               }
+#if NET_2_0
+               protected virtual DataSourceSelectArguments CreateDataSourceSelectArguments ()
+               {
+                       return DataSourceSelectArguments.Empty;
                }
 
-               protected override void OnDataBinding(EventArgs e)
+               // best documentation is (again) in BaseDataBoundControl
+               protected void EnsureDataBound ()
                {
-                       base.OnDataBinding(e);
-                       Controls.Clear();
-                       ClearChildViewState();
-                       CreateControlHierarchy(true);
-                       ChildControlsCreated = true;
-                       TrackViewState();
+                       if (IsBoundUsingDataSourceID && RequiresDataBinding)
+                               DataBind ();
                }
 
-               protected virtual void OnSelectedIndexChanged(EventArgs e)
+               private void SelectCallback (IEnumerable data)
                {
-                       if(Events != null)
-                       {
-                               EventHandler eh = (EventHandler)(Events[SelectedIndexChangedEvent]);
-                               if(eh!=null)
-                                       eh(this, e);
-                       }
+                       this.data = data;
                }
 
-               protected override void Render(HtmlTextWriter writer)
+               protected virtual IEnumerable GetData ()
                {
-                       PrepareControlHierarchy();
-                       RenderContents(writer);
-               }
-
-               protected abstract void PrepareControlHierarchy();
-               protected abstract void CreateControlHierarchy(bool useDataSource);
-               
-               #if NET_2_0
-                       
-                       protected override void OnInit (EventArgs e)
-                       {
-                               base.OnInit(e);
-                               Page.PreLoad += new EventHandler (OnPagePreLoad);
-                       }
-                       
-                       void OnPagePreLoad (object sender, EventArgs e)
-                       {
-                               SubscribeSourceChangeEvent ();
-                               inited = true;
-                       }
-               
-                       void SubscribeSourceChangeEvent ()
-                       {
-                               IDataSource ds = GetDataSource ();
-                               
-                               if (currentSource != ds && currentSource != null) {
-                                       currentSource.DataSourceChanged -= new EventHandler (OnDataSourceViewChanged);
-                                       currentSource = ds;
-                               }
-                                       
-                               if (ds != null)
-                                       ds.DataSourceChanged += new EventHandler (OnDataSourceViewChanged);
-                       }
-                       
-                       protected override void OnLoad (EventArgs e)
-                       {
-                               if (IsBoundUsingDataSourceID && (!Page.IsPostBack || !EnableViewState))
-                                       RequiresDataBinding = true;
-       
-                               base.OnLoad(e);
-                       }
-                       
-                       protected override void OnPreRender (EventArgs e)
-                       {
-                               EnsureDataBound ();
-                               base.OnPreRender (e);
-                       }
-                               
-                       protected bool IsBoundUsingDataSourceID {
-                               get { return DataSourceID.Length > 0; }
-                       }
-                       
-                       protected void EnsureDataBound ()
-                       {
-                               if (RequiresDataBinding && IsBoundUsingDataSourceID)
-                                       DataBind ();
-                       }
-                       
-                       IDataSource GetDataSource ()
-                       {
-                               if (IsBoundUsingDataSourceID) {
-                                       Control ctrl = NamingContainer.FindControl (DataSourceID);
-                                       if (ctrl == null)
-                                               throw new HttpException (string.Format ("A control with ID '{0}' could not be found.", DataSourceID));
-                                       if (!(ctrl is IDataSource))
-                                               throw new HttpException (string.Format ("The control with ID '{0}' is not a control of type IDataSource.", DataSourceID));
-                                       return (IDataSource) ctrl;
-                               }
-                               return DataSource as IDataSource;
-                       }
-                       
-                       protected IEnumerable GetData ()
-                       {
-                               if (DataSource != null && IsBoundUsingDataSourceID)
-                                       throw new HttpException ("Control bound using both DataSourceID and DataSource properties.");
-                               
-                               IDataSource ds = GetDataSource ();
-                               if (ds != null)
-                                       return ds.GetView (DataMember).ExecuteSelect (SelectArguments);
-                               
-                               IEnumerable ie = DataSourceHelper.GetResolvedDataSource (DataSource, DataMember);
-                               if (ie != null) return ie;
-                               
-                               throw new HttpException (string.Format ("Unexpected data source type: {0}", DataSource.GetType()));
-                       }
-                       
-                       protected virtual void OnDataSourceViewChanged (object sender, EventArgs e)
-                       {
-                               RequiresDataBinding = true;
-                       }
+                       if (DataSourceID.Length == 0)
+                               return null;
+
+                       if (boundDataSource == null)
+                               ConnectToDataSource ();
+
+                       DataSourceView dsv = boundDataSource.GetView (String.Empty);
+                       dsv.Select (SelectArguments, new DataSourceViewSelectCallback (SelectCallback));
+                       return data;
+               }
+#endif
+
+               protected override void OnDataBinding (EventArgs e)
+               {
+                       base.OnDataBinding (e);
+               }
+#if NET_2_0
+               protected virtual void OnDataPropertyChanged ()
+               {
+               }
+
+               protected virtual void OnDataSourceViewChanged (object sender, EventArgs e)
+               {
+                       RequiresDataBinding = true;
+               }
 
-                       protected virtual void OnDataPropertyChanged ()
-                       {
+               protected internal override void OnInit (EventArgs e)
+               {
+                       base.OnInit (e);
+               }
+
+               protected internal override void OnLoad (EventArgs e)
+               {
+                       if ((Page != null) && !Page.IsPostBack)
                                RequiresDataBinding = true;
-                               SubscribeSourceChangeEvent ();
-                       }
 
-                       [DefaultValueAttribute ("")]
-                       [IDReferencePropertyAttribute (typeof(System.Web.UI.DataSourceControl))]
-                       [ThemeableAttribute (false)]
-                       public virtual string DataSourceID {
-                               get {
-                                       object o = ViewState ["DataSourceID"];
-                                       if (o != null)
-                                               return (string)o;
-                                       
-                                       return String.Empty;
-                               }
-                               set {
-                                       ViewState ["DataSourceID"] = value;
-                                       if (inited) OnDataPropertyChanged ();
-                               }
-                       }
-                       
-                       protected bool Initialized {
-                               get { return inited; }
-                       }
-                       
-                       protected bool RequiresDataBinding {
-                               get { return requiresDataBinding; }
-                               set { requiresDataBinding = value; }
-                       }
-                       
-                       protected virtual DataSourceSelectArguments CreateDataSourceSelectArguments ()
-                       {
-                               return DataSourceSelectArguments.Empty;
-                       }
-                       
-                       protected DataSourceSelectArguments SelectArguments {
-                               get {
-                                       if (selectArguments == null)
-                                               selectArguments = CreateDataSourceSelectArguments ();
-                                       return selectArguments;
-                               }
-                       }
-                       
-                       internal IEnumerable GetResolvedDataSource ()
-                       {
-                               return GetData ();
+                       if (IsBoundUsingDataSourceID)
+                               ConnectToDataSource ();
+
+                       initialized = true;
+                       base.OnLoad (e);
+               }
+
+               protected internal override void OnPreRender (EventArgs e)
+               {
+                       EnsureDataBound ();
+                       base.OnPreRender (e);
+               }
+#endif
+               protected virtual void OnSelectedIndexChanged (EventArgs e)
+               {
+                       EventHandler selectedIndexChanged = (EventHandler) Events [selectedIndexChangedEvent];
+                       if (selectedIndexChanged != null)
+                               selectedIndexChanged (this, e);
+               }
+
+               protected abstract void PrepareControlHierarchy ();
+
+#if NET_2_0
+               protected internal
+#else          
+               protected
+#endif         
+               override void Render (HtmlTextWriter writer)
+               {
+                       PrepareControlHierarchy ();
+                       // don't call base class or RenderBegin|EndTag
+                       // or we'll get an extra <span></span>
+                       RenderContents (writer);
+               }
+
+
+               [WebSysDescription("")]
+               [WebCategory("Action")]
+               public event EventHandler SelectedIndexChanged {
+                       add { Events.AddHandler (selectedIndexChangedEvent, value); }
+                       remove { Events.RemoveHandler (selectedIndexChangedEvent, value); }
+               }
+
+
+               static public bool IsBindableType (Type type)
+               {
+                       // I can't believe how many NRE are possible in System.Web
+                       if (type == null) // Type.GetTypeCode no longer throws when a null is passed.
+                               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;
                        }
-                       
-               #else
-                       internal IEnumerable GetResolvedDataSource ()
-                       {
-                               if (DataSource != null)
-                                       return DataSourceHelper.GetResolvedDataSource (DataSource, DataMember);
-                               else
-                                       return null; 
+               }
+
+#if NET_2_0
+               void ConnectToDataSource ()
+               {
+                       if (NamingContainer != null)
+                               boundDataSource = (NamingContainer.FindControl (DataSourceID) as IDataSource);
+
+                       if (boundDataSource == null) {
+                               if (Parent != null)
+                                       boundDataSource = (Parent.FindControl (DataSourceID) as IDataSource);
+
+                               if (boundDataSource == null)
+                                       throw new HttpException (Locale.GetText ("Coulnd't find a DataSource named '{0}'.", DataSourceID));
                        }
-               #endif
+                       DataSourceView dsv = boundDataSource.GetView (String.Empty);
+                       dsv.DataSourceViewChanged += new EventHandler (OnDataSourceViewChanged);
+               }
+#endif
        }
 }