svn path=/branches/mono-1-1-9/mcs/; revision=51216
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / DataBoundControl.cs
1 //
2 // System.Web.UI.WebControls.DataBoundControl
3 //
4 // Authors:
5 //      Ben Maurer (bmaurer@users.sourceforge.net)
6 //      Sanjay Gupta (gsanjay@novell.com)
7 //
8 // (C) 2003 Ben Maurer
9 // (C) 2004 Novell, Inc. (http://www.novell.com)
10 //
11
12 //
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
20 // 
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
23 // 
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 //
32
33 #if NET_2_0
34 using System.Collections;
35 using System.Collections.Specialized;
36 using System.Text;
37 using System.Web.Util;
38 using System.ComponentModel;
39
40 namespace System.Web.UI.WebControls {
41
42         [DesignerAttribute ("System.Web.UI.Design.WebControls.DataBoundControlDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
43         public abstract class DataBoundControl : BaseDataBoundControl
44         {
45                 DataSourceSelectArguments selectArguments;
46                 DataSourceView currentView;
47
48                 protected DataBoundControl ()
49                 {
50                 }
51
52                 /* Used for controls that used to inherit from
53                  * WebControl, so the tag can propagate upwards
54                  */
55                 internal DataBoundControl (HtmlTextWriterTag tag) : base (tag)
56                 {
57                 }
58                 
59                 
60                 protected virtual IDataSource GetDataSource ()
61                 {
62                         if (IsBoundUsingDataSourceID) {
63                                 Control ctrl = NamingContainer.FindControl (DataSourceID);
64                                 if (ctrl == null)
65                                         throw new HttpException (string.Format ("A control with ID '{0}' could not be found.", DataSourceID));
66                                 if (!(ctrl is IDataSource))
67                                         throw new HttpException (string.Format ("The control with ID '{0}' is not a control of type IDataSource.", DataSourceID));
68                                 return (IDataSource) ctrl;
69                         }
70                         
71                         if (DataSource == null) return null;
72                         
73                         IDataSource ds = DataSource as IDataSource;
74                         if (ds != null) return ds;
75                         
76                         IEnumerable ie = DataSourceHelper.GetResolvedDataSource (DataSource, DataMember);
77                         if (ie != null) return new CollectionDataSource (ie);
78                         
79                         throw new HttpException (string.Format ("Unexpected data source type: {0}", DataSource.GetType()));
80                 }
81                 
82                 protected virtual DataSourceView GetData ()
83                 {
84                         if (currentView == null)
85                                 UpdateViewData ();
86                         return currentView;
87                 }
88                 
89                 DataSourceView InternalGetData ()
90                 {
91                         if (DataSource != null && IsBoundUsingDataSourceID)
92                                 throw new HttpException ("Control bound using both DataSourceID and DataSource properties.");
93                         
94                         IDataSource ds = GetDataSource ();
95                         if (ds != null)
96                                 return ds.GetView (DataMember);
97                         else
98                                 return null; 
99                 }
100                 
101                 protected override void OnDataPropertyChanged ()
102                 {
103                         base.OnDataPropertyChanged ();
104                         UpdateViewData ();
105                 }
106                 
107                 protected virtual void OnDataSourceViewChanged (object sender, EventArgs e)
108                 {
109                         RequiresDataBinding = true;
110                 }
111                 
112                 protected override void OnPagePreLoad (object sender, EventArgs e)
113                 {
114                         base.OnPagePreLoad (sender, e);
115                         UpdateViewData ();
116                 }
117                 
118                 void UpdateViewData ()
119                 {
120                         DataSourceView view = InternalGetData ();
121                         if (view == currentView) return;
122
123                         if (currentView != null)
124                                 currentView.DataSourceViewChanged -= new EventHandler (OnDataSourceViewChanged);
125
126                         currentView = view;
127
128                         if (view != null)
129                                 view.DataSourceViewChanged += new EventHandler (OnDataSourceViewChanged);
130                 }
131                 
132                 protected internal override void OnLoad (EventArgs e)
133                 {
134                         if (IsBoundUsingDataSourceID && (!Page.IsPostBack || !EnableViewState))
135                                 RequiresDataBinding = true;
136
137                         base.OnLoad(e);
138                 }
139                 
140                 protected internal virtual void PerformDataBinding (IEnumerable data)
141                 {
142                 }
143
144                 protected override void ValidateDataSource (object dataSource)
145                 {
146                         if (dataSource is IListSource || dataSource is IEnumerable || dataSource is IDataSource)
147                                 return;
148                         throw new ArgumentException ("Invalid data source source type. The data source must be of type IListSource, IEnumerable or IDataSource.");
149                 }
150
151                 [ThemeableAttribute (false)]
152                 [DefaultValueAttribute ("")]
153                 [WebCategoryAttribute ("Data")]
154                 public virtual string DataMember
155                 {
156                         get {
157                                 object o = ViewState["DataMember"];
158                                 if(o!=null)
159                                         return (string)o;
160                                 return String.Empty;
161                         }
162                         set {
163                                 ViewState["DataMember"] = value;
164                         }
165                 }
166
167                 [IDReferencePropertyAttribute (typeof(DataSourceControl))]
168                 public override string DataSourceID {
169                         get {
170                                 object o = ViewState ["DataSourceID"];
171                                 if (o != null)
172                                         return (string)o;
173                                 
174                                 return String.Empty;
175                         }
176                         set {
177                                 ViewState ["DataSourceID"] = value;
178                                 base.DataSourceID = value;
179                         }
180                 }
181                 
182                 protected override void PerformSelect ()
183                 {
184                         OnDataBinding (EventArgs.Empty);
185                         DataSourceView view = GetData ();
186                         if (view != null)
187                                 view.Select (SelectArguments, new DataSourceViewSelectCallback (OnSelect));
188                 }
189                 
190                 void OnSelect (IEnumerable data)
191                 {
192                         PerformDataBinding (data);
193                         OnDataBound (EventArgs.Empty);
194                 }
195                 
196                 protected virtual DataSourceSelectArguments CreateDataSourceSelectArguments ()
197                 {
198                         return DataSourceSelectArguments.Empty;
199                 }
200                 
201                 protected DataSourceSelectArguments SelectArguments {
202                         get {
203                                 if (selectArguments == null)
204                                         selectArguments = CreateDataSourceSelectArguments ();
205                                 return selectArguments;
206                         }
207                 }
208
209                 [MonoTODO]
210                 protected void MarkAsDataBound ()
211                 {
212                         throw new NotImplementedException ();
213                 }
214         }
215 }
216 #endif
217