ChangeLog: Updated.
[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 //   Sanjay Gupta (gsanjay@novell.com)
8 //
9 // (C) Gaurav Vaish (2001)
10 // (C) 2003 Andreas Nahr
11 // (C) 2004 Novell, Inc. (http://www.novell.com)
12 //
13
14 //
15 // Permission is hereby granted, free of charge, to any person obtaining
16 // a copy of this software and associated documentation files (the
17 // "Software"), to deal in the Software without restriction, including
18 // without limitation the rights to use, copy, modify, merge, publish,
19 // distribute, sublicense, and/or sell copies of the Software, and to
20 // permit persons to whom the Software is furnished to do so, subject to
21 // the following conditions:
22 // 
23 // The above copyright notice and this permission notice shall be
24 // included in all copies or substantial portions of the Software.
25 // 
26 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
30 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
31 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
32 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 //
34
35 using System;
36 using System.ComponentModel;
37 using System.ComponentModel.Design;
38 using System.Collections;
39 using System.Web;
40 using System.Web.UI;
41 using System.Web.Util;
42
43 namespace System.Web.UI.WebControls
44 {
45         [DefaultEvent("SelectedIndexChanged")]
46         [DefaultProperty("DataSource")]
47         [Designer("System.Web.UI.Design.WebControls.BaseDataListDesigner, " + Consts.AssemblySystem_Design, typeof (IDesigner))]
48         public abstract class BaseDataList: WebControl
49         {
50                 private  static readonly object SelectedIndexChangedEvent = new object();
51                 internal static string          ItemCountViewStateKey     = "_!ItemCount";
52
53                 private DataKeyCollection dataKeys;
54                 private object            dataSource;
55
56                 public BaseDataList() : base()
57                 {
58                 }
59
60                 public static bool IsBindableType(Type type)
61                 {
62                         if(type.IsPrimitive || type == typeof(string) || type == typeof(DateTime) || type == typeof(Decimal))
63                                 return true;
64                         return false;
65                 }
66
67                 public override ControlCollection Controls
68                 {
69                         get
70                         {
71                                 EnsureChildControls();
72                                 return base.Controls;
73                         }
74                 }
75
76                 public override void DataBind()
77                 {
78                         #if NET_2_0
79                         RequiresDataBinding = false;
80                         #endif
81                         OnDataBinding(EventArgs.Empty);
82                 }
83
84                 [WebCategory("Action")]
85                 [WebSysDescription("BaseDataList_OnSelectedIndexChanged")]
86                 public event EventHandler SelectedIndexChanged
87                 {
88                         add
89                         {
90                                 Events.AddHandler(SelectedIndexChangedEvent, value);
91                         }
92                         remove
93                         {
94                                 Events.RemoveHandler(SelectedIndexChangedEvent, value);
95                         }
96                 }
97
98                 [Bindable(true)]
99                 [DefaultValue(-1)]
100                 [WebCategory("Layout")]
101                 [WebSysDescription("BaseDataList_CellPadding")]
102                 public virtual int CellPadding
103                 {
104                         get
105                         {
106                                 if(!ControlStyleCreated)
107                                         return -1;
108                                 return ((TableStyle)ControlStyle).CellPadding;
109                         }
110                         set
111                         {
112                                 ((TableStyle)ControlStyle).CellPadding = value;
113                         }
114                 }
115
116                 [Bindable(true)]
117                 [DefaultValue(-1)]
118                 [WebCategory("Layout")]
119                 [WebSysDescription("BaseDataList_CellSpacing")]
120                 public virtual int CellSpacing
121                 {
122                         get
123                         {
124                                 if(!ControlStyleCreated)
125                                         return -1;
126                                 return ((TableStyle)ControlStyle).CellSpacing;
127                         }
128                         set
129                         {
130                                 ((TableStyle)ControlStyle).CellSpacing = value;
131                         }
132                 }
133
134                 [DefaultValue("")]
135                 [WebCategory("Data")]
136                 [WebSysDescription("BaseDataList_DataKeyField")]
137                 public virtual string DataKeyField
138                 {
139                         get
140                         {
141                                 object o = ViewState["DataKeyField"];
142                                 if(o!=null)
143                                         return (string)o;
144                                 return String.Empty;
145                         }
146                         set
147                         {
148                                 ViewState["DataKeyField"] = value;
149                         }
150                 }
151
152                 [Browsable(true)]
153                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
154                 [WebSysDescription("BaseDataList_DataKeys")]
155                 public DataKeyCollection DataKeys
156                 {
157                         get
158                         {
159                                 if( dataKeys==null )
160                                         dataKeys = new DataKeyCollection(DataKeysArray);
161                                 return dataKeys;
162
163                         }
164                 }
165
166                 [DefaultValue("")]
167                 [WebCategory("Data")]
168                 [WebSysDescription("BaseDataList_DataMember")]
169                 public string DataMember
170                 {
171                         get
172                         {
173                                 object o = ViewState["DataMember"];
174                                 if(o!=null)
175                                         return (string)o;
176                                 return String.Empty;
177                         }
178                         set
179                         {
180                                 ViewState["DataMember"] = value;
181                         }
182                 }
183
184                 [Bindable(true)]
185                 [DefaultValue(null)]
186                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
187                 [WebCategory("Data")]
188                 [WebSysDescription("BaseDataList_DataSource")]
189                 public virtual object DataSource {
190                         get {
191                                 return dataSource;
192                         }
193                         set {
194                                 if (value == null || value is IListSource || value is IEnumerable) {
195                                         dataSource = value;
196                                 } else {
197                                         throw new ArgumentException (HttpRuntime.FormatResourceString (
198                                                                 "Invalid_DataSource_Type", ID));
199                                 }
200                         }
201                 }
202
203                 [Bindable(true)]
204                 [DefaultValue(GridLines.Both)]
205                 [WebCategory("Appearance")]
206                 [WebSysDescription("BaseDataList_GridLines")]
207                 public virtual GridLines GridLines
208                 {
209                         get
210                         {
211                                 if(ControlStyleCreated)
212                                         return ((TableStyle)ControlStyle).GridLines;
213                                 return GridLines.Both;
214                         }
215                         set
216                         {
217                                 ((TableStyle)ControlStyle).GridLines = value;
218                         }
219                 }
220
221                 // LAMESPEC HorizontalAlign has a Category attribute, this should obviously be a WebCategory attribute
222                 // but is defined incorrectly in the MS framework
223
224                 [Bindable(true)]
225                 [DefaultValue(HorizontalAlign.NotSet)]
226                 [Category("Layout")]
227                 [WebSysDescription("BaseDataList_HorizontalAlign")]
228                 public virtual HorizontalAlign HorizontalAlign
229                 {
230                         get
231                         {
232                                 if(ControlStyleCreated)
233                                         return ((TableStyle)ControlStyle).HorizontalAlign;
234                                 return HorizontalAlign.NotSet;
235                         }
236                         set
237                         {
238                                 ((TableStyle)ControlStyle).HorizontalAlign = value;
239                         }
240                 }
241
242                 protected ArrayList DataKeysArray
243                 {
244                         get
245                         {
246                                 object o = ViewState["DataKeys"];
247                                 if(o == null)
248                                 {
249                                         o = new ArrayList();
250                                         ViewState["DataKeys"] = o;
251                                 }
252                                 return (ArrayList)o;
253                         }
254                 }
255
256                 protected override void AddParsedSubObject(object o)
257                 {
258                         // Preventing literal controls from being added as children.
259                 }
260
261                 protected override void CreateChildControls()
262                 {
263                         Controls.Clear();
264                         if(ViewState[ItemCountViewStateKey]!=null)
265                         {
266                                 CreateControlHierarchy(false);
267                                 ClearChildViewState();
268                         }
269                 }
270
271                 protected override void OnDataBinding(EventArgs e)
272                 {
273                         base.OnDataBinding(e);
274                         Controls.Clear();
275                         ClearChildViewState();
276                         CreateControlHierarchy(true);
277                         ChildControlsCreated = true;
278                         TrackViewState();
279                 }
280
281                 protected virtual void OnSelectedIndexChanged(EventArgs e)
282                 {
283                         if(Events != null)
284                         {
285                                 EventHandler eh = (EventHandler)(Events[SelectedIndexChangedEvent]);
286                                 if(eh!=null)
287                                         eh(this, e);
288                         }
289                 }
290
291                 protected override void Render(HtmlTextWriter writer)
292                 {
293                         PrepareControlHierarchy();
294                         RenderContents(writer);
295                 }
296
297                 protected abstract void PrepareControlHierarchy();
298                 protected abstract void CreateControlHierarchy(bool useDataSource);
299                 
300                 #if NET_2_0
301
302                         
303                         // should be `internal protected' (why, oh WHY did they do that !?!)
304                         protected override void OnInit (EventArgs e)
305                         {
306                                 base.OnInit(e);
307                                 inited = true;
308                                 if (!Page.IsPostBack)
309                                         RequiresDataBinding = true;
310                         }
311                         
312                         // should be `internal protected' (why, oh WHY did they do that !?!)
313                         protected override void OnLoad (EventArgs e)
314                         {
315                                 IDataSource ds = GetDataSourceObject () as IDataSource;
316                                 if (ds != null && DataSourceID != "")
317                                         ds.DataSourceChanged += new EventHandler (OnDataSourceChanged);
318                                 
319                                 base.OnLoad(e);
320                         }
321                         
322                         // should be `internal protected' (why, oh WHY did they do that !?!)
323                         protected override void OnPreRender (EventArgs e)
324                         {
325                                 EnsureDataBound ();
326                                 base.OnPreRender (e);
327                         }
328                                 
329                         protected void EnsureDataBound ()
330                         {
331                                 if (RequiresDataBinding && DataSourceID != "")
332                                         DataBind ();
333                         }
334                         
335                         protected virtual object GetDataSourceObject ()
336                         {
337                                 if (DataSourceID != "")
338                                         return (IDataSource) NamingContainer.FindControl (DataSourceID);
339                                 
340                                 return DataSource;
341                         }
342                         
343                         protected virtual IEnumerable GetResolvedDataSource ()
344                         {
345                                 if (DataSource != null && DataSourceID != "")
346                                         throw new HttpException ();
347                                 
348                                 IDataSource ds = this.GetDataSourceObject () as IDataSource;                            
349                                 if (ds != null && DataSourceID != "") {                                 
350                                         return ds.GetView (DataMember).ExecuteSelect (selectArguments); 
351                                 }
352                                 else if (DataSource != null)
353                                         return DataSourceHelper.GetResolvedDataSource (DataSource, DataMember);
354                                 else
355                                         return null; 
356                         }
357                         
358                         protected void OnDataSourceChanged (object sender, EventArgs e)
359                         {
360                                 RequiresDataBinding = true;
361                         }
362                         
363                         public virtual string DataSourceID {
364                                 get {
365                                         object o = ViewState ["DataSourceID"];
366                                         if (o != null)
367                                                 return (string)o;
368                                         
369                                         return String.Empty;
370                                 }
371                                 set {
372                                         if (inited)
373                                                 RequiresDataBinding = true;
374                                         
375                                         ViewState ["DataSourceID"] = value;
376                                 }
377                         }
378                         
379                         bool requiresDataBinding;
380                         protected bool RequiresDataBinding {
381                                 get { return requiresDataBinding; }
382                                 set { requiresDataBinding = value; }
383                         }
384                         
385                         protected bool inited;
386                         
387                         DataSourceSelectArguments selectArguments = null;
388                         
389                         protected DataSourceSelectArguments SelectArguments {
390                                 get { return selectArguments; }
391                         }                               
392                 #else
393                         internal IEnumerable GetResolvedDataSource ()
394                         {
395                                 if (DataSource != null)
396                                         return DataSourceHelper.GetResolvedDataSource (DataSource, DataMember);
397                                 else
398                                         return null; 
399                         }
400                 #endif
401         }
402 }