Add licensing info
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / BaseDataList.cs
1 //
2 // System.Web.UI.WebControls.BaseDataList.cs
3 //
4 // Authors:
5 //   Gaurav Vaish (gvaish@iitk.ac.in)
6 //   Andreas Nahr (ClassDevelopment@A-SoftTech.com)
7 //
8 // (C) Gaurav Vaish (2001)
9 // (C) 2003 Andreas Nahr
10 //\r
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 \r
33 using System;\r
34 using System.ComponentModel;
35 using System.ComponentModel.Design;\r
36 using System.Collections;\r
37 using System.Web;\r
38 using System.Web.UI;
39 using System.Web.Util;\r
40 \r
41 namespace System.Web.UI.WebControls\r
42 {\r
43         [DefaultEvent("SelectedIndexChanged")]\r
44         [DefaultProperty("DataSource")]\r
45         [Designer("System.Web.UI.Design.WebControls.BaseDataListDesigner, " + Consts.AssemblySystem_Design, typeof (IDesigner))]\r
46         public abstract class BaseDataList: WebControl\r
47         {\r
48                 private  static readonly object SelectedIndexChangedEvent = new object();\r
49                 internal static string          ItemCountViewStateKey     = "_!ItemCount";\r
50 \r
51                 private DataKeyCollection dataKeys;\r
52                 private object            dataSource;\r
53 \r
54                 public BaseDataList() : base()\r
55                 {\r
56                 }\r
57 \r
58                 public static bool IsBindableType(Type type)\r
59                 {\r
60                         if(type.IsPrimitive || type == typeof(string) || type == typeof(DateTime) || type == typeof(Decimal))\r
61                                 return true;\r
62                         return false;\r
63                 }\r
64 \r
65                 public override ControlCollection Controls\r
66                 {\r
67                         get\r
68                         {\r
69                                 EnsureChildControls();\r
70                                 return base.Controls;\r
71                         }\r
72                 }\r
73 \r
74                 public override void DataBind()\r
75                 {
76                         #if NET_2_0
77                         RequiresDataBinding = false;
78                         #endif\r
79                         OnDataBinding(EventArgs.Empty);\r
80                 }\r
81 \r
82                 [WebCategory("Action")]\r
83                 [WebSysDescription("BaseDataList_OnSelectedIndexChanged")]\r
84                 public event EventHandler SelectedIndexChanged\r
85                 {\r
86                         add\r
87                         {\r
88                                 Events.AddHandler(SelectedIndexChangedEvent, value);\r
89                         }\r
90                         remove\r
91                         {\r
92                                 Events.RemoveHandler(SelectedIndexChangedEvent, value);\r
93                         }\r
94                 }\r
95 \r
96                 [Bindable(true)]\r
97                 [DefaultValue(-1)]\r
98                 [WebCategory("Layout")]\r
99                 [WebSysDescription("BaseDataList_CellPadding")]\r
100                 public virtual int CellPadding\r
101                 {\r
102                         get\r
103                         {\r
104                                 if(!ControlStyleCreated)\r
105                                         return -1;\r
106                                 return ((TableStyle)ControlStyle).CellPadding;\r
107                         }\r
108                         set\r
109                         {\r
110                                 ((TableStyle)ControlStyle).CellPadding = value;\r
111                         }\r
112                 }\r
113 \r
114                 [Bindable(true)]\r
115                 [DefaultValue(-1)]\r
116                 [WebCategory("Layout")]\r
117                 [WebSysDescription("BaseDataList_CellSpacing")]\r
118                 public virtual int CellSpacing\r
119                 {\r
120                         get\r
121                         {\r
122                                 if(!ControlStyleCreated)\r
123                                         return -1;\r
124                                 return ((TableStyle)ControlStyle).CellSpacing;\r
125                         }\r
126                         set\r
127                         {\r
128                                 ((TableStyle)ControlStyle).CellSpacing = value;\r
129                         }\r
130                 }\r
131 \r
132                 [DefaultValue("")]\r
133                 [WebCategory("Data")]\r
134                 [WebSysDescription("BaseDataList_DataKeyField")]\r
135                 public virtual string DataKeyField\r
136                 {\r
137                         get\r
138                         {\r
139                                 object o = ViewState["DataKeyField"];\r
140                                 if(o!=null)\r
141                                         return (string)o;\r
142                                 return String.Empty;\r
143                         }\r
144                         set\r
145                         {\r
146                                 ViewState["DataKeyField"] = value;\r
147                         }\r
148                 }\r
149 \r
150                 [Browsable(true)]\r
151                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]\r
152                 [WebSysDescription("BaseDataList_DataKeys")]\r
153                 public DataKeyCollection DataKeys\r
154                 {\r
155                         get\r
156                         {\r
157                                 if( dataKeys==null )\r
158                                         dataKeys = new DataKeyCollection(DataKeysArray);\r
159                                 return dataKeys;\r
160 \r
161                         }\r
162                 }\r
163 \r
164                 [DefaultValue("")]\r
165                 [WebCategory("Data")]\r
166                 [WebSysDescription("BaseDataList_DataMember")]\r
167                 public string DataMember\r
168                 {\r
169                         get\r
170                         {\r
171                                 object o = ViewState["DataMember"];\r
172                                 if(o!=null)\r
173                                         return (string)o;\r
174                                 return String.Empty;\r
175                         }\r
176                         set\r
177                         {\r
178                                 ViewState["DataMember"] = value;\r
179                         }\r
180                 }\r
181 \r
182                 [Bindable(true)]\r
183                 [DefaultValue(null)]\r
184                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]\r
185                 [WebCategory("Data")]\r
186                 [WebSysDescription("BaseDataList_DataSource")]\r
187                 public virtual object DataSource {
188                         get {
189                                 return dataSource;
190                         }
191                         set {
192                                 if (value == null || value is IListSource || value is IEnumerable) {
193                                         dataSource = value;
194                                 } else {
195                                         throw new ArgumentException (HttpRuntime.FormatResourceString (
196                                                                 "Invalid_DataSource_Type", ID));
197                                 }
198                         }
199                 }
200
201                 [Bindable(true)]\r
202                 [DefaultValue(GridLines.Both)]\r
203                 [WebCategory("Appearance")]\r
204                 [WebSysDescription("BaseDataList_GridLines")]\r
205                 public virtual GridLines GridLines\r
206                 {\r
207                         get\r
208                         {\r
209                                 if(ControlStyleCreated)\r
210                                         return ((TableStyle)ControlStyle).GridLines;\r
211                                 return GridLines.Both;\r
212                         }\r
213                         set\r
214                         {\r
215                                 ((TableStyle)ControlStyle).GridLines = value;\r
216                         }\r
217                 }
218
219                 // LAMESPEC HorizontalAlign has a Category attribute, this should obviously be a WebCategory attribute
220                 // but is defined incorrectly in the MS framework\r
221 \r
222                 [Bindable(true)]\r
223                 [DefaultValue(HorizontalAlign.NotSet)]\r
224                 [Category("Layout")]\r
225                 [WebSysDescription("BaseDataList_HorizontalAlign")]\r
226                 public virtual HorizontalAlign HorizontalAlign\r
227                 {\r
228                         get\r
229                         {\r
230                                 if(ControlStyleCreated)\r
231                                         return ((TableStyle)ControlStyle).HorizontalAlign;\r
232                                 return HorizontalAlign.NotSet;\r
233                         }\r
234                         set\r
235                         {\r
236                                 ((TableStyle)ControlStyle).HorizontalAlign = value;\r
237                         }\r
238                 }\r
239 \r
240                 protected ArrayList DataKeysArray\r
241                 {\r
242                         get\r
243                         {\r
244                                 object o = ViewState["DataKeys"];\r
245                                 if(o == null)\r
246                                 {\r
247                                         o = new ArrayList();\r
248                                         ViewState["DataKeys"] = o;\r
249                                 }\r
250                                 return (ArrayList)o;\r
251                         }\r
252                 }\r
253 \r
254                 protected override void AddParsedSubObject(object o)\r
255                 {\r
256                         // Preventing literal controls from being added as children.\r
257                 }\r
258 \r
259                 protected override void CreateChildControls()\r
260                 {\r
261                         Controls.Clear();\r
262                         if(ViewState[ItemCountViewStateKey]!=null)\r
263                         {\r
264                                 CreateControlHierarchy(false);\r
265                                 ClearChildViewState();\r
266                         }\r
267                 }\r
268 \r
269                 protected override void OnDataBinding(EventArgs e)\r
270                 {\r
271                         base.OnDataBinding(e);\r
272                         Controls.Clear();\r
273                         ClearChildViewState();\r
274                         CreateControlHierarchy(true);\r
275                         ChildControlsCreated = true;\r
276                         TrackViewState();\r
277                 }\r
278 \r
279                 protected virtual void OnSelectedIndexChanged(EventArgs e)\r
280                 {\r
281                         if(Events != null)\r
282                         {\r
283                                 EventHandler eh = (EventHandler)(Events[SelectedIndexChangedEvent]);\r
284                                 if(eh!=null)\r
285                                         eh(this, e);\r
286                         }\r
287                 }\r
288 \r
289                 protected override void Render(HtmlTextWriter writer)\r
290                 {\r
291                         PrepareControlHierarchy();\r
292                         RenderContents(writer);\r
293                 }\r
294 \r
295                 protected abstract void PrepareControlHierarchy();\r
296                 protected abstract void CreateControlHierarchy(bool useDataSource);
297                 
298                 #if NET_2_0
299
300                         
301                         // should be `internal protected' (why, oh WHY did they do that !?!)
302                         protected override void OnInit (EventArgs e)
303                         {
304                                 base.OnInit(e);
305                                 inited = true;
306                                 if (!Page.IsPostBack)
307                                         RequiresDataBinding = true;
308                         }
309                         
310                         // should be `internal protected' (why, oh WHY did they do that !?!)
311                         protected override void OnLoad (EventArgs e)
312                         {
313                                 IDataSource ds = GetDataSourceObject () as IDataSource;
314                                 if (ds != null && DataSourceID != "")
315                                         ds.DataSourceChanged += new EventHandler (OnDataSourceChanged);
316                                 
317                                 base.OnLoad(e);
318                         }
319                         
320                         // should be `internal protected' (why, oh WHY did they do that !?!)
321                         protected override void OnPreRender (EventArgs e)
322                         {
323                                 EnsureDataBound ();
324                                 base.OnPreRender (e);
325                         }
326                                 
327                         protected void EnsureDataBound ()
328                         {
329                                 if (RequiresDataBinding && DataSourceID != "")
330                                         DataBind ();
331                         }
332                         
333                         protected virtual object GetDataSourceObject ()
334                         {
335                                 if (DataSourceID != "")
336                                         return (IDataSource) NamingContainer.FindControl (DataSourceID);
337                                 
338                                 return DataSource;
339                         }
340                         
341                         protected virtual IEnumerable GetResolvedDataSource ()
342                         {
343                                 if (DataSource != null && DataSourceID != "")
344                                         throw new HttpException ();
345                                 
346                                 IDataSource ds = this.GetDataSourceObject () as IDataSource;
347                                 if (ds != null && DataSourceID != "")
348                                         return ds.GetView (DataMember).Select ();
349                                 else if (DataSource != null)
350                                         return DataSourceHelper.GetResolvedDataSource (DataSource, DataMember);
351                                 else
352                                         return null; 
353                         }
354                         
355                         protected void OnDataSourceChanged (object sender, EventArgs e)
356                         {
357                                 RequiresDataBinding = true;
358                         }
359                         
360                         public virtual string DataSourceID {
361                                 get {
362                                         object o = ViewState ["DataSourceID"];
363                                         if (o != null)
364                                                 return (string)o;
365                                         
366                                         return String.Empty;
367                                 }
368                                 set {
369                                         if (inited)
370                                                 RequiresDataBinding = true;
371                                         
372                                         ViewState ["DataSourceID"] = value;
373                                 }
374                         }
375                         
376                         bool requiresDataBinding;
377                         protected bool RequiresDataBinding {
378                                 get { return requiresDataBinding; }
379                                 set { requiresDataBinding = value; }
380                         }
381                         
382                         protected bool inited;
383                                 
384                 #else
385                         internal IEnumerable GetResolvedDataSource ()
386                         {
387                                 if (DataSource != null)
388                                         return DataSourceHelper.GetResolvedDataSource (DataSource, DataMember);
389                                 else
390                                         return null; 
391                         }
392                 #endif\r
393         }\r
394 }\r