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