2 // System.Web.UI.WebControls.DetailsView.cs
5 // Lluis Sanchez Gual (lluis@novell.com)
7 // (C) 2005-2010 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.
30 using System.Collections;
31 using System.Collections.Specialized;
32 using System.ComponentModel;
34 using System.Security.Permissions;
37 using System.Reflection;
39 namespace System.Web.UI.WebControls
41 [SupportsEventValidation]
42 [ToolboxDataAttribute ("<{0}:DetailsView runat=\"server\" Width=\"125px\" Height=\"50px\"></{0}:DetailsView>")]
43 [DesignerAttribute ("System.Web.UI.Design.WebControls.DetailsViewDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
44 [ControlValuePropertyAttribute ("SelectedValue")]
45 [DefaultEventAttribute ("PageIndexChanging")]
47 [DataKeyProperty ("DataKey")]
49 [AspNetHostingPermissionAttribute (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
50 [AspNetHostingPermissionAttribute (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
51 public class DetailsView: CompositeDataBoundControl, ICallbackEventHandler, ICallbackContainer, IDataItemContainer, INamingContainer, IPostBackEventHandler, IPostBackContainer
53 , IDataBoundItemControl, IDataBoundControl, IFieldControl
59 DetailsViewRowCollection rows;
60 DetailsViewRow headerRow;
61 DetailsViewRow footerRow;
62 DetailsViewRow bottomPagerRow;
63 DetailsViewRow topPagerRow;
65 IOrderedDictionary currentEditRowKeys;
66 IOrderedDictionary currentEditNewValues;
67 IOrderedDictionary currentEditOldValues;
69 ITemplate pagerTemplate;
70 ITemplate emptyDataTemplate;
71 ITemplate headerTemplate;
72 ITemplate footerTemplate;
74 PropertyDescriptor[] cachedKeyProperties;
75 readonly string[] emptyKeys = new string[0];
76 readonly string unhandledEventExceptionMessage = "The DetailsView '{0}' fired event {1} which wasn't handled.";
79 DataControlFieldCollection columns;
80 PagerSettings pagerSettings;
82 TableItemStyle alternatingRowStyle;
83 TableItemStyle editRowStyle;
84 TableItemStyle insertRowStyle;
85 TableItemStyle emptyDataRowStyle;
86 TableItemStyle footerStyle;
87 TableItemStyle headerStyle;
88 TableItemStyle pagerStyle;
89 TableItemStyle rowStyle;
90 TableItemStyle commandRowStyle;
91 TableItemStyle fieldHeaderStyle;
93 IOrderedDictionary _keyTable;
95 DataKey oldEditValues;
96 AutoGeneratedFieldProperties[] autoFieldProperties;
98 static readonly object PageIndexChangedEvent = new object();
99 static readonly object PageIndexChangingEvent = new object();
100 static readonly object ItemCommandEvent = new object();
101 static readonly object ItemCreatedEvent = new object();
102 static readonly object ItemDeletedEvent = new object();
103 static readonly object ItemDeletingEvent = new object();
104 static readonly object ItemInsertedEvent = new object();
105 static readonly object ItemInsertingEvent = new object();
106 static readonly object ModeChangingEvent = new object();
107 static readonly object ModeChangedEvent = new object();
108 static readonly object ItemUpdatedEvent = new object();
109 static readonly object ItemUpdatingEvent = new object();
113 DetailsViewMode currentMode = DetailsViewMode.ReadOnly;
117 public DetailsView ()
119 rows = new DetailsViewRowCollection (new ArrayList ());
122 public event EventHandler PageIndexChanged {
123 add { Events.AddHandler (PageIndexChangedEvent, value); }
124 remove { Events.RemoveHandler (PageIndexChangedEvent, value); }
127 public event DetailsViewPageEventHandler PageIndexChanging {
128 add { Events.AddHandler (PageIndexChangingEvent, value); }
129 remove { Events.RemoveHandler (PageIndexChangingEvent, value); }
132 public event DetailsViewCommandEventHandler ItemCommand {
133 add { Events.AddHandler (ItemCommandEvent, value); }
134 remove { Events.RemoveHandler (ItemCommandEvent, value); }
137 public event EventHandler ItemCreated {
138 add { Events.AddHandler (ItemCreatedEvent, value); }
139 remove { Events.RemoveHandler (ItemCreatedEvent, value); }
142 public event DetailsViewDeletedEventHandler ItemDeleted {
143 add { Events.AddHandler (ItemDeletedEvent, value); }
144 remove { Events.RemoveHandler (ItemDeletedEvent, value); }
147 public event DetailsViewDeleteEventHandler ItemDeleting {
148 add { Events.AddHandler (ItemDeletingEvent, value); }
149 remove { Events.RemoveHandler (ItemDeletingEvent, value); }
152 public event DetailsViewInsertedEventHandler ItemInserted {
153 add { Events.AddHandler (ItemInsertedEvent, value); }
154 remove { Events.RemoveHandler (ItemInsertedEvent, value); }
157 public event DetailsViewInsertEventHandler ItemInserting {
158 add { Events.AddHandler (ItemInsertingEvent, value); }
159 remove { Events.RemoveHandler (ItemInsertingEvent, value); }
162 public event DetailsViewModeEventHandler ModeChanging {
163 add { Events.AddHandler (ModeChangingEvent, value); }
164 remove { Events.RemoveHandler (ModeChangingEvent, value); }
167 public event EventHandler ModeChanged {
168 add { Events.AddHandler (ModeChangedEvent, value); }
169 remove { Events.RemoveHandler (ModeChangedEvent, value); }
172 public event DetailsViewUpdatedEventHandler ItemUpdated {
173 add { Events.AddHandler (ItemUpdatedEvent, value); }
174 remove { Events.RemoveHandler (ItemUpdatedEvent, value); }
177 public event DetailsViewUpdateEventHandler ItemUpdating {
178 add { Events.AddHandler (ItemUpdatingEvent, value); }
179 remove { Events.RemoveHandler (ItemUpdatingEvent, value); }
182 protected virtual void OnPageIndexChanged (EventArgs e)
184 if (Events != null) {
185 EventHandler eh = (EventHandler) Events [PageIndexChangedEvent];
186 if (eh != null) eh (this, e);
190 protected virtual void OnPageIndexChanging (DetailsViewPageEventArgs e)
192 if (Events != null) {
193 DetailsViewPageEventHandler eh = (DetailsViewPageEventHandler) Events [PageIndexChangingEvent];
199 if (!IsBoundUsingDataSourceID)
200 throw new HttpException (String.Format (unhandledEventExceptionMessage, ID, "PageIndexChanging"));
203 protected virtual void OnItemCommand (DetailsViewCommandEventArgs e)
205 if (Events != null) {
206 DetailsViewCommandEventHandler eh = (DetailsViewCommandEventHandler) Events [ItemCommandEvent];
207 if (eh != null) eh (this, e);
211 protected virtual void OnItemCreated (EventArgs e)
213 if (Events != null) {
214 EventHandler eh = (EventHandler) Events [ItemCreatedEvent];
215 if (eh != null) eh (this, e);
219 protected virtual void OnItemDeleted (DetailsViewDeletedEventArgs e)
221 if (Events != null) {
222 DetailsViewDeletedEventHandler eh = (DetailsViewDeletedEventHandler) Events [ItemDeletedEvent];
223 if (eh != null) eh (this, e);
227 protected virtual void OnItemInserted (DetailsViewInsertedEventArgs e)
229 if (Events != null) {
230 DetailsViewInsertedEventHandler eh = (DetailsViewInsertedEventHandler) Events [ItemInsertedEvent];
231 if (eh != null) eh (this, e);
235 protected virtual void OnItemInserting (DetailsViewInsertEventArgs e)
237 if (Events != null) {
238 DetailsViewInsertEventHandler eh = (DetailsViewInsertEventHandler) Events [ItemInsertingEvent];
244 if (!IsBoundUsingDataSourceID)
245 throw new HttpException (String.Format (unhandledEventExceptionMessage, ID, "ItemInserting"));
248 protected virtual void OnItemDeleting (DetailsViewDeleteEventArgs e)
250 if (Events != null) {
251 DetailsViewDeleteEventHandler eh = (DetailsViewDeleteEventHandler) Events [ItemDeletingEvent];
257 if (!IsBoundUsingDataSourceID)
258 throw new HttpException (String.Format (unhandledEventExceptionMessage, ID, "ItemDeleting"));
261 protected virtual void OnModeChanged (EventArgs e)
263 if (Events != null) {
264 EventHandler eh = (EventHandler) Events [ModeChangedEvent];
265 if (eh != null) eh (this, e);
269 protected virtual void OnModeChanging (DetailsViewModeEventArgs e)
271 if (Events != null) {
272 DetailsViewModeEventHandler eh = (DetailsViewModeEventHandler) Events [ModeChangingEvent];
278 if (!IsBoundUsingDataSourceID)
279 throw new HttpException (String.Format (unhandledEventExceptionMessage, ID, "ModeChanging"));
282 protected virtual void OnItemUpdated (DetailsViewUpdatedEventArgs e)
284 if (Events != null) {
285 DetailsViewUpdatedEventHandler eh = (DetailsViewUpdatedEventHandler) Events [ItemUpdatedEvent];
286 if (eh != null) eh (this, e);
290 protected virtual void OnItemUpdating (DetailsViewUpdateEventArgs e)
292 if (Events != null) {
293 DetailsViewUpdateEventHandler eh = (DetailsViewUpdateEventHandler) Events [ItemUpdatingEvent];
299 if (!IsBoundUsingDataSourceID)
300 throw new HttpException (String.Format (unhandledEventExceptionMessage, ID, "ItemUpdating"));
304 DataBoundControlMode IDataBoundItemControl.Mode {
306 switch (CurrentMode) {
307 case DetailsViewMode.ReadOnly:
308 return DataBoundControlMode.ReadOnly;
310 case DetailsViewMode.Edit:
311 return DataBoundControlMode.Edit;
313 case DetailsViewMode.Insert:
314 return DataBoundControlMode.Insert;
317 throw new InvalidOperationException (String.Format ("Unsupported CurrentMode value '{0}'", CurrentMode));
322 IDataSource IDataBoundControl.DataSourceObject {
323 get { return base.DataSourceObject; }
326 IAutoFieldGenerator IFieldControl.FieldsGenerator {
328 throw new NotImplementedException ();
332 throw new NotImplementedException ();
336 [WebCategoryAttribute ("Paging")]
337 [DefaultValueAttribute (false)]
338 public virtual bool AllowPaging {
340 object ob = ViewState ["AllowPaging"];
346 ViewState ["AllowPaging"] = value;
351 [DefaultValueAttribute (null)]
352 [WebCategoryAttribute ("Styles")]
353 [PersistenceMode (PersistenceMode.InnerProperty)]
354 [NotifyParentProperty (true)]
355 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
356 public TableItemStyle AlternatingRowStyle {
358 if (alternatingRowStyle == null) {
359 alternatingRowStyle = new TableItemStyle ();
360 if (IsTrackingViewState)
361 alternatingRowStyle.TrackViewState();
363 return alternatingRowStyle;
367 [WebCategoryAttribute ("Behavior")]
368 [DefaultValueAttribute (false)]
369 public virtual bool AutoGenerateEditButton {
371 object ob = ViewState ["AutoGenerateEditButton"];
377 ViewState ["AutoGenerateEditButton"] = value;
382 [WebCategoryAttribute ("Behavior")]
383 [DefaultValueAttribute (false)]
384 public virtual bool AutoGenerateDeleteButton {
386 object ob = ViewState ["AutoGenerateDeleteButton"];
392 ViewState ["AutoGenerateDeleteButton"] = value;
397 [WebCategoryAttribute ("Behavior")]
398 [DefaultValueAttribute (false)]
399 public virtual bool AutoGenerateInsertButton {
401 object ob = ViewState ["AutoGenerateInsertButton"];
407 ViewState ["AutoGenerateInsertButton"] = value;
412 [WebCategoryAttribute ("Behavior")]
413 [DefaultValueAttribute (true)]
414 public virtual bool AutoGenerateRows {
416 object ob = ViewState ["AutoGenerateRows"];
422 ViewState ["AutoGenerateRows"] = value;
427 [UrlPropertyAttribute]
428 [WebCategoryAttribute ("Appearance")]
429 [DefaultValueAttribute ("")]
430 [EditorAttribute ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
431 public virtual string BackImageUrl {
433 if (ControlStyleCreated)
434 return ((TableStyle) ControlStyle).BackImageUrl;
438 ((TableStyle) ControlStyle).BackImageUrl = value;
442 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
443 [BrowsableAttribute (false)]
444 public virtual DetailsViewRow BottomPagerRow {
446 EnsureChildControls ();
447 return bottomPagerRow;
451 [WebCategoryAttribute ("Accessibility")]
452 [DefaultValueAttribute ("")]
453 [LocalizableAttribute (true)]
454 public virtual string Caption {
456 object ob = ViewState ["Caption"];
462 ViewState ["Caption"] = value;
467 [WebCategoryAttribute ("Accessibility")]
468 [DefaultValueAttribute (TableCaptionAlign.NotSet)]
469 public virtual TableCaptionAlign CaptionAlign {
471 object o = ViewState ["CaptionAlign"];
473 return (TableCaptionAlign) o;
474 return TableCaptionAlign.NotSet;
477 ViewState ["CaptionAlign"] = value;
482 [WebCategoryAttribute ("Layout")]
483 [DefaultValueAttribute (-1)]
484 public virtual int CellPadding {
486 if (ControlStyleCreated)
487 return ((TableStyle) ControlStyle).CellPadding;
490 set { ((TableStyle) ControlStyle).CellPadding = value; }
493 [WebCategoryAttribute ("Layout")]
494 [DefaultValueAttribute (0)]
495 public virtual int CellSpacing {
497 if (ControlStyleCreated)
498 return ((TableStyle) ControlStyle).CellSpacing;
501 set { ((TableStyle) ControlStyle).CellSpacing = value; }
504 [DefaultValueAttribute (null)]
505 [WebCategoryAttribute ("Styles")]
506 [PersistenceMode (PersistenceMode.InnerProperty)]
507 [NotifyParentProperty (true)]
508 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
509 public TableItemStyle CommandRowStyle {
511 if (commandRowStyle == null) {
512 commandRowStyle = new TableItemStyle ();
513 if (IsTrackingViewState)
514 commandRowStyle.TrackViewState();
516 return commandRowStyle;
520 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
521 [BrowsableAttribute (false)]
522 public DetailsViewMode CurrentMode {
523 get { return hasCurrentMode ? currentMode : DefaultMode; }
526 hasCurrentMode = true;
531 DetailsViewMode defaultMode = DetailsViewMode.ReadOnly;
532 [DefaultValueAttribute (DetailsViewMode.ReadOnly)]
533 [WebCategoryAttribute ("Behavior")]
534 public virtual DetailsViewMode DefaultMode {
535 get { return defaultMode; }
542 [EditorAttribute ("System.Web.UI.Design.WebControls.DataControlFieldTypeEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
543 [MergablePropertyAttribute (false)]
544 [PersistenceModeAttribute (PersistenceMode.InnerProperty)]
545 [DefaultValueAttribute (null)]
546 [WebCategoryAttribute ("Misc")]
547 public virtual DataControlFieldCollection Fields {
549 if (columns == null) {
550 columns = new DataControlFieldCollection ();
551 columns.FieldsChanged += new EventHandler (OnFieldsChanged);
552 if (IsTrackingViewState)
553 ((IStateManager)columns).TrackViewState ();
559 string[] dataKeyNames = null;
561 [DefaultValueAttribute (null)]
562 [WebCategoryAttribute ("Data")]
563 [TypeConverter (typeof(StringArrayConverter))]
564 [EditorAttribute ("System.Web.UI.Design.WebControls.DataFieldEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
565 public virtual string[] DataKeyNames {
567 if (dataKeyNames == null)
573 dataKeyNames = value;
578 IOrderedDictionary KeyTable {
580 if (_keyTable == null)
581 _keyTable = new OrderedDictionary (DataKeyNames.Length);
586 [BrowsableAttribute (false)]
587 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
588 public virtual DataKey DataKey {
591 key = new DataKey (KeyTable);
596 DataKey OldEditValues {
598 if (oldEditValues == null)
599 oldEditValues = new DataKey (new OrderedDictionary ());
600 return oldEditValues;
604 [WebCategoryAttribute ("Styles")]
605 [PersistenceMode (PersistenceMode.InnerProperty)]
606 [NotifyParentProperty (true)]
607 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
608 [DefaultValueAttribute (null)]
609 public TableItemStyle EditRowStyle {
611 if (editRowStyle == null) {
612 editRowStyle = new TableItemStyle ();
613 if (IsTrackingViewState)
614 editRowStyle.TrackViewState();
620 [WebCategoryAttribute ("Styles")]
621 [PersistenceMode (PersistenceMode.InnerProperty)]
622 [NotifyParentProperty (true)]
623 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
624 [DefaultValueAttribute (null)]
625 public TableItemStyle EmptyDataRowStyle {
627 if (emptyDataRowStyle == null) {
628 emptyDataRowStyle = new TableItemStyle ();
629 if (IsTrackingViewState)
630 emptyDataRowStyle.TrackViewState();
632 return emptyDataRowStyle;
636 [DefaultValue (null)]
637 [TemplateContainer (typeof(DetailsView), BindingDirection.OneWay)]
638 [PersistenceMode (PersistenceMode.InnerProperty)]
640 public virtual ITemplate EmptyDataTemplate {
641 get { return emptyDataTemplate; }
642 set { emptyDataTemplate = value; }
645 [LocalizableAttribute (true)]
646 [WebCategoryAttribute ("Appearance")]
647 [DefaultValueAttribute ("")]
648 public virtual string EmptyDataText {
650 object ob = ViewState ["EmptyDataText"];
656 ViewState ["EmptyDataText"] = value;
661 [WebCategoryAttribute ("Behavior")]
662 [DefaultValueAttribute (false)]
663 public virtual bool EnablePagingCallbacks {
665 object ob = ViewState ["EnablePagingCallbacks"];
671 ViewState ["EnablePagingCallbacks"] = value;
676 [WebCategoryAttribute ("Styles")]
677 [PersistenceMode (PersistenceMode.InnerProperty)]
678 [NotifyParentProperty (true)]
679 [DefaultValue (null)]
680 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
681 public TableItemStyle FieldHeaderStyle {
683 if (fieldHeaderStyle == null) {
684 fieldHeaderStyle = new TableItemStyle ();
685 if (IsTrackingViewState)
686 fieldHeaderStyle.TrackViewState();
688 return fieldHeaderStyle;
692 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
693 [BrowsableAttribute (false)]
694 public virtual DetailsViewRow FooterRow {
696 EnsureChildControls ();
701 [DefaultValue (null)]
702 [TemplateContainer (typeof(DetailsView), BindingDirection.OneWay)]
703 [PersistenceMode (PersistenceMode.InnerProperty)]
705 public virtual ITemplate FooterTemplate {
706 get { return footerTemplate; }
707 set { footerTemplate = value; }
710 [LocalizableAttribute (true)]
711 [WebCategoryAttribute ("Appearance")]
712 [DefaultValueAttribute ("")]
713 public virtual string FooterText {
715 object ob = ViewState ["FooterText"];
721 ViewState ["FooterText"] = value;
726 [WebCategoryAttribute ("Styles")]
727 [PersistenceMode (PersistenceMode.InnerProperty)]
728 [NotifyParentProperty (true)]
729 [DefaultValue (null)]
730 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
731 public TableItemStyle FooterStyle {
733 if (footerStyle == null) {
734 footerStyle = new TableItemStyle ();
735 if (IsTrackingViewState)
736 footerStyle.TrackViewState();
742 [WebCategoryAttribute ("Appearance")]
743 [DefaultValueAttribute (GridLines.Both)]
744 public virtual GridLines GridLines {
746 if (ControlStyleCreated)
747 return ((TableStyle) ControlStyle).GridLines;
748 return GridLines.Both;
750 set { ((TableStyle) ControlStyle).GridLines = value; }
753 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
754 [BrowsableAttribute (false)]
755 public virtual DetailsViewRow HeaderRow {
757 EnsureChildControls ();
762 [WebCategoryAttribute ("Styles")]
763 [PersistenceMode (PersistenceMode.InnerProperty)]
764 [NotifyParentProperty (true)]
765 [DefaultValue (null)]
766 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
767 public TableItemStyle HeaderStyle {
769 if (headerStyle == null) {
770 headerStyle = new TableItemStyle ();
771 if (IsTrackingViewState)
772 headerStyle.TrackViewState();
778 [DefaultValue (null)]
779 [TemplateContainer (typeof(DetailsView), BindingDirection.OneWay)]
780 [PersistenceMode (PersistenceMode.InnerProperty)]
782 public virtual ITemplate HeaderTemplate {
783 get { return headerTemplate; }
784 set { headerTemplate = value; }
787 [LocalizableAttribute (true)]
788 [WebCategoryAttribute ("Appearance")]
789 [DefaultValueAttribute ("")]
790 public virtual string HeaderText {
792 object ob = ViewState ["HeaderText"];
798 ViewState ["HeaderText"] = value;
803 [Category ("Layout")]
804 [DefaultValueAttribute (HorizontalAlign.NotSet)]
805 public virtual HorizontalAlign HorizontalAlign {
807 if (ControlStyleCreated)
808 return ((TableStyle) ControlStyle).HorizontalAlign;
809 return HorizontalAlign.NotSet;
811 set { ((TableStyle) ControlStyle).HorizontalAlign = value; }
814 [WebCategoryAttribute ("Styles")]
815 [PersistenceMode (PersistenceMode.InnerProperty)]
816 [NotifyParentProperty (true)]
817 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
818 [DefaultValueAttribute (null)]
819 public TableItemStyle InsertRowStyle {
821 if (insertRowStyle == null) {
822 insertRowStyle = new TableItemStyle ();
823 if (IsTrackingViewState)
824 insertRowStyle.TrackViewState();
826 return insertRowStyle;
830 [BrowsableAttribute (false)]
831 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
832 public virtual int PageCount {
833 get { return pageCount; }
834 private set { pageCount = value; }
837 [WebCategoryAttribute ("Paging")]
838 [BindableAttribute (true, BindingDirection.OneWay)]
839 [DefaultValueAttribute (0)]
840 public virtual int PageIndex {
842 if (CurrentMode == DetailsViewMode.Insert)
848 throw new ArgumentOutOfRangeException ("PageIndex must be non-negative");
849 if (pageIndex == value || value == -1)
856 [WebCategoryAttribute ("Paging")]
857 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Content)]
858 [NotifyParentPropertyAttribute (true)]
859 [PersistenceModeAttribute (PersistenceMode.InnerProperty)]
860 public virtual PagerSettings PagerSettings {
862 if (pagerSettings == null) {
863 pagerSettings = new PagerSettings (this);
864 if (IsTrackingViewState)
865 ((IStateManager)pagerSettings).TrackViewState ();
867 return pagerSettings;
871 [WebCategoryAttribute ("Styles")]
872 [PersistenceMode (PersistenceMode.InnerProperty)]
873 [NotifyParentProperty (true)]
874 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
875 public TableItemStyle PagerStyle {
877 if (pagerStyle == null) {
878 pagerStyle = new TableItemStyle ();
879 if (IsTrackingViewState)
880 pagerStyle.TrackViewState();
887 [DefaultValue (null)]
888 [TemplateContainer (typeof (DetailsView), BindingDirection.OneWay)]
889 [PersistenceMode (PersistenceMode.InnerProperty)]
891 public virtual ITemplate PagerTemplate {
892 get { return pagerTemplate; }
893 set { pagerTemplate = value; }
896 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
897 [BrowsableAttribute (false)]
898 public virtual DetailsViewRowCollection Rows {
900 EnsureChildControls ();
905 [BrowsableAttribute(false)]
906 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
907 public IAutoFieldGenerator RowsGenerator {
912 [WebCategoryAttribute ("Styles")]
913 [PersistenceMode (PersistenceMode.InnerProperty)]
914 [NotifyParentProperty (true)]
915 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
916 [DefaultValue (null)]
917 public TableItemStyle RowStyle {
919 if (rowStyle == null) {
920 rowStyle = new TableItemStyle ();
921 if (IsTrackingViewState)
922 rowStyle.TrackViewState();
928 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
929 [BrowsableAttribute (false)]
930 public object SelectedValue {
931 get { return DataKey.Value; }
934 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
935 [BrowsableAttribute (false)]
936 public virtual DetailsViewRow TopPagerRow {
938 EnsureChildControls ();
943 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
944 [BrowsableAttribute (false)]
945 public virtual object DataItem {
951 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
952 [BrowsableAttribute (false)]
953 public int DataItemCount {
954 get { return PageCount; }
957 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
958 [BrowsableAttribute (false)]
959 public virtual int DataItemIndex {
960 get { return PageIndex; }
963 int IDataItemContainer.DisplayIndex {
964 get { return PageIndex; }
967 int IDataItemContainer.DataItemIndex {
968 get { return DataItemIndex; }
971 [MonoTODO ("Make use of it in the code")]
972 [DefaultValue (true)]
973 public virtual bool EnableModelValidation {
978 public virtual bool IsBindableType (Type type)
980 return type.IsPrimitive || type == typeof (string) || type == typeof (DateTime) || type == typeof (Guid) || type == typeof (Decimal);
983 protected override DataSourceSelectArguments CreateDataSourceSelectArguments ()
985 DataSourceSelectArguments arg = new DataSourceSelectArguments ();
986 DataSourceView view = GetData ();
987 if (AllowPaging && view.CanPage) {
988 arg.StartRowIndex = PageIndex;
989 if (view.CanRetrieveTotalRowCount) {
990 arg.RetrieveTotalRowCount = true;
993 arg.MaximumRows = -1;
998 protected virtual ICollection CreateFieldSet (object dataItem, bool useDataSource)
1000 bool autoGenerate = AutoGenerateRows;
1003 IAutoFieldGenerator fieldGenerator = RowsGenerator;
1004 if (fieldGenerator != null)
1005 return fieldGenerator.GenerateFields (this);
1008 ArrayList fields = new ArrayList ();
1010 if (AutoGenerateRows) {
1011 if (useDataSource) {
1012 if (dataItem != null)
1013 fields.AddRange (CreateAutoGeneratedRows (dataItem));
1015 if (autoFieldProperties != null) {
1016 foreach (AutoGeneratedFieldProperties props in autoFieldProperties)
1017 fields.Add (CreateAutoGeneratedRow (props));
1022 fields.AddRange (Fields);
1024 if (AutoGenerateEditButton || AutoGenerateDeleteButton || AutoGenerateInsertButton) {
1025 CommandField field = new CommandField ();
1026 field.ShowEditButton = AutoGenerateEditButton;
1027 field.ShowDeleteButton = AutoGenerateDeleteButton;
1028 field.ShowInsertButton = AutoGenerateInsertButton;
1035 protected virtual ICollection CreateAutoGeneratedRows (object dataItem)
1037 if (dataItem == null)
1040 ArrayList list = new ArrayList ();
1041 autoFieldProperties = CreateAutoFieldProperties (dataItem);
1042 foreach (AutoGeneratedFieldProperties props in autoFieldProperties)
1043 list.Add (CreateAutoGeneratedRow (props));
1047 protected virtual AutoGeneratedField CreateAutoGeneratedRow (AutoGeneratedFieldProperties fieldProperties)
1049 return new AutoGeneratedField (fieldProperties);
1052 AutoGeneratedFieldProperties[] CreateAutoFieldProperties (object dataItem)
1054 if (IsBindableType (dataItem.GetType ())) {
1055 AutoGeneratedFieldProperties field = new AutoGeneratedFieldProperties ();
1056 ((IStateManager) field).TrackViewState ();
1057 field.Name = "Item";
1058 field.DataField = BoundField.ThisExpression;
1059 field.Type = dataItem.GetType ();
1060 return new AutoGeneratedFieldProperties [] { field };
1063 PropertyDescriptorCollection props = TypeDescriptor.GetProperties (dataItem, false);
1065 if (props != null && props.Count > 0) {
1066 ArrayList retVal = new ArrayList ();
1067 foreach (PropertyDescriptor current in props) {
1068 if (IsBindableType (current.PropertyType)) {
1069 AutoGeneratedFieldProperties field = new AutoGeneratedFieldProperties ();
1070 ((IStateManager) field).TrackViewState ();
1071 field.Name = current.Name;
1072 field.DataField = current.Name;
1073 for (int i = 0; i < DataKeyNames.Length; i++) {
1074 if (string.Compare (DataKeyNames [i], current.Name, StringComparison.InvariantCultureIgnoreCase) == 0) {
1075 field.IsReadOnly = true;
1079 field.Type = current.PropertyType;
1083 if (retVal.Count > 0)
1084 return (AutoGeneratedFieldProperties []) retVal.ToArray (typeof (AutoGeneratedFieldProperties));
1086 throw new HttpException (String.Format ("DetailsView with id '{0}' did not have any properties or attributes from which to generate fields. Ensure that your data source has content.", ID));
1089 protected virtual DetailsViewRow CreateRow (int rowIndex, DataControlRowType rowType, DataControlRowState rowState)
1092 if (rowType == DataControlRowType.Pager)
1093 row = new DetailsViewPagerRow (rowIndex, rowType, rowState);
1095 row = new DetailsViewRow (rowIndex, rowType, rowState);
1099 void RequireBinding ()
1102 RequiresDataBinding = true;
1105 protected virtual Table CreateTable ()
1107 return new ContainedTable (this);
1110 protected override Style CreateControlStyle ()
1112 TableStyle style = new TableStyle ();
1113 style.GridLines = GridLines.Both;
1114 style.CellSpacing = 0;
1118 protected override int CreateChildControls (IEnumerable data, bool dataBinding)
1120 PagedDataSource dataSource = new PagedDataSource ();
1121 dataSource.DataSource = CurrentMode != DetailsViewMode.Insert ? data : null;
1122 dataSource.AllowPaging = AllowPaging;
1123 dataSource.PageSize = 1;
1124 dataSource.CurrentPageIndex = PageIndex;
1126 if (dataBinding && CurrentMode != DetailsViewMode.Insert) {
1127 DataSourceView view = GetData ();
1128 if (view != null && view.CanPage) {
1129 dataSource.AllowServerPaging = true;
1130 if (SelectArguments.RetrieveTotalRowCount)
1131 dataSource.VirtualCount = SelectArguments.TotalRowCount;
1135 bool showPager = AllowPaging && (dataSource.PageCount > 1);
1138 table = CreateTable ();
1139 Controls.Add (table);
1143 bottomPagerRow = null;
1144 ArrayList list = new ArrayList ();
1146 // Gets the current data item
1149 PageCount = dataSource.DataSourceCount;
1150 if (PageIndex >= PageCount && PageCount > 0)
1151 pageIndex = dataSource.CurrentPageIndex = PageCount - 1;
1152 if (dataSource.DataSource != null) {
1153 IEnumerator e = dataSource.GetEnumerator ();
1155 dataItem = e.Current;
1159 object lastItem = null;
1160 if (dataSource.DataSource != null) {
1161 IEnumerator e = dataSource.GetEnumerator ();
1162 for (; e.MoveNext (); page++) {
1163 lastItem = e.Current;
1164 if (page == PageIndex)
1165 dataItem = e.Current;
1169 if (PageIndex >= PageCount && PageCount > 0) {
1170 pageIndex = PageCount - 1;
1171 dataItem = lastItem;
1175 if (PageCount == 0 && CurrentMode != DetailsViewMode.Insert) {
1176 DetailsViewRow row = CreateEmptyRow ();
1178 table.Rows.Add (row);
1182 // Creates the set of fields to show
1184 ICollection fieldCollection = CreateFieldSet (dataItem, dataBinding && dataItem != null);
1185 DataControlField [] fields = new DataControlField [fieldCollection.Count];
1186 fieldCollection.CopyTo (fields, 0);
1188 foreach (DataControlField field in fields) {
1189 field.Initialize (false, this);
1190 if (EnablePagingCallbacks)
1191 field.ValidateSupportsCallback ();
1194 // Main table creation
1196 headerRow = CreateRow (-1, DataControlRowType.Header, DataControlRowState.Normal);
1197 DataControlFieldCell headerCell = new DataControlFieldCell (null);
1198 headerCell.ColumnSpan = 2;
1199 if (headerTemplate != null)
1200 headerTemplate.InstantiateIn (headerCell);
1201 else if (!String.IsNullOrEmpty (HeaderText))
1202 headerCell.Text = HeaderText;
1204 headerRow.Visible = false;
1205 headerRow.Cells.Add (headerCell);
1206 table.Rows.Add (headerRow);
1208 if (showPager && PagerSettings.Position == PagerPosition.Top ||
1209 PagerSettings.Position == PagerPosition.TopAndBottom) {
1210 topPagerRow = CreateRow (-1, DataControlRowType.Pager, DataControlRowState.Normal);
1211 InitializePager (topPagerRow, dataSource);
1212 table.Rows.Add (topPagerRow);
1215 foreach (DataControlField field in fields) {
1216 DataControlRowState rstate = GetRowState (list.Count);
1217 DetailsViewRow row = CreateRow (PageIndex, DataControlRowType.DataRow, rstate);
1218 InitializeRow (row, field);
1219 table.Rows.Add (row);
1223 footerRow = CreateRow (-1, DataControlRowType.Footer, DataControlRowState.Normal);
1224 DataControlFieldCell footerCell = new DataControlFieldCell (null);
1225 footerCell.ColumnSpan = 2;
1226 if (footerTemplate != null)
1227 footerTemplate.InstantiateIn (footerCell);
1228 else if (!String.IsNullOrEmpty (FooterText))
1229 footerCell.Text = FooterText;
1231 footerRow.Visible = false;
1232 footerRow.Cells.Add (footerCell);
1233 table.Rows.Add (footerRow);
1235 if (showPager && PagerSettings.Position == PagerPosition.Bottom ||
1236 PagerSettings.Position == PagerPosition.TopAndBottom) {
1237 bottomPagerRow = CreateRow (-1, DataControlRowType.Pager, DataControlRowState.Normal);
1238 InitializePager (bottomPagerRow, dataSource);
1239 table.Rows.Add (bottomPagerRow);
1243 rows = new DetailsViewRowCollection (list);
1248 OnItemCreated (EventArgs.Empty);
1253 protected override void EnsureDataBound ()
1255 if (CurrentMode == DetailsViewMode.Insert) {
1256 if (RequiresDataBinding) {
1257 OnDataBinding (EventArgs.Empty);
1258 RequiresDataBinding = false;
1259 InternalPerformDataBinding (null);
1261 OnDataBound (EventArgs.Empty);
1264 base.EnsureDataBound ();
1267 DataControlRowState GetRowState (int index)
1269 DataControlRowState rstate = (index % 2) == 0 ? DataControlRowState.Normal : DataControlRowState.Alternate;
1270 if (CurrentMode == DetailsViewMode.Edit)
1271 rstate |= DataControlRowState.Edit;
1272 else if (CurrentMode == DetailsViewMode.Insert)
1273 rstate |= DataControlRowState.Insert;
1277 protected virtual void InitializePager (DetailsViewRow row, PagedDataSource dataSource)
1279 TableCell cell = new TableCell ();
1280 cell.ColumnSpan = 2;
1282 if (pagerTemplate != null)
1283 pagerTemplate.InstantiateIn (cell);
1285 cell.Controls.Add (PagerSettings.CreatePagerControl (dataSource.CurrentPageIndex, dataSource.PageCount));
1287 row.Cells.Add (cell);
1290 DetailsViewRow CreateEmptyRow ()
1292 TableCell cell = new TableCell ();
1294 if (emptyDataTemplate != null)
1295 emptyDataTemplate.InstantiateIn (cell);
1296 else if (!String.IsNullOrEmpty (EmptyDataText))
1297 cell.Text = EmptyDataText;
1301 DetailsViewRow row = CreateRow (-1, DataControlRowType.EmptyDataRow, DataControlRowState.Normal);
1302 row.Cells.Add (cell);
1306 protected virtual void InitializeRow (DetailsViewRow row, DataControlField field)
1308 if (!field.Visible) {
1309 row.Visible = false;
1313 row.ContainingField = field;
1314 DataControlFieldCell cell;
1316 if (field.ShowHeader) {
1317 cell = new DataControlFieldCell (field);
1318 row.Cells.Add (cell);
1319 field.InitializeCell (cell, DataControlCellType.Header, row.RowState, row.RowIndex);
1322 cell = new DataControlFieldCell (field);
1323 if (!field.ShowHeader)
1324 cell.ColumnSpan = 2;
1325 row.Cells.Add (cell);
1326 field.InitializeCell (cell, DataControlCellType.DataCell, row.RowState, row.RowIndex);
1328 if (CurrentMode == DetailsViewMode.Insert && !field.InsertVisible)
1329 row.Visible = false;
1332 void FillRowDataKey (object dataItem)
1336 if (cachedKeyProperties == null) {
1337 PropertyDescriptorCollection props = TypeDescriptor.GetProperties (dataItem);
1338 cachedKeyProperties = new PropertyDescriptor [DataKeyNames.Length];
1339 for (int n=0; n<DataKeyNames.Length; n++) {
1340 PropertyDescriptor p = props.Find (DataKeyNames [n], true);
1342 throw new InvalidOperationException ("Property '" + DataKeyNames[n] + "' not found in object of type " + dataItem.GetType());
1343 cachedKeyProperties [n] = p;
1347 foreach (PropertyDescriptor p in cachedKeyProperties)
1348 KeyTable [p.Name] = p.GetValue (dataItem);
1351 IOrderedDictionary GetRowValues (bool includeReadOnlyFields, bool includePrimaryKey)
1353 OrderedDictionary dic = new OrderedDictionary ();
1354 ExtractRowValues (dic, includeReadOnlyFields, includePrimaryKey);
1358 protected virtual void ExtractRowValues (IOrderedDictionary fieldValues, bool includeReadOnlyFields, bool includePrimaryKey)
1360 foreach (DetailsViewRow row in Rows) {
1361 if (row.Cells.Count < 1)
1363 DataControlFieldCell c = row.Cells[row.Cells.Count-1] as DataControlFieldCell;
1365 c.ContainingField.ExtractValuesFromCell (fieldValues, c, row.RowState, includeReadOnlyFields);
1367 if (!includePrimaryKey && DataKeyNames != null)
1368 foreach (string key in DataKeyNames)
1369 fieldValues.Remove (key);
1372 protected override HtmlTextWriterTag TagKey {
1374 if (EnablePagingCallbacks)
1375 return HtmlTextWriterTag.Div;
1377 return HtmlTextWriterTag.Table;
1381 public sealed override void DataBind ()
1383 cachedKeyProperties = null;
1386 if (dataItem != null) {
1387 if (CurrentMode == DetailsViewMode.Edit)
1388 oldEditValues = new DataKey (GetRowValues (false, true));
1389 FillRowDataKey (dataItem);
1390 key = new DataKey (KeyTable);
1394 protected internal override void PerformDataBinding (IEnumerable data)
1396 base.PerformDataBinding (data);
1399 protected internal virtual void PrepareControlHierarchy ()
1404 table.Caption = Caption;
1405 table.CaptionAlign = CaptionAlign;
1407 foreach (DetailsViewRow row in table.Rows) {
1408 switch (row.RowType) {
1409 case DataControlRowType.Header:
1410 if (headerStyle != null && !headerStyle.IsEmpty)
1411 row.ControlStyle.CopyFrom (headerStyle);
1413 case DataControlRowType.Footer:
1414 if (footerStyle != null && !footerStyle.IsEmpty)
1415 row.ControlStyle.CopyFrom (footerStyle);
1417 case DataControlRowType.Pager:
1418 if (pagerStyle != null && !pagerStyle.IsEmpty)
1419 row.ControlStyle.CopyFrom (pagerStyle);
1421 case DataControlRowType.EmptyDataRow:
1422 if (emptyDataRowStyle != null && !emptyDataRowStyle.IsEmpty)
1423 row.ControlStyle.CopyFrom (emptyDataRowStyle);
1425 case DataControlRowType.DataRow:
1426 if (rowStyle != null && !rowStyle.IsEmpty)
1427 row.ControlStyle.CopyFrom (rowStyle);
1428 if ((row.RowState & DataControlRowState.Alternate) != 0 && alternatingRowStyle != null && !alternatingRowStyle.IsEmpty)
1429 row.ControlStyle.CopyFrom (alternatingRowStyle);
1435 if (row.ContainingField is CommandField) {
1436 if (commandRowStyle != null && !commandRowStyle.IsEmpty)
1437 row.ControlStyle.CopyFrom (commandRowStyle);
1439 if ((row.RowState & DataControlRowState.Edit) != 0 && editRowStyle != null && !editRowStyle.IsEmpty)
1440 row.ControlStyle.CopyFrom (editRowStyle);
1441 if ((row.RowState & DataControlRowState.Insert) != 0) {
1442 if (insertRowStyle != null && !insertRowStyle.IsEmpty)
1443 row.ControlStyle.CopyFrom (insertRowStyle);
1444 else if (editRowStyle != null && !editRowStyle.IsEmpty)
1445 row.ControlStyle.CopyFrom (editRowStyle);
1449 for (int n = 0; n < row.Cells.Count; n++) {
1450 DataControlFieldCell fcell = row.Cells [n] as DataControlFieldCell;
1451 if (fcell != null && fcell.ContainingField != null) {
1452 DataControlField field = fcell.ContainingField;
1453 if (n == 0 && field.ShowHeader) {
1454 if (fieldHeaderStyle != null && !fieldHeaderStyle.IsEmpty)
1455 fcell.ControlStyle.CopyFrom (fieldHeaderStyle);
1456 if (field.HeaderStyleCreated && !field.HeaderStyle.IsEmpty)
1457 fcell.ControlStyle.CopyFrom (field.HeaderStyle);
1459 if (field.ControlStyleCreated && !field.ControlStyle.IsEmpty) {
1460 foreach (Control c in fcell.Controls) {
1461 WebControl wc = c as WebControl;
1463 wc.ControlStyle.MergeWith (field.ControlStyle);
1467 if (field.ItemStyleCreated && !field.ItemStyle.IsEmpty)
1468 fcell.ControlStyle.CopyFrom (field.ItemStyle);
1475 protected internal override void OnInit (EventArgs e)
1479 page.RegisterRequiresControlState (this);
1483 void OnFieldsChanged (object sender, EventArgs args)
1488 protected override void OnDataSourceViewChanged (object sender, EventArgs e)
1490 base.OnDataSourceViewChanged (sender, e);
1494 protected override bool OnBubbleEvent (object source, EventArgs e)
1496 DetailsViewCommandEventArgs args = e as DetailsViewCommandEventArgs;
1498 bool causesValidation = false;
1499 IButtonControl button = args.CommandSource as IButtonControl;
1500 if (button != null && button.CausesValidation) {
1501 Page.Validate (button.ValidationGroup);
1502 causesValidation = true;
1504 ProcessCommand (args, causesValidation);
1507 return base.OnBubbleEvent (source, e);
1510 void ProcessCommand (DetailsViewCommandEventArgs args, bool causesValidation) {
1511 OnItemCommand (args);
1512 ProcessEvent (args.CommandName, args.CommandArgument as string, causesValidation);
1515 void IPostBackEventHandler.RaisePostBackEvent (string eventArgument)
1517 RaisePostBackEvent (eventArgument);
1520 // TODO: This is prolly obsolete
1521 protected virtual void RaisePostBackEvent (string eventArgument)
1523 ValidateEvent (UniqueID, eventArgument);
1524 int i = eventArgument.IndexOf ('$');
1525 CommandEventArgs arg;
1527 arg = new CommandEventArgs (eventArgument.Substring (0, i), eventArgument.Substring (i + 1));
1529 arg = new CommandEventArgs (eventArgument, null);
1530 ProcessCommand (new DetailsViewCommandEventArgs (this, arg), false);
1533 void ProcessEvent (string eventName, string param, bool causesValidation)
1535 switch (eventName) {
1536 case DataControlCommands.PageCommandName:
1539 case DataControlCommands.FirstPageCommandArgument:
1542 case DataControlCommands.LastPageCommandArgument:
1543 newIndex = PageCount - 1;
1545 case DataControlCommands.NextPageCommandArgument:
1546 newIndex = PageIndex + 1;
1548 case DataControlCommands.PreviousPageCommandArgument:
1549 newIndex = PageIndex - 1;
1553 int.TryParse (param, out paramIndex);
1554 newIndex = paramIndex - 1;
1557 SetPageIndex (newIndex);
1560 case DataControlCommands.FirstPageCommandArgument:
1564 case DataControlCommands.LastPageCommandArgument:
1565 SetPageIndex (PageCount - 1);
1568 case DataControlCommands.NextPageCommandArgument:
1569 if (PageIndex < PageCount - 1)
1570 SetPageIndex (PageIndex + 1);
1573 case DataControlCommands.PreviousPageCommandArgument:
1575 SetPageIndex (PageIndex - 1);
1578 case DataControlCommands.EditCommandName:
1579 ProcessChangeMode (DetailsViewMode.Edit);
1582 case DataControlCommands.NewCommandName:
1583 ProcessChangeMode (DetailsViewMode.Insert);
1586 case DataControlCommands.UpdateCommandName:
1587 UpdateItem (param, causesValidation);
1590 case DataControlCommands.CancelCommandName:
1594 case DataControlCommands.DeleteCommandName:
1598 case DataControlCommands.InsertCommandName:
1599 InsertItem (causesValidation);
1606 void SetPageIndex (int newIndex)
1608 DetailsViewPageEventArgs args = new DetailsViewPageEventArgs (newIndex);
1609 OnPageIndexChanging (args);
1611 if (args.Cancel || !IsBoundUsingDataSourceID)
1614 if (args.NewPageIndex < 0 || args.NewPageIndex >= PageCount)
1617 PageIndex = args.NewPageIndex;
1618 OnPageIndexChanged (EventArgs.Empty);
1621 public void ChangeMode (DetailsViewMode newMode)
1623 CurrentMode = newMode;
1627 void ProcessChangeMode (DetailsViewMode newMode)
1629 DetailsViewModeEventArgs args = new DetailsViewModeEventArgs (newMode, false);
1630 OnModeChanging (args);
1632 if (args.Cancel || !IsBoundUsingDataSourceID)
1635 ChangeMode (args.NewMode);
1637 OnModeChanged (EventArgs.Empty);
1642 DetailsViewModeEventArgs args = new DetailsViewModeEventArgs (DetailsViewMode.ReadOnly, true);
1643 OnModeChanging (args);
1645 if (args.Cancel || !IsBoundUsingDataSourceID)
1651 public virtual void UpdateItem (bool causesValidation)
1653 UpdateItem (null, causesValidation);
1656 void UpdateItem (string param, bool causesValidation)
1658 if (causesValidation && Page != null && !Page.IsValid)
1661 if (CurrentMode != DetailsViewMode.Edit)
1662 throw new HttpException ();
1664 currentEditOldValues = OldEditValues.Values;
1666 currentEditRowKeys = DataKey.Values;
1667 currentEditNewValues = GetRowValues (false, false);
1669 DetailsViewUpdateEventArgs args = new DetailsViewUpdateEventArgs (param, currentEditRowKeys, currentEditOldValues, currentEditNewValues);
1670 OnItemUpdating (args);
1672 if (args.Cancel || !IsBoundUsingDataSourceID)
1675 DataSourceView view = GetData ();
1677 throw new HttpException ("The DataSourceView associated to data bound control was null");
1678 view.Update (currentEditRowKeys, currentEditNewValues, currentEditOldValues, new DataSourceViewOperationCallback (UpdateCallback));
1681 bool UpdateCallback (int recordsAffected, Exception exception)
1683 DetailsViewUpdatedEventArgs dargs = new DetailsViewUpdatedEventArgs (recordsAffected, exception, currentEditRowKeys, currentEditOldValues, currentEditNewValues);
1684 OnItemUpdated (dargs);
1686 if (!dargs.KeepInEditMode)
1689 return dargs.ExceptionHandled;
1692 public virtual void InsertItem (bool causesValidation)
1694 InsertItem (null, causesValidation);
1697 void InsertItem (string param, bool causesValidation)
1699 if (causesValidation && Page != null && !Page.IsValid)
1702 if (CurrentMode != DetailsViewMode.Insert)
1703 throw new HttpException ();
1705 currentEditNewValues = GetRowValues (false, true);
1706 DetailsViewInsertEventArgs args = new DetailsViewInsertEventArgs (param, currentEditNewValues);
1707 OnItemInserting (args);
1709 if (args.Cancel || !IsBoundUsingDataSourceID)
1712 DataSourceView view = GetData ();
1714 throw new HttpException ("The DataSourceView associated to data bound control was null");
1715 view.Insert (currentEditNewValues, new DataSourceViewOperationCallback (InsertCallback));
1718 bool InsertCallback (int recordsAffected, Exception exception)
1720 DetailsViewInsertedEventArgs dargs = new DetailsViewInsertedEventArgs (recordsAffected, exception, currentEditNewValues);
1721 OnItemInserted (dargs);
1723 if (!dargs.KeepInInsertMode)
1726 return dargs.ExceptionHandled;
1729 public virtual void DeleteItem ()
1731 currentEditRowKeys = DataKey.Values;
1732 currentEditNewValues = GetRowValues (true, false);
1734 DetailsViewDeleteEventArgs args = new DetailsViewDeleteEventArgs (PageIndex, currentEditRowKeys, currentEditNewValues);
1735 OnItemDeleting (args);
1737 if (args.Cancel || !IsBoundUsingDataSourceID)
1740 DataSourceView view = GetData ();
1742 view.Delete (currentEditRowKeys, currentEditNewValues, new DataSourceViewOperationCallback (DeleteCallback));
1744 DetailsViewDeletedEventArgs dargs = new DetailsViewDeletedEventArgs (0, null, currentEditRowKeys, currentEditNewValues);
1745 OnItemDeleted (dargs);
1747 if (PageIndex > 0 && PageIndex == PageCount - 1)
1752 bool DeleteCallback (int recordsAffected, Exception exception)
1754 DetailsViewDeletedEventArgs dargs = new DetailsViewDeletedEventArgs (recordsAffected, exception, currentEditRowKeys, currentEditNewValues);
1755 OnItemDeleted (dargs);
1756 return dargs.ExceptionHandled;
1764 void EndRowEdit (bool switchToDefaultMode)
1766 if (switchToDefaultMode)
1767 ChangeMode (DefaultMode);
1768 oldEditValues = new DataKey (new OrderedDictionary ());
1769 currentEditRowKeys = null;
1770 currentEditOldValues = null;
1771 currentEditNewValues = null;
1775 protected internal override void LoadControlState (object ob)
1779 object[] state = (object[]) ob;
1780 base.LoadControlState (state[0]);
1781 pageIndex = (int) state[1];
1782 pageCount = (int) state[2];
1783 CurrentMode = (DetailsViewMode) state[3];
1784 dataKeyNames = (string[]) state[4];
1785 defaultMode = (DetailsViewMode) state[5];
1786 if (state [6] != null)
1787 ((IStateManager) DataKey).LoadViewState (state [6]);
1788 if (state [7] != null)
1789 ((IStateManager) OldEditValues).LoadViewState (state [7]);
1792 protected internal override object SaveControlState ()
1794 object bstate = base.SaveControlState ();
1795 return new object[] {
1802 (key == null ? null : ((IStateManager)key).SaveViewState()),
1803 (oldEditValues == null ? null : ((IStateManager) oldEditValues).SaveViewState ())
1807 protected override void TrackViewState()
1809 base.TrackViewState();
1810 if (columns != null)
1811 ((IStateManager)columns).TrackViewState();
1812 if (pagerSettings != null)
1813 ((IStateManager)pagerSettings).TrackViewState();
1814 if (alternatingRowStyle != null)
1815 ((IStateManager)alternatingRowStyle).TrackViewState();
1816 if (footerStyle != null)
1817 ((IStateManager)footerStyle).TrackViewState();
1818 if (headerStyle != null)
1819 ((IStateManager)headerStyle).TrackViewState();
1820 if (pagerStyle != null)
1821 ((IStateManager)pagerStyle).TrackViewState();
1822 if (rowStyle != null)
1823 ((IStateManager)rowStyle).TrackViewState();
1824 if (editRowStyle != null)
1825 ((IStateManager)editRowStyle).TrackViewState();
1826 if (insertRowStyle != null)
1827 ((IStateManager)insertRowStyle).TrackViewState();
1828 if (emptyDataRowStyle != null)
1829 ((IStateManager)emptyDataRowStyle).TrackViewState();
1831 ((IStateManager)key).TrackViewState();
1832 if (autoFieldProperties != null) {
1833 foreach (IStateManager sm in autoFieldProperties)
1834 sm.TrackViewState ();
1836 if (ControlStyleCreated)
1837 ControlStyle.TrackViewState ();
1840 protected override object SaveViewState()
1842 object[] states = new object [13];
1843 states[0] = base.SaveViewState();
1844 states[1] = (columns == null ? null : ((IStateManager)columns).SaveViewState());
1845 states[2] = (pagerSettings == null ? null : ((IStateManager)pagerSettings).SaveViewState());
1846 states[3] = (alternatingRowStyle == null ? null : ((IStateManager)alternatingRowStyle).SaveViewState());
1847 states[4] = (footerStyle == null ? null : ((IStateManager)footerStyle).SaveViewState());
1848 states[5] = (headerStyle == null ? null : ((IStateManager)headerStyle).SaveViewState());
1849 states[6] = (pagerStyle == null ? null : ((IStateManager)pagerStyle).SaveViewState());
1850 states[7] = (rowStyle == null ? null : ((IStateManager)rowStyle).SaveViewState());
1851 states[8] = (insertRowStyle == null ? null : ((IStateManager)insertRowStyle).SaveViewState());
1852 states[9] = (editRowStyle == null ? null : ((IStateManager)editRowStyle).SaveViewState());
1853 states[10] = (emptyDataRowStyle == null ? null : ((IStateManager)emptyDataRowStyle).SaveViewState());
1855 if (autoFieldProperties != null) {
1856 object[] data = new object [autoFieldProperties.Length];
1857 bool allNull = true;
1858 for (int n=0; n<data.Length; n++) {
1859 data [n] = ((IStateManager)autoFieldProperties [n]).SaveViewState ();
1860 if (data [n] != null) allNull = false;
1862 if (!allNull) states [11] = data;
1864 if (ControlStyleCreated)
1865 states [12] = ControlStyle.SaveViewState ();
1867 for (int i = states.Length - 1; i >= 0; i--) {
1868 if (states [i] != null)
1875 protected override void LoadViewState (object savedState)
1877 if (savedState == null) {
1878 base.LoadViewState (null);
1882 object [] states = (object []) savedState;
1884 if (states[11] != null) {
1885 object[] data = (object[]) states [11];
1886 autoFieldProperties = new AutoGeneratedFieldProperties [data.Length];
1887 for (int n=0; n<data.Length; n++) {
1888 IStateManager p = new AutoGeneratedFieldProperties ();
1889 p.TrackViewState ();
1890 p.LoadViewState (data [n]);
1891 autoFieldProperties [n] = (AutoGeneratedFieldProperties) p;
1895 base.LoadViewState (states[0]);
1897 if (states[1] != null) ((IStateManager)Fields).LoadViewState (states[1]);
1898 if (states[2] != null) ((IStateManager)PagerSettings).LoadViewState (states[2]);
1899 if (states[3] != null) ((IStateManager)AlternatingRowStyle).LoadViewState (states[3]);
1900 if (states[4] != null) ((IStateManager)FooterStyle).LoadViewState (states[4]);
1901 if (states[5] != null) ((IStateManager)HeaderStyle).LoadViewState (states[5]);
1902 if (states[6] != null) ((IStateManager)PagerStyle).LoadViewState (states[6]);
1903 if (states[7] != null) ((IStateManager)RowStyle).LoadViewState (states[7]);
1904 if (states[8] != null) ((IStateManager)InsertRowStyle).LoadViewState (states[8]);
1905 if (states[9] != null) ((IStateManager)EditRowStyle).LoadViewState (states[9]);
1906 if (states[10] != null) ((IStateManager)EmptyDataRowStyle).LoadViewState (states[10]);
1907 if (states [12] != null)
1908 ControlStyle.LoadViewState (states [12]);
1911 void ICallbackEventHandler.RaiseCallbackEvent (string eventArgs)
1913 RaiseCallbackEvent (eventArgs);
1916 protected virtual void RaiseCallbackEvent (string eventArgs)
1918 string[] clientData = eventArgs.Split ('|');
1919 PageIndex = int.Parse (clientData[0]);
1921 RaisePostBackEvent (clientData[1]);
1925 string ICallbackEventHandler.GetCallbackResult ()
1927 return GetCallbackResult ();
1930 protected virtual string GetCallbackResult ()
1932 PrepareControlHierarchy ();
1934 StringWriter sw = new StringWriter ();
1935 sw.Write (PageIndex.ToString () + '|');
1937 HtmlTextWriter writer = new HtmlTextWriter (sw);
1938 RenderGrid (writer);
1939 return sw.ToString ();
1942 protected virtual string GetCallbackScript (IButtonControl buttonControl, string argument)
1944 if (EnablePagingCallbacks) {
1947 page.ClientScript.RegisterForEventValidation (UniqueID, argument);
1948 return "javascript:DetailsView_ClientEvent (\"" + ClientID + "\",\"" + buttonControl.CommandName + "$" + buttonControl.CommandArgument + "\"); return false;";
1953 string ICallbackContainer.GetCallbackScript (IButtonControl control, string argument)
1955 return GetCallbackScript (control, argument);
1958 protected override void OnPagePreLoad (object sender, EventArgs e)
1960 base.OnPagePreLoad (sender, e);
1962 if (Page.IsPostBack && EnablePagingCallbacks) {
1964 if (int.TryParse (Page.Request.Form [ClientID + "_Page"], out page))
1969 const string onPreRenderScript = @"var {0} = new Object ();
1970 {0}.pageIndex = {1};
1974 protected internal override void OnPreRender (EventArgs e)
1976 base.OnPreRender (e);
1979 if (EnablePagingCallbacks && page != null) {
1980 ClientScriptManager scriptManager = page.ClientScript;
1981 if (!scriptManager.IsClientScriptIncludeRegistered (typeof(DetailsView), "DetailsView.js")) {
1982 string url = scriptManager.GetWebResourceUrl (typeof(DetailsView), "DetailsView.js");
1983 scriptManager.RegisterClientScriptInclude (typeof(DetailsView), "DetailsView.js", url);
1985 scriptManager.RegisterHiddenField (ClientID + "_Page", PageIndex.ToString ());
1987 string cgrid = ClientID + "_data";
1988 string script = String.Format (onPreRenderScript,
1990 ClientScriptManager.GetScriptLiteral (PageIndex),
1991 ClientScriptManager.GetScriptLiteral (UniqueID),
1994 scriptManager.RegisterStartupScript (typeof(TreeView), this.UniqueID, script, true);
1996 // Make sure the basic script infrastructure is rendered
1997 scriptManager.GetCallbackEventReference (this, "null", String.Empty, "null");
1998 scriptManager.GetPostBackClientHyperlink (this, String.Empty, true);
2002 protected internal override void Render (HtmlTextWriter writer)
2004 PrepareControlHierarchy ();
2006 if (EnablePagingCallbacks)
2007 writer.AddAttribute (HtmlTextWriterAttribute.Id, ClientID + "_div");
2008 writer.RenderBeginTag (HtmlTextWriterTag.Div);
2010 RenderGrid (writer);
2012 writer.RenderEndTag ();
2015 void RenderGrid (HtmlTextWriter writer)
2020 table.Render (writer);
2023 PostBackOptions IPostBackContainer.GetPostBackOptions (IButtonControl control)
2025 if (control == null)
2026 throw new ArgumentNullException ("control");
2028 if (control.CausesValidation)
2029 throw new InvalidOperationException ("A button that causes validation in DetailsView '" + ID + "' is attempting to use the container GridView as the post back target. The button should either turn off validation or use itself as the post back container.");
2031 PostBackOptions options = new PostBackOptions (this);
2032 options.Argument = control.CommandName + "$" + control.CommandArgument;
2033 options.RequiresJavaScriptProtocol = true;