2 // System.Web.UI.WebControls.Repeater.cs
5 // Gaurav Vaish (gvaish@iitk.ac.in)
6 // Gonzalo Paniagua Javier (gonzalo@ximian.com)
7 // Andreas Nahr (ClassDevelopment@A-SoftTech.com)
9 // (c) 2002 Ximian, Inc. (http://www.ximian.com)
10 // (C) Gaurav Vaish (2002)
11 // (C) 2003 Andreas Nahr
15 using System.Collections;
\r
17 using System.Web.UI;
\r
18 using System.Web.Util;
\r
19 using System.ComponentModel;
20 using System.ComponentModel.Design;
\r
22 namespace System.Web.UI.WebControls
\r
24 [DefaultEvent("ItemCommand")]
\r
25 [DefaultProperty("DataSource")]
\r
26 [Designer ("System.Web.UI.Design.WebControls.RepeaterDesigner, " + Consts.AssemblySystem_Design, typeof (IDesigner))]
\r
27 [ParseChildren(true)]
\r
28 [PersistChildren(false)]
\r
29 public class Repeater : Control, INamingContainer
\r
31 private static readonly object ItemCommandEvent = new object();
\r
32 private static readonly object ItemCreatedEvent = new object();
\r
33 private static readonly object ItemDataBoundEvent = new object();
\r
35 private static readonly string ITEMCOUNT = "Repeater_Item_Count";
\r
37 private ITemplate alternatingItemTemplate;
\r
38 private ITemplate footerTemplate;
\r
39 private ITemplate headerTemplate;
\r
40 private ITemplate itemTemplate;
\r
41 private ITemplate separatorTemplate;
\r
42 private object dataSource;
\r
44 private RepeaterItemCollection items;
\r
45 private ArrayList itemsArrayList;
\r
47 public Repeater(): base()
\r
51 [WebCategory ("Action")]
52 [WebSysDescription ("Raised when a command is executed in the DataList.")]
\r
53 public event RepeaterCommandEventHandler ItemCommand
\r
57 Events.AddHandler(ItemCommandEvent, value);
\r
61 Events.RemoveHandler(ItemCommandEvent, value);
\r
65 [WebCategory ("Behavior")]
66 [WebSysDescription ("Raised when an item gets created.")]
\r
67 public event RepeaterItemEventHandler ItemCreated
\r
71 Events.AddHandler(ItemCreatedEvent, value);
\r
75 Events.RemoveHandler(ItemCreatedEvent, value);
\r
79 [WebCategory ("Behavior")]
80 [WebSysDescription ("Raised when an item gets data-bound.")]
\r
81 public event RepeaterItemEventHandler ItemDataBound
\r
85 Events.AddHandler(ItemDataBoundEvent, value);
\r
89 Events.RemoveHandler(ItemDataBoundEvent, value);
\r
93 [DefaultValue (null), Browsable (false), PersistenceMode (PersistenceMode.InnerProperty)]
94 [TemplateContainer (typeof (RepeaterItem))]
95 [WebSysDescription ("The template that is used to create an alternating item.")]
\r
96 public virtual ITemplate AlternatingItemTemplate
\r
100 return alternatingItemTemplate;
\r
104 alternatingItemTemplate = value;
\r
108 public override ControlCollection Controls
\r
112 EnsureChildControls();
\r
113 return base.Controls;
\r
117 [DefaultValue (""), WebCategory ("Data")]
118 [WebSysDescription ("The name of the table that is used for binding when a DataSource is specified.")]
\r
119 public virtual string DataMember
\r
123 object o = ViewState["DataMember"];
\r
128 return String.Empty;
\r
132 ViewState["DataMember"] = value;
\r
136 [DefaultValue (null), Bindable (true), WebCategory ("Data")]
137 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
138 [WebSysDescription ("The DataSource that is used for data-binding.")]
\r
139 public virtual object DataSource
\r
147 if ((value!=null) && !(value is IListSource) && !(value is IEnumerable))
148 throw new ArgumentException ("An invalid data source is being used for " +
149 ID + ". A valid data source must implement either " +
150 "IListSource or IEnumerable.");
152 dataSource = value;
\r
156 [DefaultValue (null), Browsable (false), PersistenceMode (PersistenceMode.InnerProperty)]
157 [TemplateContainer (typeof (RepeaterItem))]
158 [WebSysDescription ("The template that is used to create a footer.")]
\r
159 public virtual ITemplate FooterTemplate
\r
163 return footerTemplate;
\r
167 footerTemplate = value;
\r
171 [DefaultValue (null), Browsable (false), PersistenceMode (PersistenceMode.InnerProperty)]
172 [TemplateContainer (typeof (RepeaterItem))]
173 [WebSysDescription ("The template that is used to create a header.")]
\r
174 public virtual ITemplate HeaderTemplate
\r
178 return headerTemplate;
\r
182 headerTemplate = value;
\r
187 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
188 [WebSysDescription ("A collection containing all items.")]
\r
189 public virtual RepeaterItemCollection Items
\r
195 if(itemsArrayList == null)
\r
197 EnsureChildControls();
\r
199 items = new RepeaterItemCollection(itemsArrayList);
\r
205 [DefaultValue (null), Browsable (false), PersistenceMode (PersistenceMode.InnerProperty)]
206 [TemplateContainer (typeof (RepeaterItem))]
207 [WebSysDescription ("The template that is used to create an item.")]
\r
208 public virtual ITemplate ItemTemplate
\r
212 return itemTemplate;
\r
216 itemTemplate = value;
\r
220 [DefaultValue (null), Browsable (false), PersistenceMode (PersistenceMode.InnerProperty)]
221 [TemplateContainer (typeof (RepeaterItem))]
222 [WebSysDescription ("The template that is used to create a seperator.")]
\r
223 public virtual ITemplate SeparatorTemplate
\r
227 return separatorTemplate;
\r
231 separatorTemplate = value;
\r
235 public override void DataBind ()
238 RequiresDataBinding = false;
240 OnDataBinding (EventArgs.Empty);
243 protected override void CreateChildControls()
246 if (ViewState[ITEMCOUNT] != null) {
247 CreateControlHierarchy (false);
249 itemsArrayList = new ArrayList ();
250 ClearChildViewState ();
254 private RepeaterItem CreateItem (int itemIndex,
\r
255 ListItemType itemType,
\r
259 RepeaterItem repeaterItem = new RepeaterItem (itemIndex, itemType);
\r
260 RepeaterItemEventArgs repeaterEventArgs = new RepeaterItemEventArgs (repeaterItem);
\r
261 InstantiateItem (repeaterItem);
\r
263 repeaterItem.DataItem = dataItem;
\r
264 OnItemCreated (repeaterEventArgs);
\r
265 Controls.Add (repeaterItem);
\r
267 repeaterItem.DataBind ();
\r
268 OnItemDataBound (repeaterEventArgs);
\r
269 repeaterItem.DataItem = null;
\r
271 return repeaterItem;
\r
274 private void InstantiateItem (RepeaterItem item)
\r
276 ITemplate template;
\r
277 switch (item.ItemType) {
\r
278 case ListItemType.Header:
\r
279 template = this.headerTemplate;
\r
281 case ListItemType.Footer:
\r
282 template = this.footerTemplate;
\r
284 case ListItemType.Item:
\r
285 template = this.itemTemplate;
\r
287 case ListItemType.AlternatingItem:
\r
288 template = (alternatingItemTemplate != null ? this.alternatingItemTemplate : itemTemplate);
\r
290 case ListItemType.Separator:
\r
291 template = this.separatorTemplate;
\r
294 throw new HttpException ("Unknown ListItemType: " + item.ItemType);
\r
297 if (template != null)
\r
298 template.InstantiateIn (item);
\r
301 protected virtual void CreateControlHierarchy (bool useDataSource)
303 if (itemsArrayList != null) {
304 itemsArrayList.Clear ();
306 itemsArrayList = new ArrayList ();
309 IEnumerable ds = null;
311 ds = GetResolvedDataSource ();
313 int itemCount = (int) ViewState [ITEMCOUNT];
315 ds = new DataSourceInternal (itemCount);
320 if (headerTemplate != null)
321 CreateItem (-1, ListItemType.Header, useDataSource, null);
324 foreach (object item in ds){
325 if (separatorTemplate != null && index > 0)
326 CreateItem (index - 1, ListItemType.Separator,
327 useDataSource, null);
329 RepeaterItem repeaterItem;
332 lType = ListItemType.AlternatingItem;
334 lType = ListItemType.Item;
336 repeaterItem = CreateItem (index, lType, useDataSource, item);
337 itemsArrayList.Add (repeaterItem);
342 if (footerTemplate != null)
343 CreateItem (-1, ListItemType.Footer, useDataSource, null);
347 ViewState [ITEMCOUNT] = (ds == null) ? -1 : index;
350 protected override bool OnBubbleEvent(object sender, EventArgs e)
\r
352 bool retVal = false;
\r
353 if(e is RepeaterCommandEventArgs)
\r
355 OnItemCommand((RepeaterCommandEventArgs)e);
\r
361 protected override void OnDataBinding(EventArgs e)
\r
363 base.OnDataBinding(e);
\r
365 ClearChildViewState();
\r
366 CreateControlHierarchy(true);
\r
367 ChildControlsCreated = true;
\r
370 protected virtual void OnItemCommand(RepeaterCommandEventArgs e)
\r
374 RepeaterCommandEventHandler rceh = (RepeaterCommandEventHandler)
\r
375 Events [ItemCommandEvent];
\r
383 protected virtual void OnItemCreated(RepeaterItemEventArgs e)
\r
387 RepeaterItemEventHandler rceh = (RepeaterItemEventHandler)
\r
388 Events [ItemCreatedEvent];
\r
396 protected virtual void OnItemDataBound(RepeaterItemEventArgs e)
\r
400 RepeaterItemEventHandler rceh = (RepeaterItemEventHandler)
\r
401 Events [ItemDataBoundEvent];
\r
409 protected virtual RepeaterItem CreateItem (int itemIndex, ListItemType itemType)
\r
411 return new RepeaterItem (itemIndex, itemType);
\r
414 protected virtual void InitializeItem (RepeaterItem item)
\r
416 InstantiateItem (item);
\r
422 // should be `internal protected' (why, oh WHY did they do that !?!)
423 protected override void OnInit (EventArgs e)
427 if (!Page.IsPostBack)
428 RequiresDataBinding = true;
431 // should be `internal protected' (why, oh WHY did they do that !?!)
432 protected override void OnLoad (EventArgs e)
434 IDataSource ds = GetDataSourceObject () as IDataSource;
435 if (ds != null && DataSourceID != "")
436 ds.DataSourceChanged += new EventHandler (OnDataSourceChanged);
441 // should be `internal protected' (why, oh WHY did they do that !?!)
442 protected override void OnPreRender (EventArgs e)
445 base.OnPreRender (e);
448 protected void EnsureDataBound ()
450 if (RequiresDataBinding && DataSourceID != "")
454 protected virtual object GetDataSourceObject ()
456 if (DataSourceID != "")
457 return (IDataSource) NamingContainer.FindControl (DataSourceID);
462 protected virtual IEnumerable GetResolvedDataSource ()
464 if (DataSource != null && DataSourceID != "")
465 throw new HttpException ();
467 IDataSource ds = this.GetDataSourceObject () as IDataSource;
468 if (ds != null && DataSourceID != "")
469 return ds.GetView (DataMember).Select ();
470 else if (DataSource != null)
471 return DataSourceHelper.GetResolvedDataSource (DataSource, DataMember);
476 protected void OnDataSourceChanged (object sender, EventArgs e)
478 RequiresDataBinding = true;
481 public virtual string DataSourceID {
483 object o = ViewState ["DataSourceID"];
491 RequiresDataBinding = true;
493 ViewState ["DataSourceID"] = value;
497 bool requiresDataBinding;
498 protected bool RequiresDataBinding {
499 get { return requiresDataBinding; }
500 set { requiresDataBinding = value; }
503 protected bool inited;
506 IEnumerable GetResolvedDataSource ()
508 if (DataSource != null)
509 return DataSourceHelper.GetResolvedDataSource (DataSource, DataMember);