2 // System.Web.UI.WebControls.FormView.cs
5 // Lluis Sanchez Gual (lluis@novell.com)
7 // (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.
32 using System.Collections;
33 using System.Collections.Specialized;
34 using System.ComponentModel;
36 using System.Security.Permissions;
39 using System.Reflection;
41 namespace System.Web.UI.WebControls
43 [SupportsEventValidation]
44 [DesignerAttribute ("System.Web.UI.Design.WebControls.FormViewDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
45 [ControlValuePropertyAttribute ("SelectedValue")]
46 [DefaultEventAttribute ("PageIndexChanging")]
47 [AspNetHostingPermissionAttribute (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
48 [AspNetHostingPermissionAttribute (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
49 public class FormView: CompositeDataBoundControl, IDataItemContainer, INamingContainer, IPostBackEventHandler, IPostBackContainer
54 FormViewRow headerRow;
55 FormViewRow footerRow;
56 FormViewRow bottomPagerRow;
57 FormViewRow topPagerRow;
60 IOrderedDictionary currentEditRowKeys;
61 IOrderedDictionary currentEditNewValues;
62 IOrderedDictionary currentEditOldValues;
64 ITemplate pagerTemplate;
65 ITemplate emptyDataTemplate;
66 ITemplate headerTemplate;
67 ITemplate footerTemplate;
68 ITemplate editItemTemplate;
69 ITemplate insertItemTemplate;
70 ITemplate itemTemplate;
72 PropertyDescriptor[] cachedKeyProperties;
73 readonly string[] emptyKeys = new string[0];
76 PagerSettings pagerSettings;
78 TableItemStyle editRowStyle;
79 TableItemStyle insertRowStyle;
80 TableItemStyle emptyDataRowStyle;
81 TableItemStyle footerStyle;
82 TableItemStyle headerStyle;
83 TableItemStyle pagerStyle;
84 TableItemStyle rowStyle;
87 DataKey oldEditValues;
89 private static readonly object PageIndexChangedEvent = new object();
90 private static readonly object PageIndexChangingEvent = new object();
91 private static readonly object ItemCommandEvent = new object();
92 private static readonly object ItemCreatedEvent = new object();
93 private static readonly object ItemDeletedEvent = new object();
94 private static readonly object ItemDeletingEvent = new object();
95 private static readonly object ItemInsertedEvent = new object();
96 private static readonly object ItemInsertingEvent = new object();
97 private static readonly object ModeChangingEvent = new object();
98 private static readonly object ModeChangedEvent = new object();
99 private static readonly object ItemUpdatedEvent = new object();
100 private static readonly object ItemUpdatingEvent = new object();
104 FormViewMode currentMode = FormViewMode.ReadOnly;
110 key = new DataKey (new OrderedDictionary ());
113 public event EventHandler PageIndexChanged {
114 add { Events.AddHandler (PageIndexChangedEvent, value); }
115 remove { Events.RemoveHandler (PageIndexChangedEvent, value); }
118 public event FormViewPageEventHandler PageIndexChanging {
119 add { Events.AddHandler (PageIndexChangingEvent, value); }
120 remove { Events.RemoveHandler (PageIndexChangingEvent, value); }
123 public event FormViewCommandEventHandler ItemCommand {
124 add { Events.AddHandler (ItemCommandEvent, value); }
125 remove { Events.RemoveHandler (ItemCommandEvent, value); }
128 public event EventHandler ItemCreated {
129 add { Events.AddHandler (ItemCreatedEvent, value); }
130 remove { Events.RemoveHandler (ItemCreatedEvent, value); }
133 public event FormViewDeletedEventHandler ItemDeleted {
134 add { Events.AddHandler (ItemDeletedEvent, value); }
135 remove { Events.RemoveHandler (ItemDeletedEvent, value); }
138 public event FormViewDeleteEventHandler ItemDeleting {
139 add { Events.AddHandler (ItemDeletingEvent, value); }
140 remove { Events.RemoveHandler (ItemDeletingEvent, value); }
143 public event FormViewInsertedEventHandler ItemInserted {
144 add { Events.AddHandler (ItemInsertedEvent, value); }
145 remove { Events.RemoveHandler (ItemInsertedEvent, value); }
148 public event FormViewInsertEventHandler ItemInserting {
149 add { Events.AddHandler (ItemInsertingEvent, value); }
150 remove { Events.RemoveHandler (ItemInsertingEvent, value); }
153 public event FormViewModeEventHandler ModeChanging {
154 add { Events.AddHandler (ModeChangingEvent, value); }
155 remove { Events.RemoveHandler (ModeChangingEvent, value); }
158 public event EventHandler ModeChanged {
159 add { Events.AddHandler (ModeChangedEvent, value); }
160 remove { Events.RemoveHandler (ModeChangedEvent, value); }
163 public event FormViewUpdatedEventHandler ItemUpdated {
164 add { Events.AddHandler (ItemUpdatedEvent, value); }
165 remove { Events.RemoveHandler (ItemUpdatedEvent, value); }
168 public event FormViewUpdateEventHandler ItemUpdating {
169 add { Events.AddHandler (ItemUpdatingEvent, value); }
170 remove { Events.RemoveHandler (ItemUpdatingEvent, value); }
173 protected virtual void OnPageIndexChanged (EventArgs e)
175 if (Events != null) {
176 EventHandler eh = (EventHandler) Events [PageIndexChangedEvent];
177 if (eh != null) eh (this, e);
181 protected virtual void OnPageIndexChanging (FormViewPageEventArgs e)
183 if (Events != null) {
184 FormViewPageEventHandler eh = (FormViewPageEventHandler) Events [PageIndexChangingEvent];
185 if (eh != null) eh (this, e);
189 protected virtual void OnItemCommand (FormViewCommandEventArgs e)
191 if (Events != null) {
192 FormViewCommandEventHandler eh = (FormViewCommandEventHandler) Events [ItemCommandEvent];
193 if (eh != null) eh (this, e);
197 protected virtual void OnItemCreated (EventArgs e)
199 if (Events != null) {
200 EventHandler eh = (EventHandler) Events [ItemCreatedEvent];
201 if (eh != null) eh (this, e);
205 protected virtual void OnItemDeleted (FormViewDeletedEventArgs e)
207 if (Events != null) {
208 FormViewDeletedEventHandler eh = (FormViewDeletedEventHandler) Events [ItemDeletedEvent];
209 if (eh != null) eh (this, e);
213 protected virtual void OnItemInserted (FormViewInsertedEventArgs e)
215 if (Events != null) {
216 FormViewInsertedEventHandler eh = (FormViewInsertedEventHandler) Events [ItemInsertedEvent];
217 if (eh != null) eh (this, e);
221 protected virtual void OnItemInserting (FormViewInsertEventArgs e)
223 if (Events != null) {
224 FormViewInsertEventHandler eh = (FormViewInsertEventHandler) Events [ItemInsertingEvent];
225 if (eh != null) eh (this, e);
229 protected virtual void OnItemDeleting (FormViewDeleteEventArgs e)
231 if (Events != null) {
232 FormViewDeleteEventHandler eh = (FormViewDeleteEventHandler) Events [ItemDeletingEvent];
233 if (eh != null) eh (this, e);
237 protected virtual void OnModeChanged (EventArgs e)
239 if (Events != null) {
240 EventHandler eh = (EventHandler) Events [ModeChangedEvent];
241 if (eh != null) eh (this, e);
245 protected virtual void OnModeChanging (FormViewModeEventArgs e)
247 if (Events != null) {
248 FormViewModeEventHandler eh = (FormViewModeEventHandler) Events [ModeChangingEvent];
249 if (eh != null) eh (this, e);
253 protected virtual void OnItemUpdated (FormViewUpdatedEventArgs e)
255 if (Events != null) {
256 FormViewUpdatedEventHandler eh = (FormViewUpdatedEventHandler) Events [ItemUpdatedEvent];
257 if (eh != null) eh (this, e);
261 protected virtual void OnItemUpdating (FormViewUpdateEventArgs e)
263 if (Events != null) {
264 FormViewUpdateEventHandler eh = (FormViewUpdateEventHandler) Events [ItemUpdatingEvent];
265 if (eh != null) eh (this, e);
270 [WebCategoryAttribute ("Paging")]
271 [DefaultValueAttribute (false)]
272 public virtual bool AllowPaging {
274 object ob = ViewState ["AllowPaging"];
275 if (ob != null) return (bool) ob;
279 ViewState ["AllowPaging"] = value;
284 [UrlPropertyAttribute]
285 [WebCategoryAttribute ("Appearance")]
286 [DefaultValueAttribute ("")]
287 [EditorAttribute ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
288 public virtual string BackImageUrl {
290 if (ControlStyleCreated)
291 return ((TableStyle) ControlStyle).BackImageUrl;
295 ((TableStyle) ControlStyle).BackImageUrl = value;
299 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
300 [BrowsableAttribute (false)]
301 public virtual FormViewRow BottomPagerRow {
304 return bottomPagerRow;
308 [WebCategoryAttribute ("Accessibility")]
309 [DefaultValueAttribute ("")]
310 [LocalizableAttribute (true)]
311 public virtual string Caption {
313 object ob = ViewState ["Caption"];
314 if (ob != null) return (string) ob;
318 ViewState ["Caption"] = value;
323 [WebCategoryAttribute ("Accessibility")]
324 [DefaultValueAttribute (TableCaptionAlign.NotSet)]
325 public virtual TableCaptionAlign CaptionAlign
328 object o = ViewState ["CaptionAlign"];
329 if(o != null) return (TableCaptionAlign) o;
330 return TableCaptionAlign.NotSet;
333 ViewState ["CaptionAlign"] = value;
338 [WebCategoryAttribute ("Layout")]
339 [DefaultValueAttribute (-1)]
340 public virtual int CellPadding
343 if (ControlStyleCreated)
344 return ((TableStyle) ControlStyle).CellPadding;
348 ((TableStyle) ControlStyle).CellPadding = value;
352 [WebCategoryAttribute ("Layout")]
353 [DefaultValueAttribute (0)]
354 public virtual int CellSpacing
357 if (ControlStyleCreated)
358 return ((TableStyle) ControlStyle).CellSpacing;
362 ((TableStyle) ControlStyle).CellSpacing = value;
366 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
367 [BrowsableAttribute (false)]
368 public FormViewMode CurrentMode {
370 return hasCurrentMode ? currentMode : DefaultMode;
373 hasCurrentMode = true;
378 FormViewMode defaultMode;
380 [DefaultValueAttribute (FormViewMode.ReadOnly)]
381 [WebCategoryAttribute ("Behavior")]
382 public virtual FormViewMode DefaultMode {
392 string[] dataKeyNames;
393 [DefaultValueAttribute (null)]
394 [WebCategoryAttribute ("Data")]
395 [TypeConverter (typeof(StringArrayConverter))]
396 [EditorAttribute ("System.Web.UI.Design.WebControls.DataFieldEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
397 public virtual string[] DataKeyNames
400 if (dataKeyNames == null)
405 dataKeyNames = value;
410 [BrowsableAttribute (false)]
411 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
412 public virtual DataKey DataKey {
419 [DefaultValue (null)]
420 [TemplateContainer (typeof(FormView), BindingDirection.TwoWay)]
421 [PersistenceMode (PersistenceMode.InnerProperty)]
423 public virtual ITemplate EditItemTemplate {
424 get { return editItemTemplate; }
425 set { editItemTemplate = value; RequireBinding (); }
428 [WebCategoryAttribute ("Styles")]
429 [PersistenceMode (PersistenceMode.InnerProperty)]
430 [NotifyParentProperty (true)]
431 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
432 [DefaultValueAttribute (null)]
433 public TableItemStyle EditRowStyle {
435 if (editRowStyle == null) {
436 editRowStyle = new TableItemStyle ();
437 if (IsTrackingViewState)
438 editRowStyle.TrackViewState();
444 [WebCategoryAttribute ("Styles")]
445 [PersistenceMode (PersistenceMode.InnerProperty)]
446 [NotifyParentProperty (true)]
447 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
448 [DefaultValueAttribute (null)]
449 public TableItemStyle EmptyDataRowStyle {
451 if (emptyDataRowStyle == null) {
452 emptyDataRowStyle = new TableItemStyle ();
453 if (IsTrackingViewState)
454 emptyDataRowStyle.TrackViewState();
456 return emptyDataRowStyle;
460 [DefaultValue (null)]
461 [TemplateContainer (typeof(FormView), BindingDirection.OneWay)]
462 [PersistenceMode (PersistenceMode.InnerProperty)]
464 public virtual ITemplate EmptyDataTemplate {
465 get { return emptyDataTemplate; }
466 set { emptyDataTemplate = value; RequireBinding (); }
469 [LocalizableAttribute (true)]
470 [WebCategoryAttribute ("Appearance")]
471 [DefaultValueAttribute ("")]
472 public virtual string EmptyDataText {
474 object ob = ViewState ["EmptyDataText"];
475 if (ob != null) return (string) ob;
479 ViewState ["EmptyDataText"] = value;
484 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
485 [BrowsableAttribute (false)]
486 public virtual FormViewRow FooterRow {
488 EnsureChildControls ();
493 [DefaultValue (null)]
494 [TemplateContainer (typeof(FormView), BindingDirection.OneWay)]
495 [PersistenceMode (PersistenceMode.InnerProperty)]
497 public virtual ITemplate FooterTemplate {
498 get { return footerTemplate; }
499 set { footerTemplate = value; RequireBinding (); }
502 [LocalizableAttribute (true)]
503 [WebCategoryAttribute ("Appearance")]
504 [DefaultValueAttribute ("")]
505 public virtual string FooterText {
507 object ob = ViewState ["FooterText"];
508 if (ob != null) return (string) ob;
512 ViewState ["FooterText"] = value;
517 [WebCategoryAttribute ("Styles")]
518 [PersistenceMode (PersistenceMode.InnerProperty)]
519 [NotifyParentProperty (true)]
520 [DefaultValue (null)]
521 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
522 public TableItemStyle FooterStyle {
524 if (footerStyle == null) {
525 footerStyle = new TableItemStyle ();
526 if (IsTrackingViewState)
527 footerStyle.TrackViewState();
533 [WebCategoryAttribute ("Appearance")]
534 [DefaultValueAttribute (GridLines.None)]
535 public virtual GridLines GridLines {
537 if (ControlStyleCreated)
538 return ((TableStyle) ControlStyle).GridLines;
539 return GridLines.None;
542 ((TableStyle) ControlStyle).GridLines = value;
546 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
547 [BrowsableAttribute (false)]
548 public virtual FormViewRow HeaderRow {
550 EnsureChildControls ();
555 [WebCategoryAttribute ("Styles")]
556 [PersistenceMode (PersistenceMode.InnerProperty)]
557 [NotifyParentProperty (true)]
558 [DefaultValue (null)]
559 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
560 public TableItemStyle HeaderStyle {
562 if (headerStyle == null) {
563 headerStyle = new TableItemStyle ();
564 if (IsTrackingViewState)
565 headerStyle.TrackViewState();
571 [DefaultValue (null)]
572 [TemplateContainer (typeof(FormView), BindingDirection.OneWay)]
573 [PersistenceMode (PersistenceMode.InnerProperty)]
575 public virtual ITemplate HeaderTemplate {
576 get { return headerTemplate; }
577 set { headerTemplate = value; RequireBinding (); }
580 [LocalizableAttribute (true)]
581 [WebCategoryAttribute ("Appearance")]
582 [DefaultValueAttribute ("")]
583 public virtual string HeaderText {
585 object ob = ViewState ["HeaderText"];
586 if (ob != null) return (string) ob;
590 ViewState ["HeaderText"] = value;
595 [Category ("Layout")]
596 [DefaultValueAttribute (HorizontalAlign.NotSet)]
597 public virtual HorizontalAlign HorizontalAlign {
599 if (ControlStyleCreated)
600 return ((TableStyle) ControlStyle).HorizontalAlign;
601 return HorizontalAlign.NotSet;
604 ((TableStyle) ControlStyle).HorizontalAlign = value;
608 [DefaultValue (null)]
609 [TemplateContainer (typeof(FormView), BindingDirection.TwoWay)]
610 [PersistenceMode (PersistenceMode.InnerProperty)]
612 public virtual ITemplate InsertItemTemplate {
613 get { return insertItemTemplate; }
614 set { insertItemTemplate = value; RequireBinding (); }
617 [WebCategoryAttribute ("Styles")]
618 [PersistenceMode (PersistenceMode.InnerProperty)]
619 [NotifyParentProperty (true)]
620 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
621 [DefaultValueAttribute (null)]
622 public TableItemStyle InsertRowStyle {
624 if (insertRowStyle == null) {
625 insertRowStyle = new TableItemStyle ();
626 if (IsTrackingViewState)
627 insertRowStyle.TrackViewState();
629 return insertRowStyle;
633 [DefaultValue (null)]
634 [TemplateContainer (typeof(FormView), BindingDirection.TwoWay)]
635 [PersistenceMode (PersistenceMode.InnerProperty)]
637 public virtual ITemplate ItemTemplate {
638 get { return itemTemplate; }
639 set { itemTemplate = value; RequireBinding (); }
642 [BrowsableAttribute (false)]
643 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
644 public virtual int PageCount {
646 if (pageCount != 0) return pageCount;
652 [WebCategoryAttribute ("Paging")]
653 [BindableAttribute (true, BindingDirection.OneWay)]
654 [DefaultValueAttribute (0)]
655 public virtual int PageIndex {
660 if (pageIndex == value)
667 [WebCategoryAttribute ("Paging")]
668 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Content)]
669 [NotifyParentPropertyAttribute (true)]
670 [PersistenceModeAttribute (PersistenceMode.InnerProperty)]
671 public virtual PagerSettings PagerSettings {
673 if (pagerSettings == null) {
674 pagerSettings = new PagerSettings (this);
675 if (IsTrackingViewState)
676 ((IStateManager)pagerSettings).TrackViewState ();
678 return pagerSettings;
682 [WebCategoryAttribute ("Styles")]
683 [PersistenceMode (PersistenceMode.InnerProperty)]
684 [NotifyParentProperty (true)]
685 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
686 public TableItemStyle PagerStyle {
688 if (pagerStyle == null) {
689 pagerStyle = new TableItemStyle ();
690 if (IsTrackingViewState)
691 pagerStyle.TrackViewState();
698 [DefaultValue (null)]
699 /* DataControlPagerCell isnt specified in the docs */
700 //[TemplateContainer (typeof(DataControlPagerCell), BindingDirection.OneWay)]
701 [PersistenceMode (PersistenceMode.InnerProperty)]
703 public virtual ITemplate PagerTemplate {
704 get { return pagerTemplate; }
705 set { pagerTemplate = value; RequireBinding (); }
708 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
709 [BrowsableAttribute (false)]
710 public virtual FormViewRow Row {
717 [WebCategoryAttribute ("Styles")]
718 [PersistenceMode (PersistenceMode.InnerProperty)]
719 [NotifyParentProperty (true)]
720 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
721 [DefaultValue (null)]
722 public TableItemStyle RowStyle {
724 if (rowStyle == null) {
725 rowStyle = new TableItemStyle ();
726 if (IsTrackingViewState)
727 rowStyle.TrackViewState();
733 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
734 [BrowsableAttribute (false)]
735 public object SelectedValue {
736 get { return DataKey.Value; }
739 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
740 [BrowsableAttribute (false)]
741 public virtual FormViewRow TopPagerRow {
748 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
749 [BrowsableAttribute (false)]
750 public virtual object DataItem {
757 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
758 [BrowsableAttribute (false)]
759 public int DataItemCount {
760 get { return PageCount; }
763 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
764 [BrowsableAttribute (false)]
765 public virtual int DataItemIndex {
766 get { return PageIndex; }
769 int IDataItemContainer.DataItemIndex {
770 get { return DataItemIndex; }
773 int IDataItemContainer.DisplayIndex {
774 get { return PageIndex; }
777 public virtual bool IsBindableType (Type type)
779 return type.IsPrimitive || type == typeof (string) || type == typeof (DateTime) || type == typeof (Guid) || type == typeof (Decimal);
782 protected override DataSourceSelectArguments CreateDataSourceSelectArguments ()
784 return base.CreateDataSourceSelectArguments ();
787 protected virtual FormViewRow CreateRow (int rowIndex, DataControlRowType rowType, DataControlRowState rowState)
789 FormViewRow row = new FormViewRow (rowIndex, rowType, rowState);
790 OnItemCreated (EventArgs.Empty);
794 void RequireBinding ()
798 RequiresDataBinding = true;
802 protected virtual Table CreateTable ()
804 return new ContainedTable (this);
808 protected override void EnsureDataBound ()
810 base.EnsureDataBound ();
813 protected override Style CreateControlStyle ()
815 TableStyle style = new TableStyle (ViewState);
816 style.CellSpacing = 0;
820 protected override int CreateChildControls (IEnumerable data, bool dataBinding)
822 PagedDataSource dataSource = new PagedDataSource ();
823 dataSource.DataSource = data;
824 dataSource.AllowPaging = AllowPaging;
825 dataSource.PageSize = 1;
826 dataSource.CurrentPageIndex = PageIndex;
829 DataSourceView view = GetData ();
830 if (view != null && view.CanPage) {
831 dataSource.AllowServerPaging = true;
832 if (view.CanRetrieveTotalRowCount)
833 dataSource.VirtualCount = SelectArguments.TotalRowCount;
837 pageCount = dataSource.DataSourceCount;
838 bool showPager = AllowPaging && (pageCount > 1);
841 table = CreateTable ();
842 Controls.Add (table);
844 // Gets the current data item
846 IEnumerator e = dataSource.GetEnumerator ();
851 dataItem = e.Current;
854 for (int page = 0; e.MoveNext (); page++ )
855 if (page == PageIndex)
856 dataItem = e.Current;
858 // Main table creation
860 if (HeaderText.Length != 0 || headerTemplate != null) {
861 headerRow = CreateRow (-1, DataControlRowType.Header, DataControlRowState.Normal);
862 InitializeRow (headerRow);
863 table.Rows.Add (headerRow);
866 if (showPager && PagerSettings.Position == PagerPosition.Top || PagerSettings.Position == PagerPosition.TopAndBottom) {
867 topPagerRow = CreateRow (-1, DataControlRowType.Pager, DataControlRowState.Normal);
868 InitializePager (topPagerRow, dataSource);
869 table.Rows.Add (topPagerRow);
873 DataControlRowState rstate = GetRowState ();
874 itemRow = CreateRow (0, DataControlRowType.DataRow, rstate);
875 InitializeRow (itemRow);
876 table.Rows.Add (itemRow);
879 if (CurrentMode == FormViewMode.Edit)
880 oldEditValues = new DataKey (new OrderedDictionary ());
881 key = new DataKey (new OrderedDictionary (), DataKeyNames);
884 switch (CurrentMode) {
885 case FormViewMode.Edit:
886 itemRow = CreateRow (-1, DataControlRowType.EmptyDataRow, DataControlRowState.Edit);
888 case FormViewMode.Insert:
889 itemRow = CreateRow (-1, DataControlRowType.DataRow, DataControlRowState.Insert);
892 itemRow = CreateRow (-1, DataControlRowType.EmptyDataRow, DataControlRowState.Normal);
895 table.Rows.Add (itemRow);
896 InitializeRow (itemRow);
899 if (showPager && PagerSettings.Position == PagerPosition.Bottom || PagerSettings.Position == PagerPosition.TopAndBottom) {
900 bottomPagerRow = CreateRow (0, DataControlRowType.Pager, DataControlRowState.Normal);
901 InitializePager (bottomPagerRow, dataSource);
902 table.Rows.Add (bottomPagerRow);
905 if (FooterText.Length != 0 || footerTemplate != null) {
906 footerRow = CreateRow (-1, DataControlRowType.Footer, DataControlRowState.Normal);
907 InitializeRow (footerRow);
908 table.Rows.Add (footerRow);
914 return dataSource.DataSourceCount;
917 DataControlRowState GetRowState ()
919 DataControlRowState rstate = DataControlRowState.Normal;
920 if (CurrentMode == FormViewMode.Edit) rstate |= DataControlRowState.Edit;
921 else if (CurrentMode == FormViewMode.Insert) rstate |= DataControlRowState.Insert;
925 protected virtual void InitializePager (FormViewRow row, PagedDataSource dataSource)
927 TableCell cell = new TableCell ();
930 if (pagerTemplate != null)
931 pagerTemplate.InstantiateIn (cell);
933 cell.Controls.Add (PagerSettings.CreatePagerControl (dataSource.CurrentPageIndex, dataSource.PageCount));
935 row.Cells.Add (cell);
938 protected virtual void InitializeRow (FormViewRow row)
940 TableCell cell = new TableCell ();
942 if (row.RowType == DataControlRowType.DataRow)
944 if ((row.RowState & DataControlRowState.Edit) != 0) {
945 if (editItemTemplate != null)
946 editItemTemplate.InstantiateIn (cell);
947 } else if ((row.RowState & DataControlRowState.Insert) != 0) {
948 if (insertItemTemplate != null)
949 insertItemTemplate.InstantiateIn (cell);
950 } else if (itemTemplate != null)
951 itemTemplate.InstantiateIn (cell);
953 else if (row.RowType == DataControlRowType.EmptyDataRow)
955 if (emptyDataTemplate != null)
956 emptyDataTemplate.InstantiateIn (cell);
958 cell.Text = EmptyDataText;
960 else if (row.RowType == DataControlRowType.Footer)
962 if (footerTemplate != null)
963 footerTemplate.InstantiateIn (cell);
965 cell.Text = FooterText;
967 else if (row.RowType == DataControlRowType.Header)
969 if (headerTemplate != null)
970 headerTemplate.InstantiateIn (cell);
972 cell.Text = HeaderText;
975 row.Cells.Add (cell);
978 IOrderedDictionary CreateRowDataKey (object dataItem)
980 if (cachedKeyProperties == null) {
981 PropertyDescriptorCollection props = TypeDescriptor.GetProperties (dataItem);
982 cachedKeyProperties = new PropertyDescriptor [DataKeyNames.Length];
983 for (int n=0; n<DataKeyNames.Length; n++) {
984 PropertyDescriptor p = props [DataKeyNames[n]];
986 new InvalidOperationException ("Property '" + DataKeyNames[n] + "' not found in object of type " + dataItem.GetType());
987 cachedKeyProperties [n] = p;
991 OrderedDictionary dic = new OrderedDictionary ();
992 foreach (PropertyDescriptor p in cachedKeyProperties)
993 dic [p.Name] = p.GetValue (dataItem);
997 IOrderedDictionary GetRowValues (bool includePrimaryKey)
999 OrderedDictionary dic = new OrderedDictionary ();
1000 ExtractRowValues (dic, includePrimaryKey);
1004 protected virtual void ExtractRowValues (IOrderedDictionary fieldValues, bool includeKeys)
1009 DataControlRowState rowState = Row.RowState;
1010 IBindableTemplate bt;
1012 if ((rowState & DataControlRowState.Insert) != 0)
1013 bt = insertItemTemplate as IBindableTemplate;
1014 else if ((rowState & DataControlRowState.Edit) != 0)
1015 bt = editItemTemplate as IBindableTemplate;
1020 IOrderedDictionary values = bt.ExtractValues (Row.Cells [0]);
1021 foreach (DictionaryEntry e in values) {
1022 if (includeKeys || Array.IndexOf (DataKeyNames, e.Key) == -1)
1023 fieldValues [e.Key] = e.Value;
1028 protected override HtmlTextWriterTag TagKey {
1030 return HtmlTextWriterTag.Table;
1034 public sealed override void DataBind ()
1036 if (CurrentMode == FormViewMode.Insert) {
1037 RequiresDataBinding = false;
1038 PerformDataBinding (new object [] { null });
1042 DataSourceView view = GetData ();
1043 if (AllowPaging && view.CanPage) {
1044 SelectArguments.StartRowIndex = PageIndex;
1045 SelectArguments.MaximumRows = 1;
1046 if (view.CanRetrieveTotalRowCount)
1047 SelectArguments.RetrieveTotalRowCount = true;
1050 cachedKeyProperties = null;
1053 if (pageCount > 0) {
1054 if (CurrentMode == FormViewMode.Edit)
1055 oldEditValues = new DataKey (GetRowValues (true));
1057 oldEditValues = new DataKey (new OrderedDictionary ());
1058 key = new DataKey (CreateRowDataKey (dataItem), DataKeyNames);
1062 protected internal override void PerformDataBinding (IEnumerable data)
1064 base.PerformDataBinding (data);
1067 protected internal virtual void PrepareControlHierarchy ()
1072 table.Caption = Caption;
1073 table.CaptionAlign = CaptionAlign;
1075 foreach (FormViewRow row in table.Rows) {
1076 switch (row.RowType) {
1077 case DataControlRowType.Header:
1078 if (headerStyle != null && !headerStyle.IsEmpty)
1079 row.ControlStyle.CopyFrom (headerStyle);
1081 case DataControlRowType.Footer:
1082 if (footerStyle != null && !footerStyle.IsEmpty)
1083 row.ControlStyle.CopyFrom (footerStyle);
1085 case DataControlRowType.Pager:
1086 if (pagerStyle != null && !pagerStyle.IsEmpty)
1087 row.ControlStyle.CopyFrom (pagerStyle);
1089 case DataControlRowType.EmptyDataRow:
1090 if (emptyDataRowStyle != null && !emptyDataRowStyle.IsEmpty)
1091 row.ControlStyle.CopyFrom (emptyDataRowStyle);
1093 case DataControlRowType.DataRow:
1094 if (rowStyle != null && !rowStyle.IsEmpty)
1095 row.ControlStyle.CopyFrom (rowStyle);
1096 if ((row.RowState & (DataControlRowState.Edit | DataControlRowState.Insert)) != 0 && editRowStyle != null && !editRowStyle.IsEmpty)
1097 row.ControlStyle.CopyFrom (editRowStyle);
1098 if ((row.RowState & DataControlRowState.Insert) != 0 && insertRowStyle != null && !insertRowStyle.IsEmpty)
1099 row.ControlStyle.CopyFrom (insertRowStyle);
1107 protected internal override void OnInit (EventArgs e)
1109 Page.RegisterRequiresControlState (this);
1113 protected override bool OnBubbleEvent (object source, EventArgs e)
1115 FormViewCommandEventArgs args = e as FormViewCommandEventArgs;
1117 OnItemCommand (args);
1118 ProcessEvent (args.CommandName, args.CommandArgument as string);
1120 return base.OnBubbleEvent (source, e);
1123 void IPostBackEventHandler.RaisePostBackEvent(string eventArgument)
1125 RaisePostBackEvent (eventArgument);
1128 protected virtual void RaisePostBackEvent (string eventArgument)
1130 int i = eventArgument.IndexOf ('$');
1132 ProcessEvent (eventArgument.Substring (0, i), eventArgument.Substring (i + 1));
1134 ProcessEvent (eventArgument, null);
1137 void ProcessEvent (string eventName, string param)
1141 case DataControlCommands.PageCommandName:
1144 case DataControlCommands.FirstPageCommandArgument:
1147 case DataControlCommands.LastPageCommandArgument:
1148 newIndex = PageCount - 1;
1150 case DataControlCommands.NextPageCommandArgument:
1151 newIndex = PageIndex + 1;
1153 case DataControlCommands.PreviousPageCommandArgument:
1154 newIndex = PageIndex - 1;
1158 int.TryParse (param, out paramIndex);
1159 newIndex = paramIndex - 1;
1162 ShowPage (newIndex);
1165 case DataControlCommands.FirstPageCommandArgument:
1169 case DataControlCommands.LastPageCommandArgument:
1170 ShowPage (PageCount - 1);
1173 case DataControlCommands.NextPageCommandArgument:
1174 if (PageIndex < PageCount - 1)
1175 ShowPage (PageIndex + 1);
1178 case DataControlCommands.PreviousPageCommandArgument:
1180 ShowPage (PageIndex - 1);
1183 case DataControlCommands.EditCommandName:
1184 ChangeMode (FormViewMode.Edit);
1187 case DataControlCommands.NewCommandName:
1188 ChangeMode (FormViewMode.Insert);
1191 case DataControlCommands.UpdateCommandName:
1192 UpdateItem (param, true);
1195 case DataControlCommands.CancelCommandName:
1199 case DataControlCommands.DeleteCommandName:
1203 case DataControlCommands.InsertCommandName:
1209 void ShowPage (int newIndex)
1211 FormViewPageEventArgs args = new FormViewPageEventArgs (newIndex);
1212 OnPageIndexChanging (args);
1214 newIndex = args.NewPageIndex;
1215 if (newIndex < 0 || newIndex >= PageCount)
1218 PageIndex = newIndex;
1219 OnPageIndexChanged (EventArgs.Empty);
1223 public void ChangeMode (FormViewMode newMode)
1225 FormViewModeEventArgs args = new FormViewModeEventArgs (newMode, false);
1226 OnModeChanging (args);
1228 CurrentMode = args.NewMode;
1229 OnModeChanged (EventArgs.Empty);
1236 FormViewModeEventArgs args = new FormViewModeEventArgs (FormViewMode.ReadOnly, true);
1237 OnModeChanging (args);
1243 public virtual void UpdateItem (bool causesValidation)
1245 UpdateItem (null, causesValidation);
1248 void UpdateItem (string param, bool causesValidation)
1250 if (causesValidation)
1253 if (CurrentMode != FormViewMode.Edit) throw new NotSupportedException ();
1255 currentEditOldValues = oldEditValues.Values;
1256 currentEditRowKeys = DataKey.Values;
1257 currentEditNewValues = GetRowValues (false);
1259 FormViewUpdateEventArgs args = new FormViewUpdateEventArgs (param, currentEditRowKeys, currentEditOldValues, currentEditNewValues);
1260 OnItemUpdating (args);
1262 DataSourceView view = GetData ();
1264 throw new HttpException ("The DataSourceView associated to data bound control was null");
1266 view.Update (currentEditRowKeys, currentEditNewValues, currentEditOldValues, new DataSourceViewOperationCallback (UpdateCallback));
1272 bool UpdateCallback (int recordsAffected, Exception exception)
1274 FormViewUpdatedEventArgs dargs = new FormViewUpdatedEventArgs (recordsAffected, exception, currentEditRowKeys, currentEditOldValues, currentEditNewValues);
1275 OnItemUpdated (dargs);
1277 if (!dargs.KeepInEditMode)
1280 return dargs.ExceptionHandled;
1283 public virtual void InsertItem (bool causesValidation)
1285 InsertItem (null, causesValidation);
1288 void InsertItem (string param, bool causesValidation)
1290 if (causesValidation)
1293 if (CurrentMode != FormViewMode.Insert) throw new NotSupportedException ();
1295 currentEditNewValues = GetRowValues (true);
1296 FormViewInsertEventArgs args = new FormViewInsertEventArgs (param, currentEditNewValues);
1297 OnItemInserting (args);
1299 DataSourceView view = GetData ();
1301 throw new HttpException ("The DataSourceView associated to data bound control was null");
1303 view.Insert (currentEditNewValues, new DataSourceViewOperationCallback (InsertCallback));
1309 bool InsertCallback (int recordsAffected, Exception exception)
1311 FormViewInsertedEventArgs dargs = new FormViewInsertedEventArgs (recordsAffected, exception, currentEditNewValues);
1312 OnItemInserted (dargs);
1314 if (!dargs.KeepInInsertMode)
1317 return dargs.ExceptionHandled;
1320 public virtual void DeleteItem ()
1322 currentEditRowKeys = DataKey.Values;
1323 currentEditNewValues = GetRowValues (true);
1325 FormViewDeleteEventArgs args = new FormViewDeleteEventArgs (PageIndex, currentEditRowKeys, currentEditNewValues);
1326 OnItemDeleting (args);
1329 if (PageIndex == PageCount - 1)
1334 DataSourceView view = GetData ();
1335 if (view != null && view.CanDelete)
1336 view.Delete (currentEditRowKeys, currentEditNewValues, new DataSourceViewOperationCallback (DeleteCallback));
1338 FormViewDeletedEventArgs dargs = new FormViewDeletedEventArgs (0, null, currentEditRowKeys, currentEditNewValues);
1339 OnItemDeleted (dargs);
1344 bool DeleteCallback (int recordsAffected, Exception exception)
1346 FormViewDeletedEventArgs dargs = new FormViewDeletedEventArgs (recordsAffected, exception, currentEditRowKeys, currentEditNewValues);
1347 OnItemDeleted (dargs);
1348 return dargs.ExceptionHandled;
1356 void EndRowEdit (bool switchToDefaultMode)
1358 if (switchToDefaultMode)
1359 ChangeMode (DefaultMode);
1360 oldEditValues = new DataKey (new OrderedDictionary ());
1361 currentEditRowKeys = null;
1362 currentEditOldValues = null;
1363 currentEditNewValues = null;
1367 protected internal override void LoadControlState (object ob)
1369 if (ob == null) return;
1370 object[] state = (object[]) ob;
1371 base.LoadControlState (state[0]);
1372 pageIndex = (int) state[1];
1373 pageCount = (int) state[2];
1374 CurrentMode = (FormViewMode) state[3];
1375 defaultMode = (FormViewMode) state[4];
1376 dataKeyNames = (string[]) state[5];
1379 protected internal override object SaveControlState ()
1381 object bstate = base.SaveControlState ();
1382 return new object[] {
1383 bstate, pageIndex, pageCount, CurrentMode, defaultMode, dataKeyNames
1387 protected override void TrackViewState()
1389 base.TrackViewState();
1390 if (pagerSettings != null) ((IStateManager)pagerSettings).TrackViewState();
1391 if (footerStyle != null) ((IStateManager)footerStyle).TrackViewState();
1392 if (headerStyle != null) ((IStateManager)headerStyle).TrackViewState();
1393 if (pagerStyle != null) ((IStateManager)pagerStyle).TrackViewState();
1394 if (rowStyle != null) ((IStateManager)rowStyle).TrackViewState();
1395 if (editRowStyle != null) ((IStateManager)editRowStyle).TrackViewState();
1396 if (insertRowStyle != null) ((IStateManager)insertRowStyle).TrackViewState();
1397 if (emptyDataRowStyle != null) ((IStateManager)emptyDataRowStyle).TrackViewState();
1398 if (key != null) ((IStateManager)key).TrackViewState();
1401 protected override object SaveViewState()
1403 object[] states = new object [14];
1404 states[0] = base.SaveViewState();
1405 states[2] = (pagerSettings == null ? null : ((IStateManager)pagerSettings).SaveViewState());
1406 states[4] = (footerStyle == null ? null : ((IStateManager)footerStyle).SaveViewState());
1407 states[5] = (headerStyle == null ? null : ((IStateManager)headerStyle).SaveViewState());
1408 states[6] = (pagerStyle == null ? null : ((IStateManager)pagerStyle).SaveViewState());
1409 states[7] = (rowStyle == null ? null : ((IStateManager)rowStyle).SaveViewState());
1410 states[8] = (insertRowStyle == null ? null : ((IStateManager)insertRowStyle).SaveViewState());
1411 states[9] = (editRowStyle == null ? null : ((IStateManager)editRowStyle).SaveViewState());
1412 states[10] = (emptyDataRowStyle == null ? null : ((IStateManager)emptyDataRowStyle).SaveViewState());
1413 states[11] = (key == null ? null : ((IStateManager)key).SaveViewState());
1414 states[12] = (oldEditValues == null ? null : ((IStateManager)oldEditValues).SaveViewState());
1416 for (int i = states.Length - 1; i >= 0; i--) {
1417 if (states [i] != null)
1424 protected override void LoadViewState (object savedState)
1426 if (savedState == null) {
1427 base.LoadViewState (null);
1431 object [] states = (object []) savedState;
1433 base.LoadViewState (states[0]);
1434 EnsureChildControls ();
1436 if (states[2] != null) ((IStateManager)PagerSettings).LoadViewState (states[2]);
1437 if (states[4] != null) ((IStateManager)FooterStyle).LoadViewState (states[4]);
1438 if (states[5] != null) ((IStateManager)HeaderStyle).LoadViewState (states[5]);
1439 if (states[6] != null) ((IStateManager)PagerStyle).LoadViewState (states[6]);
1440 if (states[7] != null) ((IStateManager)RowStyle).LoadViewState (states[7]);
1441 if (states[8] != null) ((IStateManager)InsertRowStyle).LoadViewState (states[8]);
1442 if (states[9] != null) ((IStateManager)EditRowStyle).LoadViewState (states[9]);
1443 if (states[10] != null) ((IStateManager)EmptyDataRowStyle).LoadViewState (states[10]);
1444 if (states[11] != null && DataKey != null) ((IStateManager)DataKey).LoadViewState (states[11]);
1445 if (states[12] != null && oldEditValues != null) ((IStateManager)oldEditValues).LoadViewState (states[12]);
1448 protected internal override void Render (HtmlTextWriter writer)
1450 PrepareControlHierarchy ();
1455 table.Render (writer);
1458 PostBackOptions IPostBackContainer.GetPostBackOptions (IButtonControl control)
1460 Control ctrl = control as Control;
1461 return new PostBackOptions(ctrl);