2 // System.Web.UI.WebControls.DataList.cs
5 // Sebastien Pouliot <sebastien@ximian.com>
7 // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 using System.Collections;
30 using System.ComponentModel;
31 using System.Globalization;
32 using System.Security.Permissions;
33 using System.Web.Util;
35 namespace System.Web.UI.WebControls {
38 [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
39 [AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
41 [Designer ("System.Web.UI.Design.WebControls.DataListDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
43 [ControlValueProperty ("SelectedValue")]
44 [Editor ("System.Web.UI.Design.WebControls.DataListComponentEditor, " + Consts.AssemblySystem_Design, "System.ComponentModel.ComponentEditor, " + Consts.AssemblySystem)]
46 [Editor ("System.Web.UI.Design.WebControls.DataListComponentEditor, " + Consts.AssemblySystem_Design, typeof (System.ComponentModel.ComponentEditor))]
48 public class DataList : BaseDataList, INamingContainer, IRepeatInfoUser {
50 public const string CancelCommandName = "Cancel";
51 public const string DeleteCommandName = "Delete";
52 public const string EditCommandName = "Edit";
53 public const string SelectCommandName = "Select";
54 public const string UpdateCommandName = "Update";
57 private static readonly object cancelCommandEvent = new object ();
58 private static readonly object deleteCommandEvent = new object ();
59 private static readonly object editCommandEvent = new object ();
60 private static readonly object itemCommandEvent = new object ();
61 private static readonly object itemCreatedEvent = new object ();
62 private static readonly object itemDataBoundEvent = new object ();
63 private static readonly object updateCommandEvent = new object ();
65 private TableItemStyle alternatingItemStyle;
66 private TableItemStyle editItemStyle;
67 private TableItemStyle footerStyle;
68 private TableItemStyle headerStyle;
69 private TableItemStyle itemStyle;
70 private TableItemStyle selectedItemStyle;
71 private TableItemStyle separatorStyle;
73 private ITemplate alternatingItemTemplate;
74 private ITemplate editItemTemplate;
75 private ITemplate footerTemplate;
76 private ITemplate headerTemplate;
77 private ITemplate itemTemplate;
78 private ITemplate selectedItemTemplate;
79 private ITemplate separatorTemplate;
81 private DataListItemCollection items;
82 private ArrayList list;
86 private int editIndex;
87 private int selectedIndex;
103 [DefaultValue (null)]
104 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
105 [NotifyParentProperty (true)]
106 [PersistenceMode (PersistenceMode.InnerProperty)]
107 public virtual TableItemStyle AlternatingItemStyle {
109 if (alternatingItemStyle == null) {
110 alternatingItemStyle = new TableItemStyle ();
111 if (IsTrackingViewState) {
112 alternatingItemStyle.TrackViewState ();
115 return alternatingItemStyle;
120 [DefaultValue (null)]
121 [TemplateContainer (typeof (DataListItem))]
122 [PersistenceMode (PersistenceMode.InnerProperty)]
123 public virtual ITemplate AlternatingItemTemplate {
124 get { return alternatingItemTemplate; }
125 set { alternatingItemTemplate = value; }
129 public virtual int EditItemIndex {
131 get { return editIndex; }
134 throw new ArgumentOutOfRangeException ("EditItemIndex", "< -1");
139 object o = ViewState ["EditItemIndex"];
140 return (o == null) ? -1 : (int) o;
144 throw new ArgumentOutOfRangeException ("EditItemIndex", "< -1");
145 ViewState ["EditItemIndex"] = value;
150 [DefaultValue (null)]
151 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
152 [NotifyParentProperty (true)]
153 [PersistenceMode (PersistenceMode.InnerProperty)]
154 public virtual TableItemStyle EditItemStyle {
156 if (editItemStyle == null) {
157 editItemStyle = new TableItemStyle ();
158 if (IsTrackingViewState) {
159 editItemStyle.TrackViewState ();
162 return editItemStyle;
167 [DefaultValue (null)]
168 [TemplateContainer (typeof (DataListItem))]
169 [PersistenceMode (PersistenceMode.InnerProperty)]
170 public virtual ITemplate EditItemTemplate {
171 get { return editItemTemplate; }
172 set { editItemTemplate = value; }
175 [DefaultValue (false)]
176 public virtual bool ExtractTemplateRows {
178 object o = ViewState ["ExtractTemplateRows"];
179 return (o == null) ? false : (bool) o;
181 set { ViewState ["ExtractTemplateRows"] = value; }
184 [DefaultValue (null)]
185 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
186 [NotifyParentProperty (true)]
187 [PersistenceMode (PersistenceMode.InnerProperty)]
188 public virtual TableItemStyle FooterStyle {
190 if (footerStyle == null) {
191 footerStyle = new TableItemStyle ();
192 if (IsTrackingViewState) {
193 footerStyle.TrackViewState ();
201 [DefaultValue (null)]
202 [TemplateContainer (typeof (DataListItem))]
203 [PersistenceMode (PersistenceMode.InnerProperty)]
204 public virtual ITemplate FooterTemplate {
205 get { return footerTemplate; }
206 set { footerTemplate = value; }
209 // yes! they do NOT match in fx1.1
210 [DefaultValue (GridLines.None)]
211 public override GridLines GridLines {
213 if (!ControlStyleCreated) {
215 return GridLines.None;
217 return GridLines.Both;
220 return TableStyle.GridLines;
222 set { TableStyle.GridLines = value; }
225 [DefaultValue (null)]
226 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
227 [NotifyParentProperty (true)]
228 [PersistenceMode (PersistenceMode.InnerProperty)]
229 public virtual TableItemStyle HeaderStyle {
231 if (headerStyle == null) {
232 headerStyle = new TableItemStyle ();
233 if (IsTrackingViewState) {
234 headerStyle.TrackViewState ();
242 [DefaultValue (null)]
243 [TemplateContainer (typeof (DataListItem))]
244 [PersistenceMode (PersistenceMode.InnerProperty)]
245 public virtual ITemplate HeaderTemplate {
246 get { return headerTemplate; }
247 set { headerTemplate = value; }
251 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
252 public virtual DataListItemCollection Items {
255 items = new DataListItemCollection (ItemList);
260 [DefaultValue (null)]
261 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
262 [NotifyParentProperty (true)]
263 [PersistenceMode (PersistenceMode.InnerProperty)]
264 public virtual TableItemStyle ItemStyle {
266 if (itemStyle == null) {
267 itemStyle = new TableItemStyle ();
268 if (IsTrackingViewState) {
269 itemStyle.TrackViewState ();
277 [DefaultValue (null)]
278 [TemplateContainer (typeof (DataListItem))]
279 [PersistenceMode (PersistenceMode.InnerProperty)]
280 public virtual ITemplate ItemTemplate {
281 get { return itemTemplate; }
282 set { itemTemplate = value; }
289 public virtual int RepeatColumns {
291 object o = ViewState ["RepeatColumns"];
292 return (o == null) ? 0 : (int) o;
294 set { ViewState ["RepeatColumns"] = value; }
300 [DefaultValue (RepeatDirection.Vertical)]
301 public virtual RepeatDirection RepeatDirection {
303 object o = ViewState ["RepeatDirection"];
304 return (o == null) ? RepeatDirection.Vertical : (RepeatDirection) o;
306 set { ViewState ["RepeatDirection"] = value; }
312 [DefaultValue (RepeatLayout.Table)]
313 public virtual RepeatLayout RepeatLayout {
315 object o = ViewState ["RepeatLayout"];
316 return (o == null) ? RepeatLayout.Table : (RepeatLayout) o;
318 set { ViewState ["RepeatLayout"] = value; }
323 public virtual int SelectedIndex {
325 get { return selectedIndex; }
328 throw new ArgumentOutOfRangeException ("SelectedIndex", "< -1");
329 selectedIndex = value;
333 object o = ViewState ["SelectedIndex"];
334 return (o == null) ? -1 : (int) o;
338 throw new ArgumentOutOfRangeException ("SelectedIndex", "< -1");
339 ViewState ["SelectedIndex"] = value;
345 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
346 public virtual DataListItem SelectedItem {
348 if (SelectedIndex < 0)
350 if (SelectedIndex >= Items.Count)
351 throw new ArgumentOutOfRangeException ("SelectedItem", ">= Items.Count");
352 return items [SelectedIndex];
356 [DefaultValue (null)]
357 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
358 [NotifyParentProperty (true)]
359 [PersistenceMode (PersistenceMode.InnerProperty)]
360 public virtual TableItemStyle SelectedItemStyle {
362 if (selectedItemStyle == null) {
363 selectedItemStyle = new TableItemStyle ();
364 if (IsTrackingViewState) {
365 selectedItemStyle.TrackViewState ();
368 return selectedItemStyle;
373 [DefaultValue (null)]
374 [TemplateContainer (typeof (DataListItem))]
375 [PersistenceMode (PersistenceMode.InnerProperty)]
376 public virtual ITemplate SelectedItemTemplate {
377 get { return selectedItemTemplate; }
378 set { selectedItemTemplate = value; }
381 [DefaultValue (null)]
382 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
383 [NotifyParentProperty (true)]
384 [PersistenceMode (PersistenceMode.InnerProperty)]
385 public virtual TableItemStyle SeparatorStyle {
387 if (separatorStyle == null) {
388 separatorStyle = new TableItemStyle ();
389 if (IsTrackingViewState) {
390 separatorStyle.TrackViewState ();
393 return separatorStyle;
398 [DefaultValue (null)]
399 [TemplateContainer (typeof (DataListItem))]
400 [PersistenceMode (PersistenceMode.InnerProperty)]
401 public virtual ITemplate SeparatorTemplate {
402 get { return separatorTemplate; }
403 set { separatorTemplate = value; }
409 [DefaultValue (true)]
410 public virtual bool ShowFooter {
412 object o = ViewState ["ShowFooter"];
413 return (o == null) ? true : (bool) o;
415 set { ViewState ["ShowFooter"] = value; }
421 [DefaultValue (true)]
422 public virtual bool ShowHeader {
424 object o = ViewState ["ShowHeader"];
425 return (o == null) ? true : (bool) o;
427 set { ViewState ["ShowHeader"] = value; }
431 [MonoTODO ("incomplete")]
433 public object SelectedValue {
435 if (DataKeyField.Length == 0)
436 throw new InvalidOperationException (Locale.GetText ("No DataKeyField present."));
438 if ((SelectedIndex >= 0) && (selectedIndex < DataKeys.Count)) {
439 return DataKeys [selectedIndex];
446 protected override HtmlTextWriterTag TagKey {
447 get { return HtmlTextWriterTag.Table; }
451 private TableStyle TableStyle {
452 // this will throw an InvalidCasException just like we need
453 get { return (TableStyle) ControlStyle; }
456 private ArrayList ItemList {
459 list = new ArrayList ();
464 void DoItem (int i, ListItemType t, object d, bool databind)
466 DataListItem itm = CreateItem (i, t);
468 DataListItemEventArgs e = new DataListItemEventArgs (itm);
469 InitializeItem (itm);
472 // It is very important that this be called *before* data
473 // binding. Otherwise, we won't save our state in the viewstate.
486 private void DoItemInLoop (int i, object d, bool databind)
488 if (i > 0 && SeparatorTemplate != null)
489 DoItem (i - 1, ListItemType.Separator, null, databind);
491 DoItem (i, i % 2 == 0 ? ListItemType.Item : ListItemType.AlternatingItem, d, databind);
494 protected override void CreateControlHierarchy (bool useDataSource)
498 IEnumerable ds = null;
502 ds = DataSourceResolver.ResolveDataSource (DataSource, DataMember);
504 idx = (int) ViewState ["Items"];
507 if ((ds == null) && (idx == 0))
510 if (headerTemplate != null)
511 DoItem (-1, ListItemType.Header, null, useDataSource);
515 foreach (object o in ds) {
516 DoItemInLoop (idx, o, useDataSource);
520 for (int i = 0; i < idx; i++) {
521 DoItemInLoop (i, null, useDataSource);
525 if (footerTemplate != null)
526 DoItem (-1, ListItemType.Footer, null, useDataSource);
528 ViewState ["Items"] = idx;
531 protected override Style CreateControlStyle ()
534 // not kept (directly) in the DataList ViewState
535 return new TableStyle ();
537 return new TableStyle (ViewState);
541 protected virtual DataListItem CreateItem (int itemIndex, ListItemType itemType)
543 return new DataListItem (itemIndex, itemType);
546 protected virtual void InitializeItem (DataListItem item)
550 switch (item.ItemType) {
551 case ListItemType.Header:
554 case ListItemType.Footer:
557 case ListItemType.Separator:
558 t = SeparatorTemplate;
560 case ListItemType.Item:
561 case ListItemType.AlternatingItem:
562 case ListItemType.SelectedItem:
563 case ListItemType.EditItem:
564 int index = item.ItemIndex;
565 if (SelectedIndex == index)
566 t = SelectedItemTemplate;
567 else if (EditItemIndex == index)
568 t = EditItemTemplate;
569 else if (((index & 1) == 0) || (alternatingItemTemplate == null))
572 t = alternatingItemTemplate;
577 t.InstantiateIn (item);
580 protected override void LoadViewState (object savedState)
582 object[] state = (object[]) savedState;
583 base.LoadViewState (state [0]);
584 if (state [1] != null)
585 ItemStyle.LoadViewState (state [1]);
586 if (state [2] != null)
587 SelectedItemStyle.LoadViewState (state [2]);
588 if (state [3] != null)
589 AlternatingItemStyle.LoadViewState (state [3]);
590 if (state [4] != null)
591 EditItemStyle.LoadViewState (state [4]);
592 if (state [5] != null)
593 SeparatorStyle.LoadViewState (state [5]);
594 if (state [6] != null)
595 HeaderStyle.LoadViewState (state [6]);
596 if (state [7] != null)
597 FooterStyle.LoadViewState (state [7]);
600 protected internal override void LoadControlState (object savedState)
602 // FIXME: what's in Triplet.First ?
603 // ??? maybe a some space for base.LoadControlState ???
604 if (savedState == null) {
605 // reset to default values
609 Triplet t = (Triplet) savedState;
610 if (t.Second == null) {
613 editIndex = (int) t.Second;
615 if (t.Third == null) {
618 selectedIndex = (int) t.Third;
623 protected internal override object SaveControlState ()
625 bool e = (editIndex == -1);
626 bool s = (selectedIndex == -1);
630 Triplet t = new Triplet ();
632 t.Second = editIndex;
634 t.Third = selectedIndex;
639 protected override bool OnBubbleEvent (object source, EventArgs e)
641 DataListCommandEventArgs dlca = (e as DataListCommandEventArgs);
645 string cn = dlca.CommandName;
646 CultureInfo inv = CultureInfo.InvariantCulture;
648 if (String.Compare (cn, CancelCommandName, true, inv) == 0) {
649 OnCancelCommand (dlca);
651 } else if (String.Compare (cn, DeleteCommandName, true, inv) == 0) {
652 OnDeleteCommand (dlca);
654 } else if (String.Compare (cn, EditCommandName, true, inv) == 0) {
655 OnEditCommand (dlca);
657 } else if (String.Compare (cn, SelectCommandName, true, inv) == 0) {
658 OnSelectedIndexChanged (dlca);
660 } else if (String.Compare (cn, UpdateCommandName, true, inv) == 0) {
661 OnUpdateCommand (dlca);
663 } else if (String.Compare (cn, "ITEM", true, inv) == 0) {
664 OnItemCommand (dlca);
671 protected virtual void OnCancelCommand (DataListCommandEventArgs e)
673 DataListCommandEventHandler cancelCommand = (DataListCommandEventHandler) Events [cancelCommandEvent];
674 if (cancelCommand != null)
675 cancelCommand (this, e);
678 protected virtual void OnDeleteCommand (DataListCommandEventArgs e)
680 DataListCommandEventHandler deleteCommand = (DataListCommandEventHandler) Events [deleteCommandEvent];
681 if (deleteCommand != null)
682 deleteCommand (this, e);
685 protected virtual void OnEditCommand (DataListCommandEventArgs e)
687 DataListCommandEventHandler editCommand = (DataListCommandEventHandler) Events [editCommandEvent];
688 if (editCommand != null)
689 editCommand (this, e);
692 protected internal override void OnInit (EventArgs e)
694 // EditItemIndex and SelectedIndex now use the Control State (i.e not the View State)
695 Page.RegisterRequiresControlState (this);
699 protected virtual void OnItemCommand (DataListCommandEventArgs e)
701 DataListCommandEventHandler itemCommand = (DataListCommandEventHandler) Events [itemCommandEvent];
702 if (itemCommand != null)
703 itemCommand (this, e);
706 protected virtual void OnItemCreated (DataListItemEventArgs e)
708 DataListItemEventHandler itemCreated = (DataListItemEventHandler) Events [itemCreatedEvent];
709 if (itemCreated != null)
710 itemCreated (this, e);
713 protected virtual void OnItemDataBound (DataListItemEventArgs e)
715 DataListItemEventHandler itemDataBound = (DataListItemEventHandler) Events [itemDataBoundEvent];
716 if (itemDataBound != null)
717 itemDataBound (this, e);
720 protected virtual void OnUpdateCommand (DataListCommandEventArgs e)
722 DataListCommandEventHandler updateCommand = (DataListCommandEventHandler) Events [updateCommandEvent];
723 if (updateCommand != null)
724 updateCommand (this, e);
727 protected override void PrepareControlHierarchy ()
736 override void RenderContents (HtmlTextWriter writer)
738 RepeatInfo ri = new RepeatInfo ();
739 ri.RepeatColumns = RepeatColumns;
740 ri.RepeatDirection = RepeatDirection;
741 ri.RepeatLayout = RepeatLayout;
743 // debugging stuff that I prefer to keep for a while
744 Console.WriteLine ("RepeatColumns {0}", ri.RepeatColumns);
745 Console.WriteLine ("RepeatDirection {0}", ri.RepeatDirection);
746 Console.WriteLine ("RepeatLayout {0}", ri.RepeatLayout);
747 Console.WriteLine ("OuterTableImplied {0}", ExtractTemplateRows);
748 Console.WriteLine ("IRepeatInfoUser.HasFooter {0}", (ShowFooter && (footerTemplate != null)));
749 Console.WriteLine ("IRepeatInfoUser.HasHeader {0}", (ShowHeader && (headerTemplate != null)));
750 Console.WriteLine ("IRepeatInfoUser.HasSeparators {0}", (separatorTemplate != null));
751 Console.WriteLine ("IRepeatInfoUser.RepeatedItemCount {0}", Items.Count);
752 for (int i=0; i < Items.Count; i++) {
753 DataListItem dli = Items [i];
754 Console.WriteLine ("{0}: Index {1}, Type {2}", i, dli.ItemIndex, dli.ItemType);
757 bool extract = ExtractTemplateRows;
759 ri.OuterTableImplied = true;
760 writer.AddAttribute (HtmlTextWriterAttribute.Id, ID);
761 if (ControlStyleCreated) {
762 ControlStyle.AddAttributesToRender (writer);
764 writer.RenderBeginTag (HtmlTextWriterTag.Table);
765 ri.RenderRepeater (writer, this, TableStyle, this);
766 writer.RenderEndTag ();
768 ri.RenderRepeater (writer, this, TableStyle, this);
772 protected override object SaveViewState ()
775 object[] state = new object [9];
776 // FIXME: what's new in slot #0 ?
777 state[8] = base.SaveViewState ();
779 object[] state = new object [8];
780 state[0] = base.SaveViewState ();
782 if (itemStyle != null)
783 state [1] = itemStyle.SaveViewState ();
784 if (selectedItemStyle != null)
785 state [2] = selectedItemStyle.SaveViewState ();
786 if (alternatingItemStyle != null)
787 state [3] = alternatingItemStyle.SaveViewState ();
788 if (editItemStyle != null)
789 state [4] = editItemStyle.SaveViewState ();
790 if (separatorStyle != null)
791 state [5] = separatorStyle.SaveViewState ();
792 if (headerStyle != null)
793 state [6] = headerStyle.SaveViewState ();
794 if (footerStyle != null)
795 state [7] = footerStyle.SaveViewState ();
799 protected override void TrackViewState ()
801 base.TrackViewState ();
802 if (alternatingItemStyle != null)
803 alternatingItemStyle.TrackViewState ();
804 if (editItemStyle != null)
805 editItemStyle.TrackViewState ();
806 if (footerStyle != null)
807 footerStyle.TrackViewState ();
808 if (headerStyle != null)
809 headerStyle.TrackViewState ();
810 if (itemStyle != null)
811 itemStyle.TrackViewState ();
812 if (selectedItemStyle != null)
813 selectedItemStyle.TrackViewState ();
814 if (separatorStyle != null)
815 separatorStyle.TrackViewState ();
819 public event DataListCommandEventHandler CancelCommand {
820 add { Events.AddHandler (cancelCommandEvent, value); }
821 remove { Events.RemoveHandler (cancelCommandEvent, value); }
824 public event DataListCommandEventHandler DeleteCommand {
825 add { Events.AddHandler (deleteCommandEvent, value); }
826 remove { Events.RemoveHandler (deleteCommandEvent, value); }
829 public event DataListCommandEventHandler EditCommand {
830 add { Events.AddHandler (editCommandEvent, value); }
831 remove { Events.RemoveHandler (editCommandEvent, value); }
834 public event DataListCommandEventHandler ItemCommand {
835 add { Events.AddHandler (itemCommandEvent, value); }
836 remove { Events.RemoveHandler (itemCommandEvent, value); }
839 public event DataListItemEventHandler ItemCreated {
840 add { Events.AddHandler (itemCreatedEvent, value); }
841 remove { Events.RemoveHandler (itemCreatedEvent, value); }
844 public event DataListItemEventHandler ItemDataBound {
845 add { Events.AddHandler (itemDataBoundEvent, value); }
846 remove { Events.RemoveHandler (itemDataBoundEvent, value); }
849 public event DataListCommandEventHandler UpdateCommand {
850 add { Events.AddHandler (updateCommandEvent, value); }
851 remove { Events.RemoveHandler (updateCommandEvent, value); }
855 // IRepeatInfoUser support
857 bool IRepeatInfoUser.HasFooter {
858 get { return (ShowFooter && (footerTemplate != null)); }
861 bool IRepeatInfoUser.HasHeader {
862 get { return (ShowHeader && (headerTemplate != null)); }
865 bool IRepeatInfoUser.HasSeparators {
866 get { return (separatorTemplate != null); }
869 // don't include header, footer and separators in the count
870 int IRepeatInfoUser.RepeatedItemCount {
873 object o = ViewState ["Items"];
874 idx = (o == null) ? 0 : (int) o;
880 Style IRepeatInfoUser.GetItemStyle (ListItemType itemType, int repeatIndex)
883 case ListItemType.Header:
884 if (repeatIndex >= Items.Count)
885 throw new ArgumentOutOfRangeException ("repeatIndex");
887 case ListItemType.Footer:
888 if (repeatIndex >= Items.Count)
889 throw new ArgumentOutOfRangeException ("repeatIndex");
891 case ListItemType.Item:
892 case ListItemType.AlternatingItem:
893 case ListItemType.SelectedItem:
894 case ListItemType.EditItem:
895 if (repeatIndex >= Items.Count)
896 throw new ArgumentOutOfRangeException ("repeatIndex");
898 if (SelectedIndex == repeatIndex)
899 return selectedItemStyle;
901 if (EditItemIndex == repeatIndex)
902 return editItemStyle;
904 if (((repeatIndex & 1) == 0) || (alternatingItemStyle == null))
908 TableItemStyle alt = new TableItemStyle ();
909 alt.CopyFrom (itemStyle);
910 alt.CopyFrom (alternatingItemStyle);
912 case ListItemType.Separator:
913 if (repeatIndex >= Items.Count)
914 throw new ArgumentOutOfRangeException ("repeatIndex");
915 return separatorStyle;
921 // Header and Footer don't have a "real" index (-1)
922 private DataListItem FindFirstItem (ListItemType itemType)
924 for (int i = 0; i < Controls.Count; i++) {
925 DataListItem item = (Controls [i] as DataListItem);
926 if ((item != null) && (item.ItemType == itemType))
932 // Both Type and Index must match (e.g. Separator)
933 private DataListItem FindSpecificItem (ListItemType itemType, int repeatIndex)
935 for (int i = 0; i < Controls.Count; i++) {
936 DataListItem item = (Controls [i] as DataListItem);
937 if ((item != null) && (item.ItemType == itemType) && (item.ItemIndex == repeatIndex))
943 // we get call for Item even for AlternatingItem :(
944 private DataListItem FindBestItem (int repeatIndex)
946 for (int i = 0; i < Controls.Count; i++) {
947 DataListItem item = (Controls [i] as DataListItem);
948 if ((item != null) && (item.ItemIndex == repeatIndex)) {
949 switch (item.ItemType) {
950 case ListItemType.Item:
951 case ListItemType.AlternatingItem:
952 case ListItemType.SelectedItem:
953 case ListItemType.EditItem:
963 void IRepeatInfoUser.RenderItem (ListItemType itemType, int repeatIndex, RepeatInfo repeatInfo, HtmlTextWriter writer)
965 // if possible take the easy way out...
969 DataListItem item = null;
971 case ListItemType.Header:
972 case ListItemType.Footer:
973 item = FindFirstItem (itemType);
975 case ListItemType.Item:
976 case ListItemType.AlternatingItem:
977 case ListItemType.SelectedItem:
978 case ListItemType.EditItem:
979 item = FindBestItem (repeatIndex);
981 case ListItemType.Separator:
982 item = FindSpecificItem (itemType, repeatIndex);
987 bool extract = ExtractTemplateRows;
988 bool table = (RepeatLayout == RepeatLayout.Table);
989 if (!table || extract) {
990 // sadly RepeatInfo doesn't support Style for RepeatLayout.Flow
991 Style s = (this as IRepeatInfoUser).GetItemStyle (itemType, repeatIndex);
993 item.ControlStyle.CopyFrom (s);
995 //Console.WriteLine ("RenderItem #{0} type {1}", repeatIndex, itemType);
996 item.RenderItem (writer, extract, table);
998 //Console.WriteLine ("Couldn't find #{0} type {1} out of {2} items / {3} controls", repeatIndex, itemType, Items.Count, Controls.Count);