2 // System.Web.UI.WebControls.GridView.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.GridViewDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
45 [ControlValuePropertyAttribute ("SelectedValue")]
46 [DefaultEventAttribute ("SelectedIndexChanged")]
47 [AspNetHostingPermissionAttribute (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
48 [AspNetHostingPermissionAttribute (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
49 public class GridView: CompositeDataBoundControl, ICallbackEventHandler, ICallbackContainer, IPostBackEventHandler, IPostBackContainer
52 GridViewRowCollection rows;
53 GridViewRow bottomPagerRow;
54 GridViewRow topPagerRow;
56 IOrderedDictionary currentEditRowKeys;
57 IOrderedDictionary currentEditNewValues;
58 IOrderedDictionary currentEditOldValues;
60 ITemplate pagerTemplate;
61 ITemplate emptyDataTemplate;
63 PropertyDescriptor[] cachedKeyProperties;
66 DataControlFieldCollection columns;
67 PagerSettings pagerSettings;
69 TableItemStyle alternatingRowStyle;
70 TableItemStyle editRowStyle;
71 TableItemStyle emptyDataRowStyle;
72 TableItemStyle footerStyle;
73 TableItemStyle headerStyle;
74 TableItemStyle pagerStyle;
75 TableItemStyle rowStyle;
76 TableItemStyle selectedRowStyle;
77 ArrayList _dataKeyArrayList;
79 DataKey oldEditValues;
80 AutoGeneratedFieldProperties[] autoFieldProperties;
81 string [] dataKeyNames = null;
82 readonly string[] emptyKeys = new string[0];
84 private static readonly object PageIndexChangedEvent = new object();
85 private static readonly object PageIndexChangingEvent = new object();
86 private static readonly object RowCancelingEditEvent = new object();
87 private static readonly object RowCommandEvent = new object();
88 private static readonly object RowCreatedEvent = new object();
89 private static readonly object RowDataBoundEvent = new object();
90 private static readonly object RowDeletedEvent = new object();
91 private static readonly object RowDeletingEvent = new object();
92 private static readonly object RowEditingEvent = new object();
93 private static readonly object RowUpdatedEvent = new object();
94 private static readonly object RowUpdatingEvent = new object();
95 private static readonly object SelectedIndexChangedEvent = new object();
96 private static readonly object SelectedIndexChangingEvent = new object();
97 private static readonly object SortedEvent = new object();
98 private static readonly object SortingEvent = new object();
102 int selectedIndex = -1;
104 SortDirection sortDirection = SortDirection.Ascending;
105 string sortExpression;
111 public event EventHandler PageIndexChanged {
112 add { Events.AddHandler (PageIndexChangedEvent, value); }
113 remove { Events.RemoveHandler (PageIndexChangedEvent, value); }
116 public event GridViewPageEventHandler PageIndexChanging {
117 add { Events.AddHandler (PageIndexChangingEvent, value); }
118 remove { Events.RemoveHandler (PageIndexChangingEvent, value); }
121 public event GridViewCancelEditEventHandler RowCancelingEdit {
122 add { Events.AddHandler (RowCancelingEditEvent, value); }
123 remove { Events.RemoveHandler (RowCancelingEditEvent, value); }
126 public event GridViewCommandEventHandler RowCommand {
127 add { Events.AddHandler (RowCommandEvent, value); }
128 remove { Events.RemoveHandler (RowCommandEvent, value); }
131 public event GridViewRowEventHandler RowCreated {
132 add { Events.AddHandler (RowCreatedEvent, value); }
133 remove { Events.RemoveHandler (RowCreatedEvent, value); }
136 public event GridViewRowEventHandler RowDataBound {
137 add { Events.AddHandler (RowDataBoundEvent, value); }
138 remove { Events.RemoveHandler (RowDataBoundEvent, value); }
141 public event GridViewDeletedEventHandler RowDeleted {
142 add { Events.AddHandler (RowDeletedEvent, value); }
143 remove { Events.RemoveHandler (RowDeletedEvent, value); }
146 public event GridViewDeleteEventHandler RowDeleting {
147 add { Events.AddHandler (RowDeletingEvent, value); }
148 remove { Events.RemoveHandler (RowDeletingEvent, value); }
151 public event GridViewEditEventHandler RowEditing {
152 add { Events.AddHandler (RowEditingEvent, value); }
153 remove { Events.RemoveHandler (RowEditingEvent, value); }
156 public event GridViewUpdatedEventHandler RowUpdated {
157 add { Events.AddHandler (RowUpdatedEvent, value); }
158 remove { Events.RemoveHandler (RowUpdatedEvent, value); }
161 public event GridViewUpdateEventHandler RowUpdating {
162 add { Events.AddHandler (RowUpdatingEvent, value); }
163 remove { Events.RemoveHandler (RowUpdatingEvent, value); }
166 public event EventHandler SelectedIndexChanged {
167 add { Events.AddHandler (SelectedIndexChangedEvent, value); }
168 remove { Events.RemoveHandler (SelectedIndexChangedEvent, value); }
171 public event GridViewSelectEventHandler SelectedIndexChanging {
172 add { Events.AddHandler (SelectedIndexChangingEvent, value); }
173 remove { Events.RemoveHandler (SelectedIndexChangingEvent, value); }
176 public event EventHandler Sorted {
177 add { Events.AddHandler (SortedEvent, value); }
178 remove { Events.RemoveHandler (SortedEvent, value); }
181 public event GridViewSortEventHandler Sorting {
182 add { Events.AddHandler (SortingEvent, value); }
183 remove { Events.RemoveHandler (SortingEvent, value); }
186 protected virtual void OnPageIndexChanged (EventArgs e)
188 if (Events != null) {
189 EventHandler eh = (EventHandler) Events [PageIndexChangedEvent];
190 if (eh != null) eh (this, e);
194 protected virtual void OnPageIndexChanging (GridViewPageEventArgs e)
196 if (Events != null) {
197 GridViewPageEventHandler eh = (GridViewPageEventHandler) Events [PageIndexChangingEvent];
203 if (!IsBoundUsingDataSourceID)
204 throw new HttpException (String.Format ("The GridView '{0}' fired event PageIndexChanging which wasn't handled.", ID));
207 protected virtual void OnRowCancelingEdit (GridViewCancelEditEventArgs e)
209 if (Events != null) {
210 GridViewCancelEditEventHandler eh = (GridViewCancelEditEventHandler) Events [RowCancelingEditEvent];
216 if (!IsBoundUsingDataSourceID)
217 throw new HttpException (String.Format ("The GridView '{0}' fired event RowCancelingEdit which wasn't handled.", ID));
220 protected virtual void OnRowCommand (GridViewCommandEventArgs e)
222 if (Events != null) {
223 GridViewCommandEventHandler eh = (GridViewCommandEventHandler) Events [RowCommandEvent];
224 if (eh != null) eh (this, e);
228 protected virtual void OnRowCreated (GridViewRowEventArgs e)
230 if (Events != null) {
231 GridViewRowEventHandler eh = (GridViewRowEventHandler) Events [RowCreatedEvent];
232 if (eh != null) eh (this, e);
236 protected virtual void OnRowDataBound (GridViewRowEventArgs e)
238 if (Events != null) {
239 GridViewRowEventHandler eh = (GridViewRowEventHandler) Events [RowDataBoundEvent];
240 if (eh != null) eh (this, e);
244 protected virtual void OnRowDeleted (GridViewDeletedEventArgs e)
246 if (Events != null) {
247 GridViewDeletedEventHandler eh = (GridViewDeletedEventHandler) Events [RowDeletedEvent];
248 if (eh != null) eh (this, e);
252 protected virtual void OnRowDeleting (GridViewDeleteEventArgs e)
254 if (Events != null) {
255 GridViewDeleteEventHandler eh = (GridViewDeleteEventHandler) Events [RowDeletingEvent];
261 if (!IsBoundUsingDataSourceID)
262 throw new HttpException (String.Format ("The GridView '{0}' fired event RowDeleting which wasn't handled.", ID));
265 protected virtual void OnRowEditing (GridViewEditEventArgs e)
267 if (Events != null) {
268 GridViewEditEventHandler eh = (GridViewEditEventHandler) Events [RowEditingEvent];
274 if (!IsBoundUsingDataSourceID)
275 throw new HttpException (String.Format ("The GridView '{0}' fired event RowEditing which wasn't handled.", ID));
278 protected virtual void OnRowUpdated (GridViewUpdatedEventArgs e)
280 if (Events != null) {
281 GridViewUpdatedEventHandler eh = (GridViewUpdatedEventHandler) Events [RowUpdatedEvent];
282 if (eh != null) eh (this, e);
286 protected virtual void OnRowUpdating (GridViewUpdateEventArgs e)
288 if (Events != null) {
289 GridViewUpdateEventHandler eh = (GridViewUpdateEventHandler) Events [RowUpdatingEvent];
295 if (!IsBoundUsingDataSourceID)
296 throw new HttpException (String.Format ("The GridView '{0}' fired event RowUpdating which wasn't handled.", ID));
299 protected virtual void OnSelectedIndexChanged (EventArgs e)
301 if (Events != null) {
302 EventHandler eh = (EventHandler) Events [SelectedIndexChangedEvent];
303 if (eh != null) eh (this, e);
307 protected virtual void OnSelectedIndexChanging (GridViewSelectEventArgs e)
309 if (Events != null) {
310 GridViewSelectEventHandler eh = (GridViewSelectEventHandler) Events [SelectedIndexChangingEvent];
311 if (eh != null) eh (this, e);
315 protected virtual void OnSorted (EventArgs e)
317 if (Events != null) {
318 EventHandler eh = (EventHandler) Events [SortedEvent];
319 if (eh != null) eh (this, e);
323 protected virtual void OnSorting (GridViewSortEventArgs e)
325 if (Events != null) {
326 GridViewSortEventHandler eh = (GridViewSortEventHandler) Events [SortingEvent];
332 if (!IsBoundUsingDataSourceID)
333 throw new HttpException (String.Format ("The GridView '{0}' fired event Sorting which wasn't handled.", ID));
337 [WebCategoryAttribute ("Paging")]
338 [DefaultValueAttribute (false)]
339 public virtual bool AllowPaging {
341 object ob = ViewState ["AllowPaging"];
342 if (ob != null) return (bool) ob;
346 ViewState ["AllowPaging"] = value;
351 [WebCategoryAttribute ("Behavior")]
352 [DefaultValueAttribute (false)]
353 public virtual bool AllowSorting {
355 object ob = ViewState ["AllowSorting"];
356 if (ob != null) return (bool) ob;
360 ViewState ["AllowSorting"] = value;
365 [WebCategoryAttribute ("Styles")]
366 [PersistenceMode (PersistenceMode.InnerProperty)]
367 [NotifyParentProperty (true)]
368 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
369 public TableItemStyle AlternatingRowStyle {
371 if (alternatingRowStyle == null) {
372 alternatingRowStyle = new TableItemStyle ();
373 if (IsTrackingViewState)
374 alternatingRowStyle.TrackViewState();
376 return alternatingRowStyle;
380 [WebCategoryAttribute ("Behavior")]
381 [DefaultValueAttribute (false)]
382 public virtual bool AutoGenerateEditButton {
384 object ob = ViewState ["AutoGenerateEditButton"];
385 if (ob != null) return (bool) ob;
389 ViewState ["AutoGenerateEditButton"] = value;
394 [WebCategoryAttribute ("Behavior")]
395 [DefaultValueAttribute (false)]
396 public virtual bool AutoGenerateDeleteButton {
398 object ob = ViewState ["AutoGenerateDeleteButton"];
399 if (ob != null) return (bool) ob;
403 ViewState ["AutoGenerateDeleteButton"] = value;
408 [WebCategoryAttribute ("Behavior")]
409 [DefaultValueAttribute (false)]
410 public virtual bool AutoGenerateSelectButton {
412 object ob = ViewState ["AutoGenerateSelectButton"];
413 if (ob != null) return (bool) ob;
417 ViewState ["AutoGenerateSelectButton"] = value;
422 [WebCategoryAttribute ("Behavior")]
423 [DefaultValueAttribute (true)]
424 public virtual bool AutoGenerateColumns {
426 object ob = ViewState ["AutoGenerateColumns"];
427 if (ob != null) return (bool) ob;
431 ViewState ["AutoGenerateColumns"] = value;
436 [UrlPropertyAttribute]
437 [WebCategoryAttribute ("Appearance")]
438 [DefaultValueAttribute ("")]
439 [EditorAttribute ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
440 public virtual string BackImageUrl {
442 if (ControlStyleCreated)
443 return ((TableStyle) ControlStyle).BackImageUrl;
447 ((TableStyle) ControlStyle).BackImageUrl = value;
451 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
452 [BrowsableAttribute (false)]
453 public virtual GridViewRow BottomPagerRow {
456 return bottomPagerRow;
460 [WebCategoryAttribute ("Accessibility")]
461 [DefaultValueAttribute ("")]
462 [LocalizableAttribute (true)]
463 public virtual string Caption {
465 object ob = ViewState ["Caption"];
466 if (ob != null) return (string) ob;
470 ViewState ["Caption"] = value;
475 [WebCategoryAttribute ("Accessibility")]
476 [DefaultValueAttribute (TableCaptionAlign.NotSet)]
477 public virtual TableCaptionAlign CaptionAlign
480 object o = ViewState ["CaptionAlign"];
481 if(o != null) return (TableCaptionAlign) o;
482 return TableCaptionAlign.NotSet;
485 ViewState ["CaptionAlign"] = value;
490 [WebCategoryAttribute ("Layout")]
491 [DefaultValueAttribute (-1)]
492 public virtual int CellPadding
495 if (ControlStyleCreated)
496 return ((TableStyle) ControlStyle).CellPadding;
500 ((TableStyle) ControlStyle).CellPadding = value;
504 [WebCategoryAttribute ("Layout")]
505 [DefaultValueAttribute (0)]
506 public virtual int CellSpacing
509 if (ControlStyleCreated)
510 return ((TableStyle) ControlStyle).CellSpacing;
514 ((TableStyle) ControlStyle).CellSpacing = value;
518 [EditorAttribute ("System.Web.UI.Design.WebControls.DataControlFieldTypeEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
519 [MergablePropertyAttribute (false)]
520 [PersistenceModeAttribute (PersistenceMode.InnerProperty)]
521 [DefaultValueAttribute (null)]
522 [WebCategoryAttribute ("Misc")]
523 public virtual DataControlFieldCollection Columns {
525 if (columns == null) {
526 columns = new DataControlFieldCollection ();
527 columns.FieldsChanged += new EventHandler (OnFieldsChanged);
528 if (IsTrackingViewState)
529 ((IStateManager)columns).TrackViewState ();
535 [DefaultValueAttribute (null)]
536 [WebCategoryAttribute ("Data")]
537 [TypeConverter (typeof(StringArrayConverter))]
538 [EditorAttribute ("System.Web.UI.Design.WebControls.DataFieldEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
539 public virtual string[] DataKeyNames
542 if (dataKeyNames != null)
547 dataKeyNames = value;
552 ArrayList DataKeyArrayList {
554 if (_dataKeyArrayList == null) {
555 _dataKeyArrayList = new ArrayList ();
557 return _dataKeyArrayList;
561 [BrowsableAttribute (false)]
562 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
563 public virtual DataKeyArray DataKeys {
566 keys = new DataKeyArray (DataKeyArrayList);
567 if (IsTrackingViewState)
568 ((IStateManager) keys).TrackViewState ();
574 DataKey OldEditValues {
576 if (oldEditValues == null) {
577 oldEditValues = new DataKey (new OrderedDictionary ());
579 return oldEditValues;
583 [WebCategoryAttribute ("Misc")]
584 [DefaultValueAttribute (-1)]
585 public virtual int EditIndex {
590 if (value == editIndex)
597 [WebCategoryAttribute ("Styles")]
598 [PersistenceMode (PersistenceMode.InnerProperty)]
599 [NotifyParentProperty (true)]
600 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
601 public TableItemStyle EditRowStyle {
603 if (editRowStyle == null) {
604 editRowStyle = new TableItemStyle ();
605 if (IsTrackingViewState)
606 editRowStyle.TrackViewState();
612 [WebCategoryAttribute ("Styles")]
613 [PersistenceMode (PersistenceMode.InnerProperty)]
614 [NotifyParentProperty (true)]
615 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
616 public TableItemStyle EmptyDataRowStyle {
618 if (emptyDataRowStyle == null) {
619 emptyDataRowStyle = new TableItemStyle ();
620 if (IsTrackingViewState)
621 emptyDataRowStyle.TrackViewState();
623 return emptyDataRowStyle;
627 [DefaultValue (null)]
628 [TemplateContainer (typeof(GridViewRow), BindingDirection.OneWay)]
629 [PersistenceMode (PersistenceMode.InnerProperty)]
631 public virtual ITemplate EmptyDataTemplate {
632 get { return emptyDataTemplate; }
633 set { emptyDataTemplate = value; RequireBinding (); }
636 [LocalizableAttribute (true)]
637 [WebCategoryAttribute ("Appearance")]
638 [DefaultValueAttribute ("")]
639 public virtual string EmptyDataText {
641 object ob = ViewState ["EmptyDataText"];
642 if (ob != null) return (string) ob;
646 ViewState ["EmptyDataText"] = value;
651 [WebCategoryAttribute ("Behavior")]
652 [DefaultValueAttribute (false)]
653 public virtual bool EnableSortingAndPagingCallbacks {
655 object ob = ViewState ["EnableSortingAndPagingCallbacks"];
656 if (ob != null) return (bool) ob;
660 ViewState ["EnableSortingAndPagingCallbacks"] = value;
665 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
666 [BrowsableAttribute (false)]
667 public virtual GridViewRow FooterRow {
670 for (int index = table.Rows.Count - 1; index >= 0; index--) {
671 GridViewRow row = (GridViewRow) table.Rows [index];
672 switch (row.RowType) {
673 case DataControlRowType.Separator:
674 case DataControlRowType.Pager:
676 case DataControlRowType.Footer:
687 [WebCategoryAttribute ("Styles")]
688 [PersistenceMode (PersistenceMode.InnerProperty)]
689 [NotifyParentProperty (true)]
690 [DefaultValue (null)]
691 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
692 public TableItemStyle FooterStyle {
694 if (footerStyle == null) {
695 footerStyle = new TableItemStyle ();
696 if (IsTrackingViewState)
697 footerStyle.TrackViewState();
703 [WebCategoryAttribute ("Appearance")]
704 [DefaultValueAttribute (GridLines.Both)]
705 public virtual GridLines GridLines {
707 if (ControlStyleCreated)
708 return ((TableStyle) ControlStyle).GridLines;
709 return GridLines.Both;
712 ((TableStyle) ControlStyle).GridLines = value;
716 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
717 [BrowsableAttribute (false)]
718 public virtual GridViewRow HeaderRow {
721 for (int index = 0, total = table.Rows.Count; index < total; index++) {
722 GridViewRow row = (GridViewRow) table.Rows [index];
723 switch (row.RowType) {
724 case DataControlRowType.Separator:
725 case DataControlRowType.Pager:
727 case DataControlRowType.Header:
738 [WebCategoryAttribute ("Styles")]
739 [PersistenceMode (PersistenceMode.InnerProperty)]
740 [NotifyParentProperty (true)]
741 [DefaultValue (null)]
742 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
743 public TableItemStyle HeaderStyle {
745 if (headerStyle == null) {
746 headerStyle = new TableItemStyle ();
747 if (IsTrackingViewState)
748 headerStyle.TrackViewState();
754 [Category ("Layout")]
755 [DefaultValueAttribute (HorizontalAlign.NotSet)]
756 public virtual HorizontalAlign HorizontalAlign {
758 if (ControlStyleCreated)
759 return ((TableStyle) ControlStyle).HorizontalAlign;
760 return HorizontalAlign.NotSet;
763 ((TableStyle) ControlStyle).HorizontalAlign = value;
767 [BrowsableAttribute (false)]
768 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
769 public virtual int PageCount {
771 return ViewState.GetInt ("PageCount", 0);
774 ViewState ["PageCount"] = value;
778 [WebCategoryAttribute ("Paging")]
779 [BrowsableAttribute (true)]
780 [DefaultValueAttribute (0)]
781 public virtual int PageIndex {
786 if (value == pageIndex)
793 [DefaultValueAttribute (10)]
794 [WebCategoryAttribute ("Paging")]
795 public virtual int PageSize {
797 object ob = ViewState ["PageSize"];
798 if (ob != null) return (int) ob;
802 ViewState ["PageSize"] = value;
807 [WebCategoryAttribute ("Paging")]
808 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Content)]
809 [NotifyParentPropertyAttribute (true)]
810 [PersistenceModeAttribute (PersistenceMode.InnerProperty)]
811 public virtual PagerSettings PagerSettings {
813 if (pagerSettings == null) {
814 pagerSettings = new PagerSettings (this);
815 if (IsTrackingViewState)
816 ((IStateManager)pagerSettings).TrackViewState ();
818 return pagerSettings;
822 [WebCategoryAttribute ("Styles")]
823 [PersistenceMode (PersistenceMode.InnerProperty)]
824 [NotifyParentProperty (true)]
825 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
826 public TableItemStyle PagerStyle {
828 if (pagerStyle == null) {
829 pagerStyle = new TableItemStyle ();
830 if (IsTrackingViewState)
831 pagerStyle.TrackViewState();
838 [DefaultValue (null)]
839 /* DataControlPagerCell isnt specified in the docs */
840 //[TemplateContainer (typeof(DataControlPagerCell), BindingDirection.OneWay)]
841 [PersistenceMode (PersistenceMode.InnerProperty)]
843 public virtual ITemplate PagerTemplate {
844 get { return pagerTemplate; }
845 set { pagerTemplate = value; RequireBinding (); }
848 [DefaultValueAttribute ("")]
849 [WebCategoryAttribute ("Accessibility")]
850 // [TypeConverterAttribute (typeof(System.Web.UI.Design.DataColumnSelectionConverter)]
851 public virtual string RowHeaderColumn {
853 object ob = ViewState ["RowHeaderColumn"];
854 if (ob != null) return (string) ob;
858 ViewState ["RowHeaderColumn"] = value;
863 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
864 [BrowsableAttribute (false)]
865 public virtual GridViewRowCollection Rows {
867 EnsureChildControls ();
869 rows = new GridViewRowCollection (new ArrayList ());
874 [WebCategoryAttribute ("Styles")]
875 [PersistenceMode (PersistenceMode.InnerProperty)]
876 [NotifyParentProperty (true)]
877 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
878 public TableItemStyle RowStyle {
880 if (rowStyle == null) {
881 rowStyle = new TableItemStyle ();
882 if (IsTrackingViewState)
883 rowStyle.TrackViewState();
889 [BrowsableAttribute (false)]
890 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
891 public virtual DataKey SelectedDataKey {
893 if (DataKeyNames.Length == 0)
894 throw new InvalidOperationException (String.Format ("Data keys must be specified on GridView '{0}' before the selected data keys can be retrieved. Use the DataKeyNames property to specify data keys.", ID));
896 if (selectedIndex >= 0 && selectedIndex < DataKeys.Count) {
897 return DataKeys [selectedIndex];
903 [BindableAttribute (true)]
904 [DefaultValueAttribute (-1)]
905 public virtual int SelectedIndex {
907 return selectedIndex;
910 if (rows != null && selectedIndex >= 0 && selectedIndex < Rows.Count) {
911 int oldIndex = selectedIndex;
913 Rows [oldIndex].RowState = GetRowState (oldIndex);
915 selectedIndex = value;
916 if (rows != null && selectedIndex >= 0 && selectedIndex < Rows.Count) {
917 Rows [selectedIndex].RowState = GetRowState (selectedIndex);
922 [BrowsableAttribute (false)]
923 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
924 public virtual GridViewRow SelectedRow {
926 if (selectedIndex >= 0 && selectedIndex < Rows.Count) {
927 return Rows [selectedIndex];
933 [WebCategoryAttribute ("Styles")]
934 [PersistenceMode (PersistenceMode.InnerProperty)]
935 [NotifyParentProperty (true)]
936 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
937 public TableItemStyle SelectedRowStyle {
939 if (selectedRowStyle == null) {
940 selectedRowStyle = new TableItemStyle ();
941 if (IsTrackingViewState)
942 selectedRowStyle.TrackViewState();
944 return selectedRowStyle;
948 [BrowsableAttribute (false)]
949 public object SelectedValue {
951 if (SelectedDataKey != null)
952 return SelectedDataKey.Value;
958 [WebCategoryAttribute ("Appearance")]
959 [DefaultValueAttribute (false)]
960 public virtual bool ShowFooter {
962 object ob = ViewState ["ShowFooter"];
963 if (ob != null) return (bool) ob;
967 ViewState ["ShowFooter"] = value;
972 [WebCategoryAttribute ("Appearance")]
973 [DefaultValueAttribute (true)]
974 public virtual bool ShowHeader {
976 object ob = ViewState ["ShowHeader"];
977 if (ob != null) return (bool) ob;
981 ViewState ["ShowHeader"] = value;
986 [PersistenceModeAttribute (PersistenceMode.InnerProperty)]
987 [BrowsableAttribute (false)]
988 [DefaultValueAttribute (SortDirection.Ascending)]
989 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
990 public virtual SortDirection SortDirection {
991 get { return sortDirection; }
993 if (sortDirection == value)
995 sortDirection = value;
1000 [BrowsableAttribute (false)]
1001 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
1002 public virtual string SortExpression {
1004 if (sortExpression == null)
1005 return String.Empty;
1006 return sortExpression;
1009 if (sortExpression == value)
1011 sortExpression = value;
1016 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
1017 [BrowsableAttribute (false)]
1018 public virtual GridViewRow TopPagerRow {
1025 [WebCategoryAttribute ("Accessibility")]
1026 [DefaultValueAttribute (true)]
1027 public virtual bool UseAccessibleHeader {
1029 object ob = ViewState ["UseAccessibleHeader"];
1030 if (ob != null) return (bool) ob;
1034 ViewState ["UseAccessibleHeader"] = value;
1039 public virtual bool IsBindableType (Type type)
1041 return type.IsPrimitive || type == typeof (string) || type == typeof (decimal) || type == typeof (DateTime) || type == typeof (Guid);
1044 // MSDN: The CreateDataSourceSelectArguments method is a helper method called by
1045 // the GridView control to create the DataSourceSelectArguments object that
1046 // contains the arguments passed to the data source. In this implementation,
1047 // the DataSourceSelectArguments object contains the arguments for paging operations.
1048 protected override DataSourceSelectArguments CreateDataSourceSelectArguments ()
1050 DataSourceSelectArguments arg = DataSourceSelectArguments.Empty;
1051 DataSourceView view= GetData();
1052 if (AllowPaging && view.CanPage) {
1053 arg.StartRowIndex = PageIndex * PageSize;
1054 if (view.CanRetrieveTotalRowCount) {
1055 arg.RetrieveTotalRowCount = true;
1056 arg.MaximumRows = PageSize;
1059 arg.MaximumRows = -1;
1063 if (IsBoundUsingDataSourceID && !String.IsNullOrEmpty (sortExpression)) {
1064 if (sortDirection == SortDirection.Ascending)
1065 arg.SortExpression = sortExpression;
1067 arg.SortExpression = sortExpression + " DESC";
1073 protected virtual ICollection CreateColumns (PagedDataSource dataSource, bool useDataSource)
1075 ArrayList fields = new ArrayList ();
1077 if (AutoGenerateEditButton || AutoGenerateDeleteButton || AutoGenerateSelectButton) {
1078 CommandField field = new CommandField ();
1079 field.ShowEditButton = AutoGenerateEditButton;
1080 field.ShowDeleteButton = AutoGenerateDeleteButton;
1081 field.ShowSelectButton = AutoGenerateSelectButton;
1085 fields.AddRange (Columns);
1087 if (AutoGenerateColumns) {
1089 autoFieldProperties = CreateAutoFieldProperties (dataSource);
1091 if (autoFieldProperties != null) {
1092 foreach (AutoGeneratedFieldProperties props in autoFieldProperties)
1093 fields.Add (CreateAutoGeneratedColumn (props));
1100 protected virtual AutoGeneratedField CreateAutoGeneratedColumn (AutoGeneratedFieldProperties fieldProperties)
1102 return new AutoGeneratedField (fieldProperties);
1105 AutoGeneratedFieldProperties[] CreateAutoFieldProperties (PagedDataSource source)
1107 if(source == null) return null;
1109 PropertyDescriptorCollection props = source.GetItemProperties (new PropertyDescriptor[0]);
1112 ArrayList retVal = new ArrayList();
1116 object fitem = null;
1118 PropertyInfo prop_item = source.DataSource.GetType().GetProperty("Item",
1119 BindingFlags.Instance | BindingFlags.Static |
1120 BindingFlags.Public, null, null,
1121 new Type[] { typeof(int) }, null);
1123 if (prop_item != null) {
1124 prop_type = prop_item.PropertyType;
1127 if (prop_type == null || prop_type == typeof(object)) {
1128 IEnumerator en = source.GetEnumerator();
1132 prop_type = fitem.GetType();
1135 if (fitem != null && fitem is ICustomTypeDescriptor) {
1136 props = TypeDescriptor.GetProperties(fitem);
1137 } else if (prop_type != null) {
1138 if (IsBindableType (prop_type)) {
1139 AutoGeneratedFieldProperties field = new AutoGeneratedFieldProperties ();
1140 ((IStateManager)field).TrackViewState();
1141 field.Name = "Item";
1142 field.DataField = BoundField.ThisExpression;
1143 field.Type = prop_type;
1146 props = TypeDescriptor.GetProperties (prop_type);
1151 if (props != null && props.Count > 0)
1153 foreach (PropertyDescriptor current in props) {
1154 if (IsBindableType (current.PropertyType)) {
1155 AutoGeneratedFieldProperties field = new AutoGeneratedFieldProperties ();
1156 ((IStateManager)field).TrackViewState();
1157 field.Name = current.Name;
1158 field.DataField = current.Name;
1159 for (int i = 0; i < DataKeyNames.Length; i++) {
1160 if (string.Compare (DataKeyNames [i], current.Name, StringComparison.InvariantCultureIgnoreCase) == 0) {
1161 field.IsReadOnly = true;
1165 field.Type = current.PropertyType;
1171 if (retVal.Count > 0)
1172 return (AutoGeneratedFieldProperties[]) retVal.ToArray (typeof(AutoGeneratedFieldProperties));
1174 return new AutoGeneratedFieldProperties [0];
1177 protected virtual GridViewRow CreateRow (int rowIndex, int dataSourceIndex, DataControlRowType rowType, DataControlRowState rowState)
1179 GridViewRow row = new GridViewRow (rowIndex, dataSourceIndex, rowType, rowState);
1183 void RequireBinding ()
1186 RequiresDataBinding = true;
1190 protected virtual Table CreateChildTable ()
1192 return new ContainedTable (this);
1195 protected override int CreateChildControls (IEnumerable data, bool dataBinding)
1206 PagedDataSource dataSource;
1209 DataSourceView view = GetData ();
1210 dataSource = new PagedDataSource ();
1211 dataSource.DataSource = data;
1214 dataSource.AllowPaging = true;
1215 dataSource.PageSize = PageSize;
1216 dataSource.CurrentPageIndex = PageIndex;
1218 dataSource.AllowServerPaging = true;
1219 if (SelectArguments.RetrieveTotalRowCount)
1220 dataSource.VirtualCount = SelectArguments.TotalRowCount;
1224 PageCount = dataSource.PageCount;
1228 dataSource = new PagedDataSource ();
1229 dataSource.DataSource = data;
1231 dataSource.AllowPaging = true;
1232 dataSource.PageSize = PageSize;
1233 dataSource.CurrentPageIndex = PageIndex;
1237 bool showPager = AllowPaging && (PageCount > 1);
1239 ArrayList list = new ArrayList ();
1241 // Creates the set of fields to show
1243 ICollection fieldCollection = CreateColumns (dataSource, dataBinding);
1244 DataControlField[] fields = new DataControlField [fieldCollection.Count];
1245 fieldCollection.CopyTo (fields, 0);
1247 foreach (DataControlField field in fields) {
1248 field.Initialize (AllowSorting, this);
1249 if (EnableSortingAndPagingCallbacks)
1250 field.ValidateSupportsCallback ();
1253 // Main table creation
1254 foreach (object obj in dataSource) {
1256 if (list.Count == 0) {
1257 if (showPager && PagerSettings.Position == PagerPosition.Top || PagerSettings.Position == PagerPosition.TopAndBottom) {
1258 topPagerRow = CreatePagerRow (fields.Length, dataSource);
1259 OnRowCreated (new GridViewRowEventArgs (topPagerRow));
1260 ContainedTable.Rows.Add (topPagerRow);
1262 topPagerRow.DataBind ();
1263 OnRowDataBound (new GridViewRowEventArgs (topPagerRow));
1267 GridViewRow headerRow = CreateRow (-1, -1, DataControlRowType.Header, DataControlRowState.Normal);
1268 InitializeRow (headerRow, fields);
1269 OnRowCreated (new GridViewRowEventArgs (headerRow));
1270 ContainedTable.Rows.Add (headerRow);
1272 headerRow.DataBind ();
1273 OnRowDataBound (new GridViewRowEventArgs (headerRow));
1277 DataControlRowState rstate = GetRowState (list.Count);
1278 GridViewRow row = CreateRow (list.Count, list.Count, DataControlRowType.DataRow, rstate);
1281 InitializeRow (row, fields);
1282 OnRowCreated (new GridViewRowEventArgs (row));
1283 ContainedTable.Rows.Add (row);
1286 OnRowDataBound (new GridViewRowEventArgs (row));
1287 if (EditIndex == row.RowIndex)
1288 oldEditValues = new DataKey (GetRowValues (row, true, true));
1289 DataKeyArrayList.Add (new DataKey (CreateRowDataKey (row), DataKeyNames));
1293 if (list.Count == 0) {
1294 GridViewRow emptyRow = CreateEmptyrRow (fields.Length);
1295 if (emptyRow != null) {
1296 OnRowCreated (new GridViewRowEventArgs (emptyRow));
1297 ContainedTable.Rows.Add (emptyRow);
1299 emptyRow.DataBind ();
1300 OnRowDataBound (new GridViewRowEventArgs (emptyRow));
1306 GridViewRow footerRow = CreateRow (-1, -1, DataControlRowType.Footer, DataControlRowState.Normal);
1307 InitializeRow (footerRow, fields);
1308 OnRowCreated (new GridViewRowEventArgs (footerRow));
1309 ContainedTable.Rows.Add (footerRow);
1311 footerRow.DataBind ();
1312 OnRowDataBound (new GridViewRowEventArgs (footerRow));
1315 if (showPager && PagerSettings.Position == PagerPosition.Bottom || PagerSettings.Position == PagerPosition.TopAndBottom) {
1316 bottomPagerRow = CreatePagerRow (fields.Length, dataSource);
1317 OnRowCreated (new GridViewRowEventArgs (bottomPagerRow));
1318 ContainedTable.Rows.Add (bottomPagerRow);
1320 bottomPagerRow.DataBind ();
1321 OnRowDataBound (new GridViewRowEventArgs (bottomPagerRow));
1326 rows = new GridViewRowCollection (list);
1332 return dataSource.DataSourceCount;
1337 Table ContainedTable {
1339 if (table == null) {
1340 table = CreateChildTable ();
1341 Controls.Add (table);
1347 protected override Style CreateControlStyle ()
1349 TableStyle style = new TableStyle (ViewState);
1350 style.GridLines = GridLines.Both;
1351 style.CellSpacing = 0;
1355 DataControlRowState GetRowState (int index)
1357 DataControlRowState rstate = (index % 2) == 0 ? DataControlRowState.Normal : DataControlRowState.Alternate;
1358 if (index == SelectedIndex) rstate |= DataControlRowState.Selected;
1359 if (index == EditIndex) rstate |= DataControlRowState.Edit;
1363 GridViewRow CreatePagerRow (int fieldCount, PagedDataSource dataSource)
1365 GridViewRow row = CreateRow (-1, -1, DataControlRowType.Pager, DataControlRowState.Normal);
1366 InitializePager (row, fieldCount, dataSource);
1370 protected virtual void InitializePager (GridViewRow row, int columnSpan, PagedDataSource dataSource)
1372 TableCell cell = new TableCell ();
1374 cell.ColumnSpan = columnSpan;
1376 if (pagerTemplate != null)
1377 pagerTemplate.InstantiateIn (cell);
1379 cell.Controls.Add (PagerSettings.CreatePagerControl (dataSource.CurrentPageIndex, dataSource.PageCount));
1381 row.Cells.Add (cell);
1384 GridViewRow CreateEmptyrRow (int fieldCount)
1386 if (emptyDataTemplate == null && String.IsNullOrEmpty (EmptyDataText))
1389 GridViewRow row = CreateRow (-1, -1, DataControlRowType.EmptyDataRow, DataControlRowState.Normal);
1390 TableCell cell = new TableCell ();
1391 cell.ColumnSpan = fieldCount;
1393 if (emptyDataTemplate != null)
1394 emptyDataTemplate.InstantiateIn (cell);
1396 cell.Text = EmptyDataText;
1398 row.Cells.Add (cell);
1402 protected virtual void InitializeRow (GridViewRow row, DataControlField[] fields)
1404 DataControlCellType ctype;
1405 bool accessibleHeader = false;
1407 switch (row.RowType) {
1408 case DataControlRowType.Header:
1409 ctype = DataControlCellType.Header;
1410 accessibleHeader = UseAccessibleHeader;
1412 case DataControlRowType.Footer:
1413 ctype = DataControlCellType.Footer;
1416 ctype = DataControlCellType.DataCell;
1420 for (int n=0; n<fields.Length; n++) {
1421 DataControlField field = fields [n];
1422 DataControlFieldCell cell;
1423 if (((field is BoundField) && ((BoundField)field).DataField == RowHeaderColumn) || accessibleHeader)
1424 cell = new DataControlFieldHeaderCell (field, accessibleHeader ? TableHeaderScope.Column : TableHeaderScope.Row);
1426 cell = new DataControlFieldCell (field);
1427 row.Cells.Add (cell);
1428 field.InitializeCell (cell, ctype, row.RowState, row.RowIndex);
1432 IOrderedDictionary CreateRowDataKey (GridViewRow row)
1434 if (cachedKeyProperties == null) {
1435 PropertyDescriptorCollection props = TypeDescriptor.GetProperties (row.DataItem);
1436 cachedKeyProperties = new PropertyDescriptor [DataKeyNames.Length];
1437 for (int n=0; n<DataKeyNames.Length; n++) {
1438 PropertyDescriptor p = props.Find (DataKeyNames [n], true);
1440 throw new InvalidOperationException ("Property '" + DataKeyNames [n] + "' not found in object of type " + row.DataItem.GetType ());
1441 cachedKeyProperties [n] = p;
1445 OrderedDictionary dic = new OrderedDictionary ();
1446 foreach (PropertyDescriptor p in cachedKeyProperties)
1447 dic [p.Name] = p.GetValue (row.DataItem);
1451 IOrderedDictionary GetRowValues (GridViewRow row, bool includeReadOnlyFields, bool includePrimaryKey)
1453 OrderedDictionary dic = new OrderedDictionary ();
1454 ExtractRowValues (dic, row, includeReadOnlyFields, includePrimaryKey);
1458 protected virtual void ExtractRowValues (IOrderedDictionary fieldValues, GridViewRow row, bool includeReadOnlyFields, bool includePrimaryKey)
1460 foreach (TableCell cell in row.Cells) {
1461 DataControlFieldCell c = cell as DataControlFieldCell;
1463 c.ContainingField.ExtractValuesFromCell (fieldValues, c, row.RowState, includeReadOnlyFields);
1465 if (!includePrimaryKey && DataKeyNames != null)
1466 foreach (string key in DataKeyNames)
1467 fieldValues.Remove (key);
1470 protected override HtmlTextWriterTag TagKey {
1472 if (EnableSortingAndPagingCallbacks)
1473 return HtmlTextWriterTag.Div;
1475 return HtmlTextWriterTag.Table;
1479 public sealed override void DataBind ()
1481 DataKeyArrayList.Clear ();
1482 cachedKeyProperties = null;
1485 keys = new DataKeyArray (DataKeyArrayList);
1488 protected internal override void PerformDataBinding (IEnumerable data)
1490 base.PerformDataBinding (data);
1493 protected internal virtual void PrepareControlHierarchy ()
1498 table.Caption = Caption;
1499 table.CaptionAlign = CaptionAlign;
1501 foreach (GridViewRow row in table.Rows) {
1502 switch (row.RowType) {
1503 case DataControlRowType.Header:
1504 if (headerStyle != null && !headerStyle.IsEmpty)
1505 row.ControlStyle.MergeWith(headerStyle);
1506 row.Visible = ShowHeader;
1508 case DataControlRowType.Footer:
1509 if (footerStyle != null && !footerStyle.IsEmpty)
1510 row.ControlStyle.MergeWith (footerStyle);
1511 row.Visible = ShowFooter;
1513 case DataControlRowType.Pager:
1514 if (pagerStyle != null && !pagerStyle.IsEmpty)
1515 row.ControlStyle.MergeWith (pagerStyle);
1517 case DataControlRowType.EmptyDataRow:
1518 if (emptyDataRowStyle != null && !emptyDataRowStyle.IsEmpty)
1519 row.ControlStyle.MergeWith (emptyDataRowStyle);
1521 case DataControlRowType.DataRow:
1522 if ((row.RowState & DataControlRowState.Edit) != 0 && editRowStyle != null && !editRowStyle.IsEmpty)
1523 row.ControlStyle.MergeWith (editRowStyle);
1524 if ((row.RowState & DataControlRowState.Selected) != 0 && selectedRowStyle != null && !selectedRowStyle.IsEmpty)
1525 row.ControlStyle.MergeWith (selectedRowStyle);
1526 if ((row.RowState & DataControlRowState.Alternate) != 0 && alternatingRowStyle != null && !alternatingRowStyle.IsEmpty)
1527 row.ControlStyle.MergeWith (alternatingRowStyle);
1528 if (rowStyle != null && !rowStyle.IsEmpty)
1529 row.ControlStyle.MergeWith (rowStyle);
1535 foreach (TableCell cell in row.Cells) {
1536 DataControlFieldCell fcell = cell as DataControlFieldCell;
1537 if (fcell != null) {
1538 DataControlField field = fcell.ContainingField;
1539 switch (row.RowType) {
1540 case DataControlRowType.Header:
1541 if (field.HeaderStyleCreated && !field.HeaderStyle.IsEmpty)
1542 cell.ControlStyle.MergeWith (field.HeaderStyle);
1544 case DataControlRowType.Footer:
1545 if (field.FooterStyleCreated && !field.FooterStyle.IsEmpty)
1546 cell.ControlStyle.MergeWith (field.FooterStyle);
1549 if (field.ControlStyleCreated && !field.ControlStyle.IsEmpty)
1550 foreach (Control c in cell.Controls) {
1551 WebControl wc = c as WebControl;
1553 wc.ControlStyle.MergeWith (field.ControlStyle);
1555 if (field.ItemStyleCreated && !field.ItemStyle.IsEmpty)
1556 cell.ControlStyle.MergeWith (field.ItemStyle);
1564 protected internal override void OnInit (EventArgs e)
1566 Page.RegisterRequiresControlState (this);
1570 void OnFieldsChanged (object sender, EventArgs args)
1575 protected override void OnDataPropertyChanged ()
1577 base.OnDataPropertyChanged ();
1581 protected override void OnDataSourceViewChanged (object sender, EventArgs e)
1583 base.OnDataSourceViewChanged (sender, e);
1587 protected override bool OnBubbleEvent (object source, EventArgs e)
1589 GridViewCommandEventArgs args = e as GridViewCommandEventArgs;
1591 bool causesValidation = false;
1592 IButtonControl button = args.CommandSource as IButtonControl;
1593 if (button != null && button.CausesValidation) {
1594 Page.Validate (button.ValidationGroup);
1595 causesValidation = true;
1597 OnRowCommand (args);
1598 string param = args.CommandArgument as string;
1599 if (param == null || param.Length == 0) {
1600 GridViewRow row = args.Row;
1602 param = row.RowIndex.ToString();
1604 ProcessEvent (args.CommandName, param, causesValidation);
1607 return base.OnBubbleEvent (source, e);
1610 void IPostBackEventHandler.RaisePostBackEvent (string eventArgument)
1612 RaisePostBackEvent (eventArgument);
1615 // This is prolly obsolete
1616 protected virtual void RaisePostBackEvent (string eventArgument)
1618 GridViewCommandEventArgs args;
1619 int i = eventArgument.IndexOf ('$');
1621 args = new GridViewCommandEventArgs (this, new CommandEventArgs (eventArgument.Substring (0, i), eventArgument.Substring (i + 1)));
1623 args = new GridViewCommandEventArgs (this, new CommandEventArgs (eventArgument, null));
1625 OnRowCommand (args);
1626 ProcessEvent (args.CommandName, (string) args.CommandArgument, false);
1629 void ProcessEvent (string eventName, string param, bool causesValidation)
1633 case DataControlCommands.PageCommandName:
1636 case DataControlCommands.FirstPageCommandArgument:
1639 case DataControlCommands.LastPageCommandArgument:
1640 newIndex = PageCount - 1;
1642 case DataControlCommands.NextPageCommandArgument:
1643 newIndex = PageIndex + 1;
1645 case DataControlCommands.PreviousPageCommandArgument:
1646 newIndex = PageIndex - 1;
1650 int.TryParse (param, out paramIndex);
1651 newIndex = paramIndex - 1;
1654 ShowPage (newIndex);
1657 case DataControlCommands.FirstPageCommandArgument:
1661 case DataControlCommands.LastPageCommandArgument:
1662 ShowPage (PageCount - 1);
1665 case DataControlCommands.NextPageCommandArgument:
1666 if (PageIndex < PageCount - 1)
1667 ShowPage (PageIndex + 1);
1670 case DataControlCommands.PreviousPageCommandArgument:
1672 ShowPage (PageIndex - 1);
1675 case DataControlCommands.SelectCommandName:
1676 SelectRow (int.Parse (param));
1679 case DataControlCommands.EditCommandName:
1680 EditRow (int.Parse (param));
1683 case DataControlCommands.UpdateCommandName:
1684 int editIndex = int.Parse (param);
1685 UpdateRow (Rows [editIndex], editIndex, causesValidation);
1688 case DataControlCommands.CancelCommandName:
1692 case DataControlCommands.DeleteCommandName:
1693 DeleteRow (int.Parse (param));
1696 case DataControlCommands.SortCommandName:
1702 void Sort (string newSortExpression)
1704 SortDirection newDirection = SortDirection.Ascending;
1705 if (sortExpression == newSortExpression && sortDirection == SortDirection.Ascending)
1706 newDirection = SortDirection.Descending;
1708 Sort (newSortExpression, newDirection);
1711 public virtual void Sort (string newSortExpression, SortDirection newSortDirection)
1713 GridViewSortEventArgs args = new GridViewSortEventArgs (newSortExpression, newSortDirection);
1715 if (args.Cancel) return;
1717 if (IsBoundUsingDataSourceID) {
1720 SortExpression = args.SortExpression;
1721 SortDirection = args.SortDirection;
1724 OnSorted (EventArgs.Empty);
1727 void SelectRow (int index)
1729 GridViewSelectEventArgs args = new GridViewSelectEventArgs (index);
1730 OnSelectedIndexChanging (args);
1733 SelectedIndex = args.NewSelectedIndex;
1734 OnSelectedIndexChanged (EventArgs.Empty);
1738 void ShowPage (int newIndex)
1740 GridViewPageEventArgs args = new GridViewPageEventArgs (newIndex);
1741 OnPageIndexChanging (args);
1743 if (args.Cancel || !IsBoundUsingDataSourceID)
1747 PageIndex = args.NewPageIndex;
1748 OnPageIndexChanged (EventArgs.Empty);
1751 void EditRow (int index)
1753 GridViewEditEventArgs args = new GridViewEditEventArgs (index);
1754 OnRowEditing (args);
1756 if (args.Cancel || !IsBoundUsingDataSourceID)
1759 EditIndex = args.NewEditIndex;
1764 GridViewCancelEditEventArgs args = new GridViewCancelEditEventArgs (EditIndex);
1765 OnRowCancelingEdit (args);
1767 if (args.Cancel || !IsBoundUsingDataSourceID)
1773 [MonoTODO ("Support two-way binding expressions")]
1774 public virtual void UpdateRow (int rowIndex, bool causesValidation)
1776 if (rowIndex != EditIndex) throw new NotSupportedException ();
1778 GridViewRow row = Rows [rowIndex];
1779 UpdateRow (row, rowIndex, causesValidation);
1782 void UpdateRow (GridViewRow row, int rowIndex, bool causesValidation)
1784 if (causesValidation && Page != null && !Page.IsValid)
1787 currentEditOldValues = OldEditValues.Values;
1789 currentEditRowKeys = DataKeys [rowIndex].Values;
1790 currentEditNewValues = GetRowValues (row, false, false);
1792 GridViewUpdateEventArgs args = new GridViewUpdateEventArgs (rowIndex, currentEditRowKeys, currentEditOldValues, currentEditNewValues);
1793 OnRowUpdating (args);
1795 if (args.Cancel || !IsBoundUsingDataSourceID)
1798 DataSourceView view = GetData ();
1800 throw new HttpException ("The DataSourceView associated to data bound control was null");
1801 view.Update (currentEditRowKeys, currentEditNewValues, currentEditOldValues, new DataSourceViewOperationCallback (UpdateCallback));
1804 bool UpdateCallback (int recordsAffected, Exception exception)
1806 GridViewUpdatedEventArgs dargs = new GridViewUpdatedEventArgs (recordsAffected, exception, currentEditRowKeys, currentEditOldValues, currentEditNewValues);
1807 OnRowUpdated (dargs);
1809 if (!dargs.KeepInEditMode)
1812 return dargs.ExceptionHandled;
1815 public virtual void DeleteRow (int rowIndex)
1817 GridViewRow row = Rows [rowIndex];
1818 currentEditRowKeys = DataKeys [rowIndex].Values;
1819 currentEditNewValues = GetRowValues (row, true, true);
1821 GridViewDeleteEventArgs args = new GridViewDeleteEventArgs (rowIndex, currentEditRowKeys, currentEditNewValues);
1822 OnRowDeleting (args);
1824 if (args.Cancel || !IsBoundUsingDataSourceID)
1828 DataSourceView view = GetData ();
1830 view.Delete (currentEditRowKeys, currentEditNewValues, new DataSourceViewOperationCallback (DeleteCallback));
1832 GridViewDeletedEventArgs dargs = new GridViewDeletedEventArgs (0, null, currentEditRowKeys, currentEditNewValues);
1833 OnRowDeleted (dargs);
1837 bool DeleteCallback (int recordsAffected, Exception exception)
1839 GridViewDeletedEventArgs dargs = new GridViewDeletedEventArgs (recordsAffected, exception, currentEditRowKeys, currentEditNewValues);
1840 OnRowDeleted (dargs);
1841 return dargs.ExceptionHandled;
1847 oldEditValues = new DataKey (new OrderedDictionary ());
1848 currentEditRowKeys = null;
1849 currentEditOldValues = null;
1850 currentEditNewValues = null;
1853 protected internal override void LoadControlState (object ob)
1855 if (ob == null) return;
1856 object[] state = (object[]) ob;
1857 base.LoadControlState (state[0]);
1858 pageIndex = (int) state[1];
1859 selectedIndex = (int) state[2];
1860 editIndex = (int) state[3];
1861 sortExpression = (string) state[4];
1862 sortDirection = (SortDirection) state[5];
1863 DataKeyNames = (string []) state [6];
1864 if (state [7] != null)
1865 LoadDataKeyArrayState ((object []) state [7]);
1866 if (state [8] != null)
1867 ((IStateManager) OldEditValues).LoadViewState (state [8]);
1870 protected internal override object SaveControlState ()
1872 if (EnableSortingAndPagingCallbacks) {
1873 Page.ClientScript.RegisterHiddenField (ClientID + "_Page", PageIndex.ToString ());
1874 Page.ClientScript.RegisterHiddenField (ClientID + "_SortExpression", SortExpression);
1875 Page.ClientScript.RegisterHiddenField (ClientID + "_SortDirection", ((int)SortDirection).ToString());
1878 object bstate = base.SaveControlState ();
1879 return new object [] {
1887 SaveDataKeyArrayState (),
1888 (oldEditValues == null ? null : ((IStateManager)oldEditValues).SaveViewState ())
1892 object [] SaveDataKeyArrayState ()
1897 object [] state = new object [keys.Count];
1898 for (int i = 0; i < keys.Count; i++) {
1899 state [i] = ((IStateManager) keys [i]).SaveViewState ();
1904 void LoadDataKeyArrayState (object [] state)
1906 for (int i = 0; i < state.Length; i++) {
1907 DataKey dataKey = new DataKey (new OrderedDictionary (DataKeyNames.Length), DataKeyNames);
1908 ((IStateManager) dataKey).LoadViewState (state [i]);
1909 DataKeyArrayList.Add (dataKey);
1911 keys = new DataKeyArray (DataKeyArrayList);
1914 protected override void TrackViewState()
1916 base.TrackViewState();
1917 if (columns != null) ((IStateManager)columns).TrackViewState();
1918 if (pagerSettings != null) ((IStateManager)pagerSettings).TrackViewState();
1919 if (alternatingRowStyle != null) ((IStateManager)alternatingRowStyle).TrackViewState();
1920 if (footerStyle != null) ((IStateManager)footerStyle).TrackViewState();
1921 if (headerStyle != null) ((IStateManager)headerStyle).TrackViewState();
1922 if (pagerStyle != null) ((IStateManager)pagerStyle).TrackViewState();
1923 if (rowStyle != null) ((IStateManager)rowStyle).TrackViewState();
1924 if (selectedRowStyle != null) ((IStateManager)selectedRowStyle).TrackViewState();
1925 if (editRowStyle != null) ((IStateManager)editRowStyle).TrackViewState();
1926 if (emptyDataRowStyle != null) ((IStateManager)emptyDataRowStyle).TrackViewState();
1927 if (keys != null) ((IStateManager)keys).TrackViewState();
1928 if (autoFieldProperties != null) {
1929 foreach (IStateManager sm in autoFieldProperties)
1930 sm.TrackViewState ();
1934 protected override object SaveViewState()
1936 object[] states = new object [12];
1937 states[0] = base.SaveViewState();
1938 states[1] = (columns == null ? null : ((IStateManager)columns).SaveViewState());
1939 states[2] = (pagerSettings == null ? null : ((IStateManager)pagerSettings).SaveViewState());
1940 states[3] = (alternatingRowStyle == null ? null : ((IStateManager)alternatingRowStyle).SaveViewState());
1941 states[4] = (footerStyle == null ? null : ((IStateManager)footerStyle).SaveViewState());
1942 states[5] = (headerStyle == null ? null : ((IStateManager)headerStyle).SaveViewState());
1943 states[6] = (pagerStyle == null ? null : ((IStateManager)pagerStyle).SaveViewState());
1944 states[7] = (rowStyle == null ? null : ((IStateManager)rowStyle).SaveViewState());
1945 states[8] = (selectedRowStyle == null ? null : ((IStateManager)selectedRowStyle).SaveViewState());
1946 states[9] = (editRowStyle == null ? null : ((IStateManager)editRowStyle).SaveViewState());
1947 states[10] = (emptyDataRowStyle == null ? null : ((IStateManager)emptyDataRowStyle).SaveViewState());
1949 if (autoFieldProperties != null) {
1950 object[] data = new object [autoFieldProperties.Length];
1951 bool allNull = true;
1952 for (int n=0; n<data.Length; n++) {
1953 data [n] = ((IStateManager)autoFieldProperties [n]).SaveViewState ();
1954 if (data [n] != null) allNull = false;
1956 if (!allNull) states [11] = data;
1959 for (int i = states.Length - 1; i >= 0; i--) {
1960 if (states [i] != null)
1967 protected override void LoadViewState (object savedState)
1969 if (savedState == null) {
1970 base.LoadViewState (null);
1974 object [] states = (object []) savedState;
1976 if (states[11] != null) {
1977 object[] data = (object[]) states [11];
1978 autoFieldProperties = new AutoGeneratedFieldProperties [data.Length];
1979 for (int n=0; n<data.Length; n++) {
1980 IStateManager p = new AutoGeneratedFieldProperties ();
1981 p.TrackViewState ();
1982 p.LoadViewState (data [n]);
1983 autoFieldProperties [n] = (AutoGeneratedFieldProperties) p;
1987 base.LoadViewState (states[0]);
1989 if (states[1] != null) ((IStateManager)Columns).LoadViewState (states[1]);
1990 if (states[2] != null) ((IStateManager)PagerSettings).LoadViewState (states[2]);
1991 if (states[3] != null) ((IStateManager)AlternatingRowStyle).LoadViewState (states[3]);
1992 if (states[4] != null) ((IStateManager)FooterStyle).LoadViewState (states[4]);
1993 if (states[5] != null) ((IStateManager)HeaderStyle).LoadViewState (states[5]);
1994 if (states[6] != null) ((IStateManager)PagerStyle).LoadViewState (states[6]);
1995 if (states[7] != null) ((IStateManager)RowStyle).LoadViewState (states[7]);
1996 if (states[8] != null) ((IStateManager)SelectedRowStyle).LoadViewState (states[8]);
1997 if (states[9] != null) ((IStateManager)EditRowStyle).LoadViewState (states[9]);
1998 if (states[10] != null) ((IStateManager)EmptyDataRowStyle).LoadViewState (states[10]);
2001 void ICallbackEventHandler.RaiseCallbackEvent (string eventArgs)
2003 RaiseCallbackEvent (eventArgs);
2006 protected virtual void RaiseCallbackEvent (string eventArgs)
2008 string[] clientData = eventArgs.Split ('|');
2009 PageIndex = int.Parse (clientData[0]);
2010 SortExpression = HttpUtility.UrlDecode (clientData [1]);
2011 SortDirection = (SortDirection) int.Parse (clientData [2]);
2013 RaisePostBackEvent (clientData[3]);
2017 string ICallbackEventHandler.GetCallbackResult ()
2019 return GetCallbackResult ();
2022 protected virtual string GetCallbackResult ()
2024 PrepareControlHierarchy ();
2026 StringWriter sw = new StringWriter ();
2027 sw.Write (PageIndex.ToString () + '|' + SortExpression + '|' + (int) SortDirection + '|');
2029 HtmlTextWriter writer = new HtmlTextWriter (sw);
2030 RenderGrid (writer);
2031 return sw.ToString ();
2034 string ICallbackContainer.GetCallbackScript (IButtonControl control, string argument)
2036 return GetCallbackScript (control, argument);
2039 protected virtual string GetCallbackScript (IButtonControl control, string argument)
2041 if (EnableSortingAndPagingCallbacks)
2042 return "javascript:GridView_ClientEvent (\"" + ClientID + "\",\"" + control.CommandName + "$" + control.CommandArgument + "\"); return false;";
2047 protected override void OnPagePreLoad (object sender, EventArgs e)
2049 base.OnPagePreLoad (sender, e);
2051 if (Page.IsPostBack && EnableSortingAndPagingCallbacks) {
2053 if (int.TryParse (Page.Request.Form [ClientID + "_Page"], out page))
2056 if (int.TryParse (Page.Request.Form [ClientID + "_SortDirection"], out dir))
2057 SortDirection = (SortDirection) dir;
2058 SortExpression = Page.Request.Form [ClientID + "_SortExpression"];
2062 protected internal override void OnPreRender (EventArgs e)
2064 base.OnPreRender (e);
2066 if (EnableSortingAndPagingCallbacks)
2068 if (!Page.ClientScript.IsClientScriptIncludeRegistered (typeof(GridView), "GridView.js")) {
2069 string url = Page.ClientScript.GetWebResourceUrl (typeof(GridView), "GridView.js");
2070 Page.ClientScript.RegisterClientScriptInclude (typeof(GridView), "GridView.js", url);
2073 string cgrid = ClientID + "_data";
2074 string script = string.Format ("var {0} = new Object ();\n", cgrid);
2075 script += string.Format ("{0}.pageIndex = {1};\n", cgrid, ClientScriptManager.GetScriptLiteral (PageIndex));
2076 script += string.Format ("{0}.sortExp = {1};\n", cgrid, ClientScriptManager.GetScriptLiteral (SortExpression == null ? "" : SortExpression));
2077 script += string.Format ("{0}.sortDir = {1};\n", cgrid, ClientScriptManager.GetScriptLiteral ((int) SortDirection));
2078 script += string.Format ("{0}.uid = {1};\n", cgrid, ClientScriptManager.GetScriptLiteral (UniqueID));
2079 script += string.Format ("{0}.form = {1};\n", cgrid, Page.theForm);
2080 Page.ClientScript.RegisterStartupScript (typeof(TreeView), this.UniqueID, script, true);
2082 // Make sure the basic script infrastructure is rendered
2083 Page.ClientScript.GetCallbackEventReference (this, "null", "", "null");
2084 Page.ClientScript.GetPostBackClientHyperlink (this, "");
2088 protected internal override void Render (HtmlTextWriter writer)
2090 PrepareControlHierarchy ();
2092 if (EnableSortingAndPagingCallbacks)
2093 writer.AddAttribute (HtmlTextWriterAttribute.Id, ClientID + "_div");
2094 writer.RenderBeginTag (HtmlTextWriterTag.Div);
2096 RenderGrid (writer);
2098 writer.RenderEndTag ();
2101 void RenderGrid (HtmlTextWriter writer)
2106 table.Render (writer);
2109 PostBackOptions IPostBackContainer.GetPostBackOptions (IButtonControl control)
2111 if (control == null)
2112 throw new ArgumentNullException ("control");
2114 if (control.CausesValidation)
2115 throw new InvalidOperationException ("A button that causes validation in GridView '" + 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.");
2117 PostBackOptions options = new PostBackOptions (this);
2118 options.Argument = control.CommandName + "$" + control.CommandArgument;
2119 options.RequiresJavaScriptProtocol = true;