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 [WebSysDescription ("")]
108 [WebCategory ("Style")]
109 public virtual TableItemStyle AlternatingItemStyle {
111 if (alternatingItemStyle == null) {
112 alternatingItemStyle = new TableItemStyle ();
113 if (IsTrackingViewState) {
114 alternatingItemStyle.TrackViewState ();
117 return alternatingItemStyle;
122 [DefaultValue (null)]
123 [TemplateContainer (typeof (DataListItem))]
124 [PersistenceMode (PersistenceMode.InnerProperty)]
125 [WebSysDescription ("")]
126 [WebCategory ("Style")]
127 public virtual ITemplate AlternatingItemTemplate {
128 get { return alternatingItemTemplate; }
129 set { alternatingItemTemplate = value; }
133 [WebSysDescription ("")]
134 [WebCategory ("Misc")]
135 public virtual int EditItemIndex {
137 object o = ViewState ["EditItemIndex"];
138 return (o == null) ? -1 : (int) o;
142 throw new ArgumentOutOfRangeException ("EditItemIndex", "< -1");
143 ViewState ["EditItemIndex"] = value;
147 [DefaultValue (null)]
148 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
149 [NotifyParentProperty (true)]
150 [PersistenceMode (PersistenceMode.InnerProperty)]
151 [WebSysDescription ("")]
152 [WebCategory ("Style")]
153 public virtual TableItemStyle EditItemStyle {
155 if (editItemStyle == null) {
156 editItemStyle = new TableItemStyle ();
157 if (IsTrackingViewState) {
158 editItemStyle.TrackViewState ();
161 return editItemStyle;
166 [DefaultValue (null)]
167 [TemplateContainer (typeof (DataListItem))]
168 [PersistenceMode (PersistenceMode.InnerProperty)]
169 [WebSysDescription ("")]
170 [WebCategory ("Style")]
171 public virtual ITemplate EditItemTemplate {
172 get { return editItemTemplate; }
173 set { editItemTemplate = value; }
176 [DefaultValue (false)]
177 [WebSysDescription ("")]
178 [WebCategory ("Misc")]
179 public virtual bool ExtractTemplateRows {
181 object o = ViewState ["ExtractTemplateRows"];
182 return (o == null) ? false : (bool) o;
184 set { ViewState ["ExtractTemplateRows"] = value; }
187 [DefaultValue (null)]
188 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
189 [NotifyParentProperty (true)]
190 [PersistenceMode (PersistenceMode.InnerProperty)]
191 [WebSysDescription ("")]
192 [WebCategory ("Style")]
193 public virtual TableItemStyle FooterStyle {
195 if (footerStyle == null) {
196 footerStyle = new TableItemStyle ();
197 if (IsTrackingViewState) {
198 footerStyle.TrackViewState ();
206 [DefaultValue (null)]
207 [TemplateContainer (typeof (DataListItem))]
208 [PersistenceMode (PersistenceMode.InnerProperty)]
209 [WebSysDescription ("")]
210 [WebCategory ("Style")]
211 public virtual ITemplate FooterTemplate {
212 get { return footerTemplate; }
213 set { footerTemplate = value; }
216 // yes! they do NOT match in fx1.1
217 [DefaultValue (GridLines.None)]
218 public override GridLines GridLines {
220 if (!ControlStyleCreated) {
222 return GridLines.None;
224 return GridLines.Both;
227 return TableStyle.GridLines;
229 set { TableStyle.GridLines = value; }
232 [DefaultValue (null)]
233 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
234 [NotifyParentProperty (true)]
235 [PersistenceMode (PersistenceMode.InnerProperty)]
236 [WebSysDescription ("")]
237 [WebCategory ("Style")]
238 public virtual TableItemStyle HeaderStyle {
240 if (headerStyle == null) {
241 headerStyle = new TableItemStyle ();
242 if (IsTrackingViewState) {
243 headerStyle.TrackViewState ();
251 [DefaultValue (null)]
252 [TemplateContainer (typeof (DataListItem))]
253 [PersistenceMode (PersistenceMode.InnerProperty)]
254 [WebSysDescription ("")]
255 [WebCategory ("Style")]
256 public virtual ITemplate HeaderTemplate {
257 get { return headerTemplate; }
258 set { headerTemplate = value; }
262 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
263 [WebSysDescription ("")]
264 [WebCategory ("Style")]
265 public virtual DataListItemCollection Items {
268 items = new DataListItemCollection (ItemList);
273 [DefaultValue (null)]
274 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
275 [NotifyParentProperty (true)]
276 [PersistenceMode (PersistenceMode.InnerProperty)]
277 [WebSysDescription ("")]
278 [WebCategory ("Style")]
279 public virtual TableItemStyle ItemStyle {
281 if (itemStyle == null) {
282 itemStyle = new TableItemStyle ();
283 if (IsTrackingViewState) {
284 itemStyle.TrackViewState ();
292 [DefaultValue (null)]
293 [TemplateContainer (typeof (DataListItem))]
294 [PersistenceMode (PersistenceMode.InnerProperty)]
295 [WebSysDescription ("")]
296 [WebCategory ("Style")]
297 public virtual ITemplate ItemTemplate {
298 get { return itemTemplate; }
299 set { itemTemplate = value; }
306 [WebSysDescription ("")]
307 [WebCategory ("Layout")]
308 public virtual int RepeatColumns {
310 object o = ViewState ["RepeatColumns"];
311 return (o == null) ? 0 : (int) o;
315 throw new ArgumentOutOfRangeException ("value", "RepeatColumns value has to be 0 for 'not set' or > 0.");
317 ViewState ["RepeatColumns"] = value;
324 [DefaultValue (RepeatDirection.Vertical)]
325 [WebSysDescription ("")]
326 [WebCategory ("Layout")]
327 public virtual RepeatDirection RepeatDirection {
329 object o = ViewState ["RepeatDirection"];
330 return (o == null) ? RepeatDirection.Vertical : (RepeatDirection) o;
332 set { ViewState ["RepeatDirection"] = value; }
338 [DefaultValue (RepeatLayout.Table)]
339 [WebSysDescription ("")]
340 [WebCategory ("Layout")]
341 public virtual RepeatLayout RepeatLayout {
343 object o = ViewState ["RepeatLayout"];
344 return (o == null) ? RepeatLayout.Table : (RepeatLayout) o;
346 set { ViewState ["RepeatLayout"] = value; }
351 [WebSysDescription ("")]
352 [WebCategory ("Layout")]
353 public virtual int SelectedIndex {
355 object o = ViewState ["SelectedIndex"];
356 return (o == null) ? -1 : (int) o;
360 throw new ArgumentOutOfRangeException ("SelectedIndex", "< -1");
361 ViewState ["SelectedIndex"] = value;
366 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
367 [WebSysDescription ("")]
368 [WebCategory ("Layout")]
369 public virtual DataListItem SelectedItem {
371 if (SelectedIndex < 0)
373 if (SelectedIndex >= Items.Count)
374 throw new ArgumentOutOfRangeException ("SelectedItem", ">= Items.Count");
375 return items [SelectedIndex];
379 [DefaultValue (null)]
380 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
381 [NotifyParentProperty (true)]
382 [PersistenceMode (PersistenceMode.InnerProperty)]
383 [WebSysDescription ("")]
384 [WebCategory ("Style")]
385 public virtual TableItemStyle SelectedItemStyle {
387 if (selectedItemStyle == null) {
388 selectedItemStyle = new TableItemStyle ();
389 if (IsTrackingViewState) {
390 selectedItemStyle.TrackViewState ();
393 return selectedItemStyle;
398 [DefaultValue (null)]
399 [TemplateContainer (typeof (DataListItem))]
400 [PersistenceMode (PersistenceMode.InnerProperty)]
401 [WebSysDescription ("")]
402 [WebCategory ("Style")]
403 public virtual ITemplate SelectedItemTemplate {
404 get { return selectedItemTemplate; }
405 set { selectedItemTemplate = value; }
408 [DefaultValue (null)]
409 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
410 [NotifyParentProperty (true)]
411 [PersistenceMode (PersistenceMode.InnerProperty)]
412 [WebSysDescription ("")]
413 [WebCategory ("Style")]
414 public virtual TableItemStyle SeparatorStyle {
416 if (separatorStyle == null) {
417 separatorStyle = new TableItemStyle ();
418 if (IsTrackingViewState) {
419 separatorStyle.TrackViewState ();
422 return separatorStyle;
427 [DefaultValue (null)]
428 [TemplateContainer (typeof (DataListItem))]
429 [PersistenceMode (PersistenceMode.InnerProperty)]
430 [WebSysDescription ("")]
431 [WebCategory ("Style")]
432 public virtual ITemplate SeparatorTemplate {
433 get { return separatorTemplate; }
434 set { separatorTemplate = value; }
440 [DefaultValue (true)]
441 [WebSysDescription ("")]
442 [WebCategory ("Appearance")]
443 public virtual bool ShowFooter {
445 object o = ViewState ["ShowFooter"];
446 return (o == null) ? true : (bool) o;
448 set { ViewState ["ShowFooter"] = value; }
454 [DefaultValue (true)]
455 [WebSysDescription ("")]
456 [WebCategory ("Appearance")]
457 public virtual bool ShowHeader {
459 object o = ViewState ["ShowHeader"];
460 return (o == null) ? true : (bool) o;
462 set { ViewState ["ShowHeader"] = value; }
466 [MonoTODO ("incomplete")]
468 public object SelectedValue {
470 if (DataKeyField.Length == 0)
471 throw new InvalidOperationException (Locale.GetText ("No DataKeyField present."));
473 if ((SelectedIndex >= 0) && (selectedIndex < DataKeys.Count)) {
474 return DataKeys [selectedIndex];
481 protected override HtmlTextWriterTag TagKey {
482 get { return HtmlTextWriterTag.Table; }
486 private TableStyle TableStyle {
487 // this will throw an InvalidCasException just like we need
488 get { return (TableStyle) ControlStyle; }
491 private ArrayList ItemList {
494 list = new ArrayList ();
499 void DoItem (int i, ListItemType t, object d, bool databind)
501 DataListItem itm = CreateItem (i, t);
504 DataListItemEventArgs e = new DataListItemEventArgs (itm);
505 InitializeItem (itm);
508 // It is very important that this be called *before* data
509 // binding. Otherwise, we won't save our state in the viewstate.
524 private void DoItemInLoop (int i, object d, bool databind, ListItemType type)
526 DoItem (i, type, d, databind);
527 if (SeparatorTemplate != null)
528 DoItem (i, ListItemType.Separator, null, databind);
532 protected override void CreateControlHierarchy (bool useDataSource)
536 IEnumerable ds = null;
537 ArrayList keys = null;
542 if (IsBoundUsingDataSourceID)
546 ds = DataSourceResolver.ResolveDataSource (DataSource, DataMember);
547 keys = DataKeysArray;
550 idx = (int) ViewState ["Items"];
553 if ((ds == null) && (idx == 0))
556 if (headerTemplate != null)
557 DoItem (-1, ListItemType.Header, null, useDataSource);
560 int selected_index = SelectedIndex;
561 int edit_item_index = EditItemIndex;
564 string key = DataKeyField;
565 foreach (object o in ds) {
566 if (useDataSource && key != "")
567 keys.Add (DataBinder.GetPropertyValue (o, key));
568 type = ListItemType.Item;
569 if (idx == edit_item_index)
570 type = ListItemType.EditItem;
571 else if (idx == selected_index)
572 type = ListItemType.SelectedItem;
573 else if (idx % 2 != 0)
574 type = ListItemType.AlternatingItem;
576 DoItemInLoop (idx, o, useDataSource, type);
580 for (int i = 0; i < idx; i++) {
581 type = ListItemType.Item;
582 if (idx == edit_item_index)
583 type = ListItemType.EditItem;
584 else if (idx == selected_index)
585 type = ListItemType.SelectedItem;
586 else if (idx % 2 != 0)
587 type = ListItemType.AlternatingItem;
589 DoItemInLoop (i, null, useDataSource, type);
593 if (footerTemplate != null)
594 DoItem (-1, ListItemType.Footer, null, useDataSource);
596 ViewState ["Items"] = idx;
599 protected override Style CreateControlStyle ()
602 // not kept (directly) in the DataList ViewState
603 return new TableStyle ();
605 TableStyle tableStyle = new TableStyle (ViewState);
606 tableStyle.CellSpacing = 0;
611 protected virtual DataListItem CreateItem (int itemIndex, ListItemType itemType)
613 return new DataListItem (itemIndex, itemType);
616 protected virtual void InitializeItem (DataListItem item)
620 switch (item.ItemType) {
621 case ListItemType.Header:
624 case ListItemType.Footer:
627 case ListItemType.Separator:
628 t = SeparatorTemplate;
630 case ListItemType.Item:
631 case ListItemType.AlternatingItem:
632 case ListItemType.SelectedItem:
633 case ListItemType.EditItem:
634 int index = item.ItemIndex;
635 if ((SelectedIndex == index) && (SelectedItemTemplate != null))
636 t = SelectedItemTemplate;
637 else if ((EditItemIndex == index) && (EditItemTemplate != null))
638 t = EditItemTemplate;
639 else if (((index & 1) == 0) || (alternatingItemTemplate == null))
642 t = alternatingItemTemplate;
647 t.InstantiateIn (item);
650 protected override void LoadViewState (object savedState)
652 object[] state = (object[]) savedState;
654 base.LoadViewState (state [8]);
656 base.LoadViewState (state [0]);
658 if (state [1] != null)
659 ItemStyle.LoadViewState (state [1]);
660 if (state [2] != null)
661 SelectedItemStyle.LoadViewState (state [2]);
662 if (state [3] != null)
663 AlternatingItemStyle.LoadViewState (state [3]);
664 if (state [4] != null)
665 EditItemStyle.LoadViewState (state [4]);
666 if (state [5] != null)
667 SeparatorStyle.LoadViewState (state [5]);
668 if (state [6] != null)
669 HeaderStyle.LoadViewState (state [6]);
670 if (state [7] != null)
671 FooterStyle.LoadViewState (state [7]);
674 protected override bool OnBubbleEvent (object source, EventArgs e)
676 DataListCommandEventArgs dlca = (e as DataListCommandEventArgs);
680 string cn = dlca.CommandName;
681 CultureInfo inv = CultureInfo.InvariantCulture;
683 OnItemCommand (dlca);
684 if (String.Compare (cn, CancelCommandName, true, inv) == 0) {
685 OnCancelCommand (dlca);
687 } else if (String.Compare (cn, DeleteCommandName, true, inv) == 0) {
688 OnDeleteCommand (dlca);
690 } else if (String.Compare (cn, EditCommandName, true, inv) == 0) {
691 OnEditCommand (dlca);
693 } else if (String.Compare (cn, SelectCommandName, true, inv) == 0) {
694 OnSelectedIndexChanged (dlca);
696 } else if (String.Compare (cn, UpdateCommandName, true, inv) == 0) {
697 OnUpdateCommand (dlca);
703 protected virtual void OnCancelCommand (DataListCommandEventArgs e)
705 DataListCommandEventHandler cancelCommand = (DataListCommandEventHandler) Events [cancelCommandEvent];
706 if (cancelCommand != null)
707 cancelCommand (this, e);
710 protected virtual void OnDeleteCommand (DataListCommandEventArgs e)
712 DataListCommandEventHandler deleteCommand = (DataListCommandEventHandler) Events [deleteCommandEvent];
713 if (deleteCommand != null)
714 deleteCommand (this, e);
717 protected virtual void OnEditCommand (DataListCommandEventArgs e)
719 DataListCommandEventHandler editCommand = (DataListCommandEventHandler) Events [editCommandEvent];
720 if (editCommand != null)
721 editCommand (this, e);
724 protected internal override void OnInit (EventArgs e)
726 // EditItemIndex and SelectedIndex now use the Control State (i.e not the View State)
727 Page.RegisterRequiresControlState (this);
731 protected virtual void OnItemCommand (DataListCommandEventArgs e)
733 DataListCommandEventHandler itemCommand = (DataListCommandEventHandler) Events [itemCommandEvent];
734 if (itemCommand != null)
735 itemCommand (this, e);
738 protected virtual void OnItemCreated (DataListItemEventArgs e)
740 DataListItemEventHandler itemCreated = (DataListItemEventHandler) Events [itemCreatedEvent];
741 if (itemCreated != null)
742 itemCreated (this, e);
745 protected virtual void OnItemDataBound (DataListItemEventArgs e)
747 DataListItemEventHandler itemDataBound = (DataListItemEventHandler) Events [itemDataBoundEvent];
748 if (itemDataBound != null)
749 itemDataBound (this, e);
752 protected virtual void OnUpdateCommand (DataListCommandEventArgs e)
754 DataListCommandEventHandler updateCommand = (DataListCommandEventHandler) Events [updateCommandEvent];
755 if (updateCommand != null)
756 updateCommand (this, e);
759 void ApplyControlStyle (Control ctrl, Style style)
761 if (style == null || false == ctrl.HasControls ())
764 foreach (Control c in ctrl.Controls) {
766 Table tbl = (Table) c;
767 foreach (TableRow row in tbl.Rows)
768 row.MergeStyle (style);
773 protected override void PrepareControlHierarchy ()
775 if (!HasControls () || Controls.Count == 0)
776 return; // No one called CreateControlHierarchy() with DataSource != null
779 foreach (DataListItem item in Controls) {
780 switch (item.ItemType) {
781 case ListItemType.Item:
782 item.MergeStyle (itemStyle);
783 ApplyControlStyle (item, itemStyle);
785 case ListItemType.AlternatingItem:
787 if (alternatingItemStyle != null) {
788 alt = new TableItemStyle ();
789 alt.CopyFrom (itemStyle);
790 alt.CopyFrom (alternatingItemStyle);
796 item.MergeStyle (alt);
797 ApplyControlStyle (item, alt);
799 case ListItemType.EditItem:
800 if (editItemStyle != null) {
801 item.MergeStyle (editItemStyle);
802 ApplyControlStyle (item, editItemStyle);
804 item.MergeStyle (itemStyle);
805 ApplyControlStyle (item, itemStyle);
808 case ListItemType.Footer:
810 item.Visible = false;
813 if (footerStyle != null) {
814 item.MergeStyle (footerStyle);
815 ApplyControlStyle (item, footerStyle);
818 case ListItemType.Header:
820 item.Visible = false;
823 if (headerStyle != null) {
824 item.MergeStyle (headerStyle);
825 ApplyControlStyle (item, headerStyle);
828 case ListItemType.SelectedItem:
829 if (selectedItemStyle != null) {
830 item.MergeStyle (selectedItemStyle);
831 ApplyControlStyle (item, selectedItemStyle);
833 item.MergeStyle (itemStyle);
834 ApplyControlStyle (item, itemStyle);
837 case ListItemType.Separator:
838 if (separatorStyle != null) {
839 item.MergeStyle(separatorStyle);
840 ApplyControlStyle (item, separatorStyle);
843 item.MergeStyle (itemStyle);
844 ApplyControlStyle (item, itemStyle);
856 override void RenderContents (HtmlTextWriter writer)
858 if (Items.Count == 0)
861 RepeatInfo ri = new RepeatInfo ();
862 ri.RepeatColumns = RepeatColumns;
863 ri.RepeatDirection = RepeatDirection;
864 ri.RepeatLayout = RepeatLayout;
865 ri.CaptionAlign = CaptionAlign;
866 ri.Caption = Caption;
867 ri.UseAccessibleHeader = UseAccessibleHeader;
869 // debugging stuff that I prefer to keep for a while
870 Console.WriteLine ("RepeatColumns {0}", ri.RepeatColumns);
871 Console.WriteLine ("RepeatDirection {0}", ri.RepeatDirection);
872 Console.WriteLine ("RepeatLayout {0}", ri.RepeatLayout);
873 Console.WriteLine ("OuterTableImplied {0}", ExtractTemplateRows);
874 Console.WriteLine ("IRepeatInfoUser.HasFooter {0}", (ShowFooter && (footerTemplate != null)));
875 Console.WriteLine ("IRepeatInfoUser.HasHeader {0}", (ShowHeader && (headerTemplate != null)));
876 Console.WriteLine ("IRepeatInfoUser.HasSeparators {0}", (separatorTemplate != null));
877 Console.WriteLine ("IRepeatInfoUser.RepeatedItemCount {0}", Items.Count);
878 for (int i=0; i < Items.Count; i++) {
879 DataListItem dli = Items [i];
880 Console.WriteLine ("{0}: Index {1}, Type {2}", i, dli.ItemIndex, dli.ItemType);
883 bool extract = ExtractTemplateRows;
885 ri.OuterTableImplied = true;
886 writer.AddAttribute (HtmlTextWriterAttribute.Id, ClientID);
887 if (ControlStyleCreated) {
888 ControlStyle.AddAttributesToRender (writer);
890 writer.RenderBeginTag (HtmlTextWriterTag.Table);
891 ri.RenderRepeater (writer, this, ControlStyle, this);
892 writer.RenderEndTag ();
894 ri.RenderRepeater (writer, this, ControlStyle, this);
898 protected override object SaveViewState ()
901 object[] state = new object [9];
902 // FIXME: what's new in slot #0 ?
903 state[8] = base.SaveViewState ();
905 object[] state = new object [8];
906 state[0] = base.SaveViewState ();
908 if (itemStyle != null)
909 state [1] = itemStyle.SaveViewState ();
910 if (selectedItemStyle != null)
911 state [2] = selectedItemStyle.SaveViewState ();
912 if (alternatingItemStyle != null)
913 state [3] = alternatingItemStyle.SaveViewState ();
914 if (editItemStyle != null)
915 state [4] = editItemStyle.SaveViewState ();
916 if (separatorStyle != null)
917 state [5] = separatorStyle.SaveViewState ();
918 if (headerStyle != null)
919 state [6] = headerStyle.SaveViewState ();
920 if (footerStyle != null)
921 state [7] = footerStyle.SaveViewState ();
925 protected override void TrackViewState ()
927 base.TrackViewState ();
928 if (alternatingItemStyle != null)
929 alternatingItemStyle.TrackViewState ();
930 if (editItemStyle != null)
931 editItemStyle.TrackViewState ();
932 if (footerStyle != null)
933 footerStyle.TrackViewState ();
934 if (headerStyle != null)
935 headerStyle.TrackViewState ();
936 if (itemStyle != null)
937 itemStyle.TrackViewState ();
938 if (selectedItemStyle != null)
939 selectedItemStyle.TrackViewState ();
940 if (separatorStyle != null)
941 separatorStyle.TrackViewState ();
945 [WebSysDescription ("")]
946 [WebCategory ("Action")]
947 public event DataListCommandEventHandler CancelCommand {
948 add { Events.AddHandler (cancelCommandEvent, value); }
949 remove { Events.RemoveHandler (cancelCommandEvent, value); }
952 [WebSysDescription ("")]
953 [WebCategory ("Action")]
954 public event DataListCommandEventHandler DeleteCommand {
955 add { Events.AddHandler (deleteCommandEvent, value); }
956 remove { Events.RemoveHandler (deleteCommandEvent, value); }
959 [WebSysDescription ("")]
960 [WebCategory ("Action")]
961 public event DataListCommandEventHandler EditCommand {
962 add { Events.AddHandler (editCommandEvent, value); }
963 remove { Events.RemoveHandler (editCommandEvent, value); }
966 [WebSysDescription ("")]
967 [WebCategory ("Action")]
968 public event DataListCommandEventHandler ItemCommand {
969 add { Events.AddHandler (itemCommandEvent, value); }
970 remove { Events.RemoveHandler (itemCommandEvent, value); }
973 [WebSysDescription ("")]
974 [WebCategory ("Action")]
975 public event DataListItemEventHandler ItemCreated {
976 add { Events.AddHandler (itemCreatedEvent, value); }
977 remove { Events.RemoveHandler (itemCreatedEvent, value); }
980 [WebSysDescription ("")]
981 [WebCategory ("Action")]
982 public event DataListItemEventHandler ItemDataBound {
983 add { Events.AddHandler (itemDataBoundEvent, value); }
984 remove { Events.RemoveHandler (itemDataBoundEvent, value); }
987 [WebSysDescription ("")]
988 [WebCategory ("Action")]
989 public event DataListCommandEventHandler UpdateCommand {
990 add { Events.AddHandler (updateCommandEvent, value); }
991 remove { Events.RemoveHandler (updateCommandEvent, value); }
995 // IRepeatInfoUser support
997 bool IRepeatInfoUser.HasFooter {
998 get { return (ShowFooter && (footerTemplate != null)); }
1001 bool IRepeatInfoUser.HasHeader {
1002 get { return (ShowHeader && (headerTemplate != null)); }
1005 bool IRepeatInfoUser.HasSeparators {
1006 get { return (separatorTemplate != null); }
1009 // don't include header, footer and separators in the count
1010 int IRepeatInfoUser.RepeatedItemCount {
1013 object o = ViewState ["Items"];
1014 idx = (o == null) ? 0 : (int) o;
1020 Style IRepeatInfoUser.GetItemStyle (ListItemType itemType, int repeatIndex)
1022 DataListItem item = null;
1024 case ListItemType.Header:
1025 case ListItemType.Footer:
1026 if (repeatIndex >= 0 && (!HasControls () || repeatIndex >= Controls.Count))
1027 throw new ArgumentOutOfRangeException ();
1029 item = FindFirstItem (itemType);
1031 case ListItemType.Item:
1032 case ListItemType.AlternatingItem:
1033 case ListItemType.SelectedItem:
1034 case ListItemType.EditItem:
1035 if (repeatIndex >= 0 && (!HasControls () || repeatIndex >= Controls.Count))
1036 throw new ArgumentOutOfRangeException ();
1038 item = FindBestItem (repeatIndex);
1040 case ListItemType.Separator:
1041 if (repeatIndex >= 0 && (!HasControls () || repeatIndex >= Controls.Count))
1042 throw new ArgumentOutOfRangeException ();
1044 item = FindSpecificItem (itemType, repeatIndex);
1051 if (item == null || item.ControlStyleCreated == false)
1054 return item.ControlStyle;
1057 // Header and Footer don't have a "real" index (-1)
1058 private DataListItem FindFirstItem (ListItemType itemType)
1060 for (int i = 0; i < Controls.Count; i++) {
1061 DataListItem item = (Controls [i] as DataListItem);
1062 if ((item != null) && (item.ItemType == itemType))
1068 // Both Type and Index must match (e.g. Separator)
1069 private DataListItem FindSpecificItem (ListItemType itemType, int repeatIndex)
1071 for (int i = 0; i < Controls.Count; i++) {
1072 DataListItem item = (Controls [i] as DataListItem);
1073 if ((item != null) && (item.ItemType == itemType) && (item.ItemIndex == repeatIndex))
1079 // we get call for Item even for AlternatingItem :(
1080 private DataListItem FindBestItem (int repeatIndex)
1082 for (int i = 0; i < Controls.Count; i++) {
1083 DataListItem item = (Controls [i] as DataListItem);
1084 if ((item != null) && (item.ItemIndex == repeatIndex)) {
1085 switch (item.ItemType) {
1086 case ListItemType.Item:
1087 case ListItemType.AlternatingItem:
1088 case ListItemType.SelectedItem:
1089 case ListItemType.EditItem:
1099 void IRepeatInfoUser.RenderItem (ListItemType itemType, int repeatIndex, RepeatInfo repeatInfo, HtmlTextWriter writer)
1101 // if possible take the easy way out...
1102 if (!HasControls ())
1105 DataListItem item = null;
1107 case ListItemType.Header:
1108 case ListItemType.Footer:
1109 item = FindFirstItem (itemType);
1111 case ListItemType.Item:
1112 case ListItemType.AlternatingItem:
1113 case ListItemType.SelectedItem:
1114 case ListItemType.EditItem:
1115 item = FindBestItem (repeatIndex);
1117 case ListItemType.Separator:
1118 item = FindSpecificItem (itemType, repeatIndex);
1123 bool extract = ExtractTemplateRows;
1124 bool table = (RepeatLayout == RepeatLayout.Table);
1125 if (!table || extract) {
1126 // sadly RepeatInfo doesn't support Style for RepeatLayout.Flow
1127 Style s = (this as IRepeatInfoUser).GetItemStyle (itemType, repeatIndex);
1129 item.ControlStyle.CopyFrom (s);
1131 //Console.WriteLine ("RenderItem #{0} type {1}", repeatIndex, itemType);
1132 item.RenderItem (writer, extract, table);
1134 //Console.WriteLine ("Couldn't find #{0} type {1} out of {2} items / {3} controls", repeatIndex, itemType, Items.Count, Controls.Count);