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)
8 // Sanjay Gupta (gsanjay@novell.com)
10 // (c) 2002 Ximian, Inc. (http://www.ximian.com)
11 // (C) Gaurav Vaish (2002)
12 // (C) 2003 Andreas Nahr
13 // (C) 2004 Novell, Inc. (http://www.novell.com)
17 // Permission is hereby granted, free of charge, to any person obtaining
18 // a copy of this software and associated documentation files (the
19 // "Software"), to deal in the Software without restriction, including
20 // without limitation the rights to use, copy, modify, merge, publish,
21 // distribute, sublicense, and/or sell copies of the Software, and to
22 // permit persons to whom the Software is furnished to do so, subject to
23 // the following conditions:
25 // The above copyright notice and this permission notice shall be
26 // included in all copies or substantial portions of the Software.
28 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
29 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
30 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
31 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
32 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
33 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
34 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
38 using System.Collections;
\r
40 using System.Web.UI;
\r
41 using System.Web.Util;
\r
42 using System.ComponentModel;
43 using System.ComponentModel.Design;
\r
45 namespace System.Web.UI.WebControls
\r
47 [DefaultEvent("ItemCommand")]
\r
48 [DefaultProperty("DataSource")]
\r
49 [Designer ("System.Web.UI.Design.WebControls.RepeaterDesigner, " + Consts.AssemblySystem_Design, typeof (IDesigner))]
\r
50 [ParseChildren(true)]
\r
51 [PersistChildren(false)]
\r
52 public class Repeater : Control, INamingContainer
\r
54 private static readonly object ItemCommandEvent = new object();
\r
55 private static readonly object ItemCreatedEvent = new object();
\r
56 private static readonly object ItemDataBoundEvent = new object();
\r
58 private static readonly string ITEMCOUNT = "Repeater_Item_Count";
\r
60 private ITemplate alternatingItemTemplate;
\r
61 private ITemplate footerTemplate;
\r
62 private ITemplate headerTemplate;
\r
63 private ITemplate itemTemplate;
\r
64 private ITemplate separatorTemplate;
\r
65 private object dataSource;
\r
67 private RepeaterItemCollection items;
\r
68 private ArrayList itemsArrayList;
\r
70 public Repeater(): base()
\r
74 [WebCategory ("Action")]
75 [WebSysDescription ("Raised when a command is executed in the DataList.")]
\r
76 public event RepeaterCommandEventHandler ItemCommand
\r
80 Events.AddHandler(ItemCommandEvent, value);
\r
84 Events.RemoveHandler(ItemCommandEvent, value);
\r
88 [WebCategory ("Behavior")]
89 [WebSysDescription ("Raised when an item gets created.")]
\r
90 public event RepeaterItemEventHandler ItemCreated
\r
94 Events.AddHandler(ItemCreatedEvent, value);
\r
98 Events.RemoveHandler(ItemCreatedEvent, value);
\r
102 [WebCategory ("Behavior")]
103 [WebSysDescription ("Raised when an item gets data-bound.")]
\r
104 public event RepeaterItemEventHandler ItemDataBound
\r
108 Events.AddHandler(ItemDataBoundEvent, value);
\r
112 Events.RemoveHandler(ItemDataBoundEvent, value);
\r
116 [DefaultValue (null), Browsable (false), PersistenceMode (PersistenceMode.InnerProperty)]
117 [TemplateContainer (typeof (RepeaterItem))]
118 [WebSysDescription ("The template that is used to create an alternating item.")]
\r
119 public virtual ITemplate AlternatingItemTemplate
\r
123 return alternatingItemTemplate;
\r
127 alternatingItemTemplate = value;
\r
131 public override ControlCollection Controls
\r
135 EnsureChildControls();
\r
136 return base.Controls;
\r
140 [DefaultValue (""), WebCategory ("Data")]
141 [WebSysDescription ("The name of the table that is used for binding when a DataSource is specified.")]
\r
142 public virtual string DataMember
\r
146 object o = ViewState["DataMember"];
\r
151 return String.Empty;
\r
155 ViewState["DataMember"] = value;
\r
159 [DefaultValue (null), Bindable (true), WebCategory ("Data")]
160 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
161 [WebSysDescription ("The DataSource that is used for data-binding.")]
\r
162 public virtual object DataSource
\r
170 if ((value!=null) && !(value is IListSource) && !(value is IEnumerable))
171 throw new ArgumentException ("An invalid data source is being used for " +
172 ID + ". A valid data source must implement either " +
173 "IListSource or IEnumerable.");
175 dataSource = value;
\r
179 [DefaultValue (null), Browsable (false), PersistenceMode (PersistenceMode.InnerProperty)]
180 [TemplateContainer (typeof (RepeaterItem))]
181 [WebSysDescription ("The template that is used to create a footer.")]
\r
182 public virtual ITemplate FooterTemplate
\r
186 return footerTemplate;
\r
190 footerTemplate = value;
\r
194 [DefaultValue (null), Browsable (false), PersistenceMode (PersistenceMode.InnerProperty)]
195 [TemplateContainer (typeof (RepeaterItem))]
196 [WebSysDescription ("The template that is used to create a header.")]
\r
197 public virtual ITemplate HeaderTemplate
\r
201 return headerTemplate;
\r
205 headerTemplate = value;
\r
210 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
211 [WebSysDescription ("A collection containing all items.")]
\r
212 public virtual RepeaterItemCollection Items
\r
218 if(itemsArrayList == null)
\r
220 EnsureChildControls();
\r
222 items = new RepeaterItemCollection(itemsArrayList);
\r
228 [DefaultValue (null), Browsable (false), PersistenceMode (PersistenceMode.InnerProperty)]
229 [TemplateContainer (typeof (RepeaterItem))]
230 [WebSysDescription ("The template that is used to create an item.")]
\r
231 public virtual ITemplate ItemTemplate
\r
235 return itemTemplate;
\r
239 itemTemplate = value;
\r
243 [DefaultValue (null), Browsable (false), PersistenceMode (PersistenceMode.InnerProperty)]
244 [TemplateContainer (typeof (RepeaterItem))]
245 [WebSysDescription ("The template that is used to create a seperator.")]
\r
246 public virtual ITemplate SeparatorTemplate
\r
250 return separatorTemplate;
\r
254 separatorTemplate = value;
\r
258 public override void DataBind ()
261 RequiresDataBinding = false;
263 OnDataBinding (EventArgs.Empty);
266 protected override void CreateChildControls()
269 if (ViewState[ITEMCOUNT] != null) {
270 CreateControlHierarchy (false);
272 itemsArrayList = new ArrayList ();
273 ClearChildViewState ();
277 private RepeaterItem CreateItem (int itemIndex,
\r
278 ListItemType itemType,
\r
282 RepeaterItem repeaterItem = new RepeaterItem (itemIndex, itemType);
\r
283 RepeaterItemEventArgs repeaterEventArgs = new RepeaterItemEventArgs (repeaterItem);
\r
284 InstantiateItem (repeaterItem);
\r
286 repeaterItem.DataItem = dataItem;
\r
287 OnItemCreated (repeaterEventArgs);
\r
288 Controls.Add (repeaterItem);
\r
290 repeaterItem.DataBind ();
\r
291 OnItemDataBound (repeaterEventArgs);
\r
292 repeaterItem.DataItem = null;
\r
294 return repeaterItem;
\r
297 private void InstantiateItem (RepeaterItem item)
\r
299 ITemplate template;
\r
300 switch (item.ItemType) {
\r
301 case ListItemType.Header:
\r
302 template = this.headerTemplate;
\r
304 case ListItemType.Footer:
\r
305 template = this.footerTemplate;
\r
307 case ListItemType.Item:
\r
308 template = this.itemTemplate;
\r
310 case ListItemType.AlternatingItem:
\r
311 template = (alternatingItemTemplate != null ? this.alternatingItemTemplate : itemTemplate);
\r
313 case ListItemType.Separator:
\r
314 template = this.separatorTemplate;
\r
317 throw new HttpException ("Unknown ListItemType: " + item.ItemType);
\r
320 if (template != null)
\r
321 template.InstantiateIn (item);
\r
324 protected virtual void CreateControlHierarchy (bool useDataSource)
326 if (itemsArrayList != null) {
327 itemsArrayList.Clear ();
329 itemsArrayList = new ArrayList ();
332 IEnumerable ds = null;
334 ds = GetResolvedDataSource ();
336 int itemCount = (int) ViewState [ITEMCOUNT];
338 ds = new DataSourceInternal (itemCount);
343 if (headerTemplate != null)
344 CreateItem (-1, ListItemType.Header, useDataSource, null);
347 foreach (object item in ds){
348 if (separatorTemplate != null && index > 0)
349 CreateItem (index - 1, ListItemType.Separator,
350 useDataSource, null);
352 RepeaterItem repeaterItem;
355 lType = ListItemType.AlternatingItem;
357 lType = ListItemType.Item;
359 repeaterItem = CreateItem (index, lType, useDataSource, item);
360 itemsArrayList.Add (repeaterItem);
365 if (footerTemplate != null)
366 CreateItem (-1, ListItemType.Footer, useDataSource, null);
370 ViewState [ITEMCOUNT] = (ds == null) ? -1 : index;
373 protected override bool OnBubbleEvent(object sender, EventArgs e)
\r
375 bool retVal = false;
\r
376 if(e is RepeaterCommandEventArgs)
\r
378 OnItemCommand((RepeaterCommandEventArgs)e);
\r
384 protected override void OnDataBinding(EventArgs e)
\r
386 base.OnDataBinding(e);
\r
388 ClearChildViewState();
\r
389 CreateControlHierarchy(true);
\r
390 ChildControlsCreated = true;
\r
393 protected virtual void OnItemCommand(RepeaterCommandEventArgs e)
\r
397 RepeaterCommandEventHandler rceh = (RepeaterCommandEventHandler)
\r
398 Events [ItemCommandEvent];
\r
406 protected virtual void OnItemCreated(RepeaterItemEventArgs e)
\r
410 RepeaterItemEventHandler rceh = (RepeaterItemEventHandler)
\r
411 Events [ItemCreatedEvent];
\r
419 protected virtual void OnItemDataBound(RepeaterItemEventArgs e)
\r
423 RepeaterItemEventHandler rceh = (RepeaterItemEventHandler)
\r
424 Events [ItemDataBoundEvent];
\r
432 protected virtual RepeaterItem CreateItem (int itemIndex, ListItemType itemType)
\r
434 return new RepeaterItem (itemIndex, itemType);
\r
437 protected virtual void InitializeItem (RepeaterItem item)
\r
439 InstantiateItem (item);
\r
445 // should be `internal protected' (why, oh WHY did they do that !?!)
446 protected override void OnInit (EventArgs e)
450 if (!Page.IsPostBack)
451 RequiresDataBinding = true;
454 // should be `internal protected' (why, oh WHY did they do that !?!)
455 protected override void OnLoad (EventArgs e)
457 IDataSource ds = GetDataSourceObject () as IDataSource;
458 if (ds != null && DataSourceID != "")
459 ds.DataSourceChanged += new EventHandler (OnDataSourceChanged);
464 // should be `internal protected' (why, oh WHY did they do that !?!)
465 protected override void OnPreRender (EventArgs e)
468 base.OnPreRender (e);
471 protected void EnsureDataBound ()
473 if (RequiresDataBinding && DataSourceID != "")
477 protected virtual object GetDataSourceObject ()
479 if (DataSourceID != "")
480 return (IDataSource) NamingContainer.FindControl (DataSourceID);
485 protected virtual IEnumerable GetResolvedDataSource ()
487 if (DataSource != null && DataSourceID != "")
488 throw new HttpException ();
490 IDataSource ds = this.GetDataSourceObject () as IDataSource;
491 if (ds != null && DataSourceID != "")
492 return ds.GetView (DataMember).ExecuteSelect (selectArguments);
493 else if (DataSource != null)
494 return DataSourceHelper.GetResolvedDataSource (DataSource, DataMember);
499 protected void OnDataSourceChanged (object sender, EventArgs e)
501 RequiresDataBinding = true;
504 public virtual string DataSourceID {
506 object o = ViewState ["DataSourceID"];
514 RequiresDataBinding = true;
516 ViewState ["DataSourceID"] = value;
520 bool requiresDataBinding;
521 protected bool RequiresDataBinding {
522 get { return requiresDataBinding; }
523 set { requiresDataBinding = value; }
526 protected bool inited;
528 DataSourceSelectArguments selectArguments = null;
530 protected DataSourceSelectArguments SelectArguments {
531 get { return selectArguments; }
535 IEnumerable GetResolvedDataSource ()
537 if (DataSource != null)
538 return DataSourceHelper.GetResolvedDataSource (DataSource, DataMember);