// // System.Web.UI.WebControls.GridView.cs // // Authors: // Lluis Sanchez Gual (lluis@novell.com) // // (C) 2005 Novell, Inc (http://www.novell.com) // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // #if NET_2_0 using System; using System.Collections; using System.Collections.Specialized; using System.ComponentModel; using System.Web.UI; using System.Security.Permissions; using System.Text; using System.IO; using System.Reflection; namespace System.Web.UI.WebControls { [SupportsEventValidation] [DesignerAttribute ("System.Web.UI.Design.WebControls.GridViewDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")] [ControlValuePropertyAttribute ("SelectedValue")] [DefaultEventAttribute ("SelectedIndexChanged")] [AspNetHostingPermissionAttribute (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] [AspNetHostingPermissionAttribute (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] public class GridView: CompositeDataBoundControl, ICallbackEventHandler, ICallbackContainer, IPostBackEventHandler, IPostBackContainer { Table table; GridViewRowCollection rows; GridViewRow bottomPagerRow; GridViewRow topPagerRow; IOrderedDictionary currentEditRowKeys; IOrderedDictionary currentEditNewValues; IOrderedDictionary currentEditOldValues; ITemplate pagerTemplate; ITemplate emptyDataTemplate; PropertyDescriptor[] cachedKeyProperties; // View state DataControlFieldCollection columns; PagerSettings pagerSettings; TableItemStyle alternatingRowStyle; TableItemStyle editRowStyle; TableItemStyle emptyDataRowStyle; TableItemStyle footerStyle; TableItemStyle headerStyle; TableItemStyle pagerStyle; TableItemStyle rowStyle; TableItemStyle selectedRowStyle; DataKeyArray keys; DataKey oldEditValues; AutoGeneratedFieldProperties[] autoFieldProperties; string [] dataKeyNames = null; readonly string[] emptyKeys = new string[0]; private static readonly object PageIndexChangedEvent = new object(); private static readonly object PageIndexChangingEvent = new object(); private static readonly object RowCancelingEditEvent = new object(); private static readonly object RowCommandEvent = new object(); private static readonly object RowCreatedEvent = new object(); private static readonly object RowDataBoundEvent = new object(); private static readonly object RowDeletedEvent = new object(); private static readonly object RowDeletingEvent = new object(); private static readonly object RowEditingEvent = new object(); private static readonly object RowUpdatedEvent = new object(); private static readonly object RowUpdatingEvent = new object(); private static readonly object SelectedIndexChangedEvent = new object(); private static readonly object SelectedIndexChangingEvent = new object(); private static readonly object SortedEvent = new object(); private static readonly object SortingEvent = new object(); // Control state int pageIndex; int pageCount = 0; int selectedIndex = -1; int editIndex = -1; SortDirection sortDirection = SortDirection.Ascending; string sortExpression = string.Empty; public GridView () { } public event EventHandler PageIndexChanged { add { Events.AddHandler (PageIndexChangedEvent, value); } remove { Events.RemoveHandler (PageIndexChangedEvent, value); } } public event GridViewPageEventHandler PageIndexChanging { add { Events.AddHandler (PageIndexChangingEvent, value); } remove { Events.RemoveHandler (PageIndexChangingEvent, value); } } public event GridViewCancelEditEventHandler RowCancelingEdit { add { Events.AddHandler (RowCancelingEditEvent, value); } remove { Events.RemoveHandler (RowCancelingEditEvent, value); } } public event GridViewCommandEventHandler RowCommand { add { Events.AddHandler (RowCommandEvent, value); } remove { Events.RemoveHandler (RowCommandEvent, value); } } public event GridViewRowEventHandler RowCreated { add { Events.AddHandler (RowCreatedEvent, value); } remove { Events.RemoveHandler (RowCreatedEvent, value); } } public event GridViewRowEventHandler RowDataBound { add { Events.AddHandler (RowDataBoundEvent, value); } remove { Events.RemoveHandler (RowDataBoundEvent, value); } } public event GridViewDeletedEventHandler RowDeleted { add { Events.AddHandler (RowDeletedEvent, value); } remove { Events.RemoveHandler (RowDeletedEvent, value); } } public event GridViewDeleteEventHandler RowDeleting { add { Events.AddHandler (RowDeletingEvent, value); } remove { Events.RemoveHandler (RowDeletingEvent, value); } } public event GridViewEditEventHandler RowEditing { add { Events.AddHandler (RowEditingEvent, value); } remove { Events.RemoveHandler (RowEditingEvent, value); } } public event GridViewUpdatedEventHandler RowUpdated { add { Events.AddHandler (RowUpdatedEvent, value); } remove { Events.RemoveHandler (RowUpdatedEvent, value); } } public event GridViewUpdateEventHandler RowUpdating { add { Events.AddHandler (RowUpdatingEvent, value); } remove { Events.RemoveHandler (RowUpdatingEvent, value); } } public event EventHandler SelectedIndexChanged { add { Events.AddHandler (SelectedIndexChangedEvent, value); } remove { Events.RemoveHandler (SelectedIndexChangedEvent, value); } } public event GridViewSelectEventHandler SelectedIndexChanging { add { Events.AddHandler (SelectedIndexChangingEvent, value); } remove { Events.RemoveHandler (SelectedIndexChangingEvent, value); } } public event EventHandler Sorted { add { Events.AddHandler (SortedEvent, value); } remove { Events.RemoveHandler (SortedEvent, value); } } public event GridViewSortEventHandler Sorting { add { Events.AddHandler (SortingEvent, value); } remove { Events.RemoveHandler (SortingEvent, value); } } protected virtual void OnPageIndexChanged (EventArgs e) { if (Events != null) { EventHandler eh = (EventHandler) Events [PageIndexChangedEvent]; if (eh != null) eh (this, e); } } protected virtual void OnPageIndexChanging (GridViewPageEventArgs e) { if (Events != null) { GridViewPageEventHandler eh = (GridViewPageEventHandler) Events [PageIndexChangingEvent]; if (eh != null) eh (this, e); } } protected virtual void OnRowCancelingEdit (GridViewCancelEditEventArgs e) { if (Events != null) { GridViewCancelEditEventHandler eh = (GridViewCancelEditEventHandler) Events [RowCancelingEditEvent]; if (eh != null) eh (this, e); } } protected virtual void OnRowCommand (GridViewCommandEventArgs e) { if (Events != null) { GridViewCommandEventHandler eh = (GridViewCommandEventHandler) Events [RowCommandEvent]; if (eh != null) eh (this, e); } } protected virtual void OnRowCreated (GridViewRowEventArgs e) { if (Events != null) { GridViewRowEventHandler eh = (GridViewRowEventHandler) Events [RowCreatedEvent]; if (eh != null) eh (this, e); } } protected virtual void OnRowDataBound (GridViewRowEventArgs e) { if (Events != null) { GridViewRowEventHandler eh = (GridViewRowEventHandler) Events [RowDataBoundEvent]; if (eh != null) eh (this, e); } } protected virtual void OnRowDeleted (GridViewDeletedEventArgs e) { if (Events != null) { GridViewDeletedEventHandler eh = (GridViewDeletedEventHandler) Events [RowDeletedEvent]; if (eh != null) eh (this, e); } } protected virtual void OnRowDeleting (GridViewDeleteEventArgs e) { if (Events != null) { GridViewDeleteEventHandler eh = (GridViewDeleteEventHandler) Events [RowDeletingEvent]; if (eh != null) eh (this, e); } } protected virtual void OnRowEditing (GridViewEditEventArgs e) { if (Events != null) { GridViewEditEventHandler eh = (GridViewEditEventHandler) Events [RowEditingEvent]; if (eh != null) eh (this, e); } } protected virtual void OnRowUpdated (GridViewUpdatedEventArgs e) { if (Events != null) { GridViewUpdatedEventHandler eh = (GridViewUpdatedEventHandler) Events [RowUpdatedEvent]; if (eh != null) eh (this, e); } } protected virtual void OnRowUpdating (GridViewUpdateEventArgs e) { if (Events != null) { GridViewUpdateEventHandler eh = (GridViewUpdateEventHandler) Events [RowUpdatingEvent]; if (eh != null) eh (this, e); } } protected virtual void OnSelectedIndexChanged (EventArgs e) { if (Events != null) { EventHandler eh = (EventHandler) Events [SelectedIndexChangedEvent]; if (eh != null) eh (this, e); } } protected virtual void OnSelectedIndexChanging (GridViewSelectEventArgs e) { if (Events != null) { GridViewSelectEventHandler eh = (GridViewSelectEventHandler) Events [SelectedIndexChangingEvent]; if (eh != null) eh (this, e); } } protected virtual void OnSorted (EventArgs e) { if (Events != null) { EventHandler eh = (EventHandler) Events [SortedEvent]; if (eh != null) eh (this, e); } } protected virtual void OnSorting (GridViewSortEventArgs e) { if (Events != null) { GridViewSortEventHandler eh = (GridViewSortEventHandler) Events [SortingEvent]; if (eh != null) eh (this, e); } } [WebCategoryAttribute ("Paging")] [DefaultValueAttribute (false)] public virtual bool AllowPaging { get { object ob = ViewState ["AllowPaging"]; if (ob != null) return (bool) ob; return false; } set { ViewState ["AllowPaging"] = value; RequireBinding (); } } [WebCategoryAttribute ("Behavior")] [DefaultValueAttribute (false)] public virtual bool AllowSorting { get { object ob = ViewState ["AllowSorting"]; if (ob != null) return (bool) ob; return false; } set { ViewState ["AllowSorting"] = value; RequireBinding (); } } [WebCategoryAttribute ("Styles")] [PersistenceMode (PersistenceMode.InnerProperty)] [NotifyParentProperty (true)] [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)] public TableItemStyle AlternatingRowStyle { get { if (alternatingRowStyle == null) { alternatingRowStyle = new TableItemStyle (); if (IsTrackingViewState) alternatingRowStyle.TrackViewState(); } return alternatingRowStyle; } } [WebCategoryAttribute ("Behavior")] [DefaultValueAttribute (false)] public virtual bool AutoGenerateEditButton { get { object ob = ViewState ["AutoGenerateEditButton"]; if (ob != null) return (bool) ob; return false; } set { ViewState ["AutoGenerateEditButton"] = value; RequireBinding (); } } [WebCategoryAttribute ("Behavior")] [DefaultValueAttribute (false)] public virtual bool AutoGenerateDeleteButton { get { object ob = ViewState ["AutoGenerateDeleteButton"]; if (ob != null) return (bool) ob; return false; } set { ViewState ["AutoGenerateDeleteButton"] = value; RequireBinding (); } } [WebCategoryAttribute ("Behavior")] [DefaultValueAttribute (false)] public virtual bool AutoGenerateSelectButton { get { object ob = ViewState ["AutoGenerateSelectButton"]; if (ob != null) return (bool) ob; return false; } set { ViewState ["AutoGenerateSelectButton"] = value; RequireBinding (); } } [WebCategoryAttribute ("Behavior")] [DefaultValueAttribute (true)] public virtual bool AutoGenerateColumns { get { object ob = ViewState ["AutoGenerateColumns"]; if (ob != null) return (bool) ob; return true; } set { ViewState ["AutoGenerateColumns"] = value; RequireBinding (); } } [UrlPropertyAttribute] [WebCategoryAttribute ("Appearance")] [DefaultValueAttribute ("")] [EditorAttribute ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)] public virtual string BackImageUrl { get { if (ControlStyleCreated) return ((TableStyle) ControlStyle).BackImageUrl; return String.Empty; } set { ((TableStyle) ControlStyle).BackImageUrl = value; } } [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)] [BrowsableAttribute (false)] public virtual GridViewRow BottomPagerRow { get { EnsureDataBound (); return bottomPagerRow; } } [WebCategoryAttribute ("Accessibility")] [DefaultValueAttribute ("")] [LocalizableAttribute (true)] public virtual string Caption { get { object ob = ViewState ["Caption"]; if (ob != null) return (string) ob; return string.Empty; } set { ViewState ["Caption"] = value; RequireBinding (); } } [WebCategoryAttribute ("Accessibility")] [DefaultValueAttribute (TableCaptionAlign.NotSet)] public virtual TableCaptionAlign CaptionAlign { get { object o = ViewState ["CaptionAlign"]; if(o != null) return (TableCaptionAlign) o; return TableCaptionAlign.NotSet; } set { ViewState ["CaptionAlign"] = value; RequireBinding (); } } [WebCategoryAttribute ("Layout")] [DefaultValueAttribute (-1)] public virtual int CellPadding { get { if (ControlStyleCreated) return ((TableStyle) ControlStyle).CellPadding; return -1; } set { ((TableStyle) ControlStyle).CellPadding = value; } } [WebCategoryAttribute ("Layout")] [DefaultValueAttribute (0)] public virtual int CellSpacing { get { if (ControlStyleCreated) return ((TableStyle) ControlStyle).CellSpacing; return 0; } set { ((TableStyle) ControlStyle).CellSpacing = value; } } [EditorAttribute ("System.Web.UI.Design.WebControls.DataControlFieldTypeEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)] [MergablePropertyAttribute (false)] [PersistenceModeAttribute (PersistenceMode.InnerProperty)] [DefaultValueAttribute (null)] [WebCategoryAttribute ("Misc")] public virtual DataControlFieldCollection Columns { get { if (columns == null) { columns = new DataControlFieldCollection (); columns.FieldsChanged += new EventHandler (OnFieldsChanged); if (IsTrackingViewState) ((IStateManager)columns).TrackViewState (); } return columns; } } [DefaultValueAttribute (null)] [WebCategoryAttribute ("Data")] [TypeConverter (typeof(StringArrayConverter))] [EditorAttribute ("System.Web.UI.Design.WebControls.DataFieldEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)] public virtual string[] DataKeyNames { get { if (dataKeyNames != null) return dataKeyNames; return emptyKeys; } set { dataKeyNames = value; RequireBinding (); } } [BrowsableAttribute (false)] [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)] public virtual DataKeyArray DataKeys { get { EnsureDataBound (); return keys; } } [WebCategoryAttribute ("Misc")] [DefaultValueAttribute (-1)] public virtual int EditIndex { get { return editIndex; } set { editIndex = value; RequireBinding (); } } [WebCategoryAttribute ("Styles")] [PersistenceMode (PersistenceMode.InnerProperty)] [NotifyParentProperty (true)] [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)] public TableItemStyle EditRowStyle { get { if (editRowStyle == null) { editRowStyle = new TableItemStyle (); if (IsTrackingViewState) editRowStyle.TrackViewState(); } return editRowStyle; } } [WebCategoryAttribute ("Styles")] [PersistenceMode (PersistenceMode.InnerProperty)] [NotifyParentProperty (true)] [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)] public TableItemStyle EmptyDataRowStyle { get { if (emptyDataRowStyle == null) { emptyDataRowStyle = new TableItemStyle (); if (IsTrackingViewState) emptyDataRowStyle.TrackViewState(); } return emptyDataRowStyle; } } [DefaultValue (null)] [TemplateContainer (typeof(GridViewRow), BindingDirection.OneWay)] [PersistenceMode (PersistenceMode.InnerProperty)] [Browsable (false)] public virtual ITemplate EmptyDataTemplate { get { return emptyDataTemplate; } set { emptyDataTemplate = value; RequireBinding (); } } [LocalizableAttribute (true)] [WebCategoryAttribute ("Appearance")] [DefaultValueAttribute ("")] public virtual string EmptyDataText { get { object ob = ViewState ["EmptyDataText"]; if (ob != null) return (string) ob; return string.Empty; } set { ViewState ["EmptyDataText"] = value; RequireBinding (); } } [WebCategoryAttribute ("Behavior")] [DefaultValueAttribute (false)] public virtual bool EnableSortingAndPagingCallbacks { get { object ob = ViewState ["EnableSortingAndPagingCallbacks"]; if (ob != null) return (bool) ob; return false; } set { ViewState ["EnableSortingAndPagingCallbacks"] = value; RequireBinding (); } } [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)] [BrowsableAttribute (false)] public virtual GridViewRow FooterRow { get { if (table != null) { for (int index = table.Rows.Count - 1; index >= 0; index--) { GridViewRow row = (GridViewRow) table.Rows [index]; switch (row.RowType) { case DataControlRowType.Separator: case DataControlRowType.Pager: continue; case DataControlRowType.Footer: return row; default: break; } } } return null; } } [WebCategoryAttribute ("Styles")] [PersistenceMode (PersistenceMode.InnerProperty)] [NotifyParentProperty (true)] [DefaultValue (null)] [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)] public TableItemStyle FooterStyle { get { if (footerStyle == null) { footerStyle = new TableItemStyle (); if (IsTrackingViewState) footerStyle.TrackViewState(); } return footerStyle; } } [WebCategoryAttribute ("Appearance")] [DefaultValueAttribute (GridLines.Both)] public virtual GridLines GridLines { get { if (ControlStyleCreated) return ((TableStyle) ControlStyle).GridLines; return GridLines.Both; } set { ((TableStyle) ControlStyle).GridLines = value; } } [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)] [BrowsableAttribute (false)] public virtual GridViewRow HeaderRow { get { if (table != null) { for (int index = 0, total = table.Rows.Count; index < total; index++) { GridViewRow row = (GridViewRow) table.Rows [index]; switch (row.RowType) { case DataControlRowType.Separator: case DataControlRowType.Pager: continue; case DataControlRowType.Header: return row; default: break; } } } return null; } } [WebCategoryAttribute ("Styles")] [PersistenceMode (PersistenceMode.InnerProperty)] [NotifyParentProperty (true)] [DefaultValue (null)] [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)] public TableItemStyle HeaderStyle { get { if (headerStyle == null) { headerStyle = new TableItemStyle (); if (IsTrackingViewState) headerStyle.TrackViewState(); } return headerStyle; } } [Category ("Layout")] [DefaultValueAttribute (HorizontalAlign.NotSet)] public virtual HorizontalAlign HorizontalAlign { get { if (ControlStyleCreated) return ((TableStyle) ControlStyle).HorizontalAlign; return HorizontalAlign.NotSet; } set { ((TableStyle) ControlStyle).HorizontalAlign = value; } } [BrowsableAttribute (false)] [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)] public virtual int PageCount { get { if (pageCount != 0) return pageCount; EnsureDataBound (); return pageCount; } } [WebCategoryAttribute ("Paging")] [BrowsableAttribute (true)] [DefaultValueAttribute (0)] public virtual int PageIndex { get { return pageIndex; } set { pageIndex = value; RequireBinding (); } } [DefaultValueAttribute (10)] [WebCategoryAttribute ("Paging")] public virtual int PageSize { get { object ob = ViewState ["PageSize"]; if (ob != null) return (int) ob; return 10; } set { ViewState ["PageSize"] = value; RequireBinding (); } } [WebCategoryAttribute ("Paging")] [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Content)] [NotifyParentPropertyAttribute (true)] [PersistenceModeAttribute (PersistenceMode.InnerProperty)] public virtual PagerSettings PagerSettings { get { if (pagerSettings == null) { pagerSettings = new PagerSettings (this); if (IsTrackingViewState) ((IStateManager)pagerSettings).TrackViewState (); } return pagerSettings; } } [WebCategoryAttribute ("Styles")] [PersistenceMode (PersistenceMode.InnerProperty)] [NotifyParentProperty (true)] [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)] public TableItemStyle PagerStyle { get { if (pagerStyle == null) { pagerStyle = new TableItemStyle (); if (IsTrackingViewState) pagerStyle.TrackViewState(); } return pagerStyle; } } [DefaultValue (null)] /* DataControlPagerCell isnt specified in the docs */ //[TemplateContainer (typeof(DataControlPagerCell), BindingDirection.OneWay)] [PersistenceMode (PersistenceMode.InnerProperty)] [Browsable (false)] public virtual ITemplate PagerTemplate { get { return pagerTemplate; } set { pagerTemplate = value; RequireBinding (); } } [DefaultValueAttribute ("")] [WebCategoryAttribute ("Accessibility")] // [TypeConverterAttribute (typeof(System.Web.UI.Design.DataColumnSelectionConverter)] public virtual string RowHeaderColumn { get { object ob = ViewState ["RowHeaderColumn"]; if (ob != null) return (string) ob; return string.Empty; } set { ViewState ["RowHeaderColumn"] = value; RequireBinding (); } } [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)] [BrowsableAttribute (false)] public virtual GridViewRowCollection Rows { get { EnsureDataBound (); return rows; } } [WebCategoryAttribute ("Styles")] [PersistenceMode (PersistenceMode.InnerProperty)] [NotifyParentProperty (true)] [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)] public TableItemStyle RowStyle { get { if (rowStyle == null) { rowStyle = new TableItemStyle (); if (IsTrackingViewState) rowStyle.TrackViewState(); } return rowStyle; } } [BrowsableAttribute (false)] [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)] public virtual DataKey SelectedDataKey { get { if (DataKeys == null) throw new InvalidOperationException ("DataKeys"); if (selectedIndex >= 0 && selectedIndex < DataKeys.Count) { return DataKeys [selectedIndex]; } else return null; } } [BindableAttribute (true)] [DefaultValueAttribute (-1)] public virtual int SelectedIndex { get { return selectedIndex; } set { if (Rows != null && selectedIndex >= 0 && selectedIndex < Rows.Count) { int oldIndex = selectedIndex; selectedIndex = -1; Rows [oldIndex].RowState = GetRowState (oldIndex); } selectedIndex = value; if (Rows != null && selectedIndex >= 0 && selectedIndex < Rows.Count) { Rows [selectedIndex].RowState = GetRowState (selectedIndex); } } } [BrowsableAttribute (false)] [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)] public virtual GridViewRow SelectedRow { get { if (selectedIndex >= 0 && selectedIndex < Rows.Count) { return Rows [selectedIndex]; } else return null; } } [WebCategoryAttribute ("Styles")] [PersistenceMode (PersistenceMode.InnerProperty)] [NotifyParentProperty (true)] [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)] public TableItemStyle SelectedRowStyle { get { if (selectedRowStyle == null) { selectedRowStyle = new TableItemStyle (); if (IsTrackingViewState) selectedRowStyle.TrackViewState(); } return selectedRowStyle; } } [BrowsableAttribute (false)] public object SelectedValue { get { if (SelectedDataKey != null) return SelectedDataKey.Value; else return null; } } [WebCategoryAttribute ("Appearance")] [DefaultValueAttribute (false)] public virtual bool ShowFooter { get { object ob = ViewState ["ShowFooter"]; if (ob != null) return (bool) ob; return false; } set { ViewState ["ShowFooter"] = value; RequireBinding (); } } [WebCategoryAttribute ("Appearance")] [DefaultValueAttribute (true)] public virtual bool ShowHeader { get { object ob = ViewState ["ShowHeader"]; if (ob != null) return (bool) ob; return true; } set { ViewState ["ShowHeader"] = value; RequireBinding (); } } [PersistenceModeAttribute (PersistenceMode.InnerProperty)] [BrowsableAttribute (false)] [DefaultValueAttribute (SortDirection.Ascending)] [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)] public virtual SortDirection SortDirection { get { return sortDirection; } } [BrowsableAttribute (false)] [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)] public virtual string SortExpression { get { return sortExpression; } } [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)] [BrowsableAttribute (false)] public virtual GridViewRow TopPagerRow { get { EnsureDataBound (); return topPagerRow; } } [WebCategoryAttribute ("Accessibility")] [DefaultValueAttribute (true)] public virtual bool UseAccessibleHeader { get { object ob = ViewState ["UseAccessibleHeader"]; if (ob != null) return (bool) ob; return true; } set { ViewState ["UseAccessibleHeader"] = value; RequireBinding (); } } public virtual bool IsBindableType (Type type) { return type.IsPrimitive || type == typeof(string) || type == typeof(DateTime) || type == typeof(Guid); } protected override DataSourceSelectArguments CreateDataSourceSelectArguments () { return base.CreateDataSourceSelectArguments (); } protected virtual ICollection CreateColumns (PagedDataSource dataSource, bool useDataSource) { ArrayList fields = new ArrayList (); fields.AddRange (Columns); if (AutoGenerateEditButton || AutoGenerateDeleteButton || AutoGenerateSelectButton) { CommandField field = new CommandField (); field.ShowEditButton = AutoGenerateEditButton; field.ShowDeleteButton = AutoGenerateDeleteButton; field.ShowSelectButton = AutoGenerateSelectButton; fields.Add (field); } if (AutoGenerateColumns) { if (useDataSource) autoFieldProperties = CreateAutoFieldProperties (dataSource); if (autoFieldProperties != null) { foreach (AutoGeneratedFieldProperties props in autoFieldProperties) fields.Add (CreateAutoGeneratedColumn (props)); } } return fields; } protected virtual AutoGeneratedField CreateAutoGeneratedColumn (AutoGeneratedFieldProperties fieldProperties) { return new AutoGeneratedField (fieldProperties); } AutoGeneratedFieldProperties[] CreateAutoFieldProperties (PagedDataSource source) { if(source == null) return null; PropertyDescriptorCollection props = source.GetItemProperties (new PropertyDescriptor[0]); Type prop_type; ArrayList retVal = new ArrayList(); if (props == null) { object fitem = null; prop_type = null; PropertyInfo prop_item = source.DataSource.GetType().GetProperty("Item", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public, null, null, new Type[] { typeof(int) }, null); if (prop_item != null) { prop_type = prop_item.PropertyType; } if (prop_type == null || prop_type == typeof(object)) { IEnumerator en = source.GetEnumerator(); if (en.MoveNext()) fitem = en.Current; if (fitem != null) prop_type = fitem.GetType(); } if (fitem != null && fitem is ICustomTypeDescriptor) { props = TypeDescriptor.GetProperties(fitem); } else if (prop_type != null) { if (IsBindableType (prop_type)) { AutoGeneratedFieldProperties field = new AutoGeneratedFieldProperties (); ((IStateManager)field).TrackViewState(); field.Name = "Item"; field.DataField = BoundField.ThisExpression; field.Type = prop_type; retVal.Add (field); } else { props = TypeDescriptor.GetProperties (prop_type); } } } if (props != null && props.Count > 0) { foreach (PropertyDescriptor current in props) { if (IsBindableType (current.PropertyType)) { AutoGeneratedFieldProperties field = new AutoGeneratedFieldProperties (); ((IStateManager)field).TrackViewState(); field.Name = current.Name; field.DataField = current.Name; field.IsReadOnly = current.IsReadOnly; field.Type = current.PropertyType; retVal.Add (field); } } } if (retVal.Count > 0) return (AutoGeneratedFieldProperties[]) retVal.ToArray (typeof(AutoGeneratedFieldProperties)); else return new AutoGeneratedFieldProperties [0]; } protected virtual GridViewRow CreateRow (int rowIndex, int dataSourceIndex, DataControlRowType rowType, DataControlRowState rowState) { GridViewRow row = new GridViewRow (rowIndex, dataSourceIndex, rowType, rowState); OnRowCreated (new GridViewRowEventArgs (row)); return row; } void RequireBinding () { if (Initialized) { RequiresDataBinding = true; pageCount = -1; } } protected virtual Table CreateChildTable () { return new ContainedTable (this); } protected override int CreateChildControls (IEnumerable data, bool dataBinding) { PagedDataSource dataSource; if (dataBinding) { DataSourceView view = GetData (); dataSource = new PagedDataSource (); dataSource.DataSource = data; if (AllowPaging) { dataSource.AllowPaging = true; dataSource.PageSize = PageSize; dataSource.CurrentPageIndex = PageIndex; if (view.CanPage) { dataSource.AllowServerPaging = true; if (view.CanRetrieveTotalRowCount) dataSource.VirtualCount = SelectArguments.TotalRowCount; } } pageCount = dataSource.PageCount; } else { dataSource = new PagedDataSource (); dataSource.DataSource = data; if (AllowPaging) { dataSource.AllowPaging = true; dataSource.PageSize = PageSize; dataSource.CurrentPageIndex = PageIndex; } } bool showPager = AllowPaging && (PageCount > 1); Controls.Clear (); table = CreateChildTable (); Controls.Add (table); ArrayList list = new ArrayList (); ArrayList keyList = new ArrayList (); // Creates the set of fields to show ICollection fieldCollection = CreateColumns (dataSource, dataBinding); DataControlField[] fields = new DataControlField [fieldCollection.Count]; fieldCollection.CopyTo (fields, 0); foreach (DataControlField field in fields) { field.Initialize (AllowSorting, this); if (EnableSortingAndPagingCallbacks) field.ValidateSupportsCallback (); } // Main table creation if (showPager && PagerSettings.Position == PagerPosition.Top || PagerSettings.Position == PagerPosition.TopAndBottom) { topPagerRow = CreatePagerRow (fields.Length, dataSource); table.Rows.Add (topPagerRow); } GridViewRow headerRow = CreateRow (0, 0, DataControlRowType.Header, DataControlRowState.Normal); table.Rows.Add (headerRow); InitializeRow (headerRow, fields); foreach (object obj in dataSource) { DataControlRowState rstate = GetRowState (list.Count); GridViewRow row = CreateRow (list.Count, list.Count, DataControlRowType.DataRow, rstate); row.DataItem = obj; list.Add (row); table.Rows.Add (row); InitializeRow (row, fields); if (dataBinding) { row.DataBind (); OnRowDataBound (new GridViewRowEventArgs (row)); if (EditIndex == row.RowIndex) oldEditValues = new DataKey (GetRowValues (row, false, true)); keyList.Add (new DataKey (CreateRowDataKey (row), DataKeyNames)); } else { if (EditIndex == row.RowIndex) oldEditValues = new DataKey (new OrderedDictionary ()); keyList.Add (new DataKey (new OrderedDictionary (), DataKeyNames)); } if (list.Count >= PageSize) break; } if (list.Count == 0) table.Rows.Add (CreateEmptyrRow (fields.Length)); GridViewRow footerRow = CreateRow (0, 0, DataControlRowType.Footer, DataControlRowState.Normal); table.Rows.Add (footerRow); InitializeRow (footerRow, fields); if (showPager && PagerSettings.Position == PagerPosition.Bottom || PagerSettings.Position == PagerPosition.TopAndBottom) { bottomPagerRow = CreatePagerRow (fields.Length, dataSource); table.Rows.Add (bottomPagerRow); } rows = new GridViewRowCollection (list); keys = new DataKeyArray (keyList); return dataSource.DataSourceCount; } protected override Style CreateControlStyle () { TableStyle style = new TableStyle (ViewState); style.GridLines = GridLines.Both; style.CellSpacing = 0; return style; } DataControlRowState GetRowState (int index) { DataControlRowState rstate = (index % 2) == 0 ? DataControlRowState.Normal : DataControlRowState.Alternate; if (index == SelectedIndex) rstate |= DataControlRowState.Selected; if (index == EditIndex) rstate |= DataControlRowState.Edit; return rstate; } GridViewRow CreatePagerRow (int fieldCount, PagedDataSource dataSource) { GridViewRow row = CreateRow (-1, -1, DataControlRowType.Pager, DataControlRowState.Normal); InitializePager (row, fieldCount, dataSource); return row; } protected virtual void InitializePager (GridViewRow row, int columnSpan, PagedDataSource dataSource) { TableCell cell = new TableCell (); if (columnSpan > 1) cell.ColumnSpan = columnSpan; if (pagerTemplate != null) pagerTemplate.InstantiateIn (cell); else cell.Controls.Add (PagerSettings.CreatePagerControl (dataSource.CurrentPageIndex, dataSource.PageCount, pagerStyle)); row.Cells.Add (cell); } GridViewRow CreateEmptyrRow (int fieldCount) { GridViewRow row = CreateRow (-1, -1, DataControlRowType.EmptyDataRow, DataControlRowState.Normal); TableCell cell = new TableCell (); cell.ColumnSpan = fieldCount; if (emptyDataTemplate != null) emptyDataTemplate.InstantiateIn (cell); else cell.Text = EmptyDataText; row.Cells.Add (cell); return row; } protected virtual void InitializeRow (GridViewRow row, DataControlField[] fields) { DataControlCellType ctype; bool accessibleHeader = false; switch (row.RowType) { case DataControlRowType.Header: ctype = DataControlCellType.Header; accessibleHeader = UseAccessibleHeader; break; case DataControlRowType.Footer: ctype = DataControlCellType.Footer; break; default: ctype = DataControlCellType.DataCell; break; } for (int n=0; n 0) newIndex = PageIndex - 1; break; default: newIndex = int.Parse (param) - 1; break; } ShowPage (newIndex); break; case DataControlCommands.FirstPageCommandArgument: ShowPage (0); break; case DataControlCommands.LastPageCommandArgument: ShowPage (PageCount - 1); break; case DataControlCommands.NextPageCommandArgument: if (PageIndex < PageCount - 1) ShowPage (PageIndex + 1); break; case DataControlCommands.PreviousPageCommandArgument: if (PageIndex > 0) ShowPage (PageIndex - 1); break; case DataControlCommands.SelectCommandName: SelectRow (int.Parse (param)); break; case DataControlCommands.EditCommandName: EditRow (int.Parse (param)); break; case DataControlCommands.UpdateCommandName: UpdateRow (EditIndex, true); break; case DataControlCommands.CancelCommandName: CancelEdit (); break; case DataControlCommands.DeleteCommandName: DeleteRow (int.Parse (param)); break; case DataControlCommands.SortCommandName: Sort (param); break; } } void Sort (string newSortExpression) { SortDirection newDirection; if (sortExpression == newSortExpression) { if (sortDirection == SortDirection.Ascending) newDirection = SortDirection.Descending; else newDirection = SortDirection.Ascending; } else newDirection = sortDirection; Sort (newSortExpression, newDirection); } public virtual void Sort (string newSortExpression, SortDirection newSortDirection) { GridViewSortEventArgs args = new GridViewSortEventArgs (newSortExpression, newSortDirection); OnSorting (args); if (args.Cancel) return; sortExpression = args.SortExpression; sortDirection = args.SortDirection; RequireBinding (); OnSorted (EventArgs.Empty); } void SelectRow (int index) { GridViewSelectEventArgs args = new GridViewSelectEventArgs (index); OnSelectedIndexChanging (args); if (!args.Cancel) { SelectedIndex = args.NewSelectedIndex; OnSelectedIndexChanged (EventArgs.Empty); } } void ShowPage (int newIndex) { GridViewPageEventArgs args = new GridViewPageEventArgs (newIndex); OnPageIndexChanging (args); if (!args.Cancel) { EndRowEdit (); PageIndex = args.NewPageIndex; OnPageIndexChanged (EventArgs.Empty); } } void EditRow (int index) { GridViewEditEventArgs args = new GridViewEditEventArgs (index); OnRowEditing (args); if (!args.Cancel) { EditIndex = args.NewEditIndex; } } void CancelEdit () { GridViewCancelEditEventArgs args = new GridViewCancelEditEventArgs (EditIndex); OnRowCancelingEdit (args); if (!args.Cancel) { EndRowEdit (); } } [MonoTODO ("Support two-way binding expressions")] public virtual void UpdateRow (int rowIndex, bool causesValidation) { if (causesValidation) Page.Validate (); if (rowIndex != EditIndex) throw new NotSupportedException (); currentEditOldValues = oldEditValues.Values; GridViewRow row = Rows [rowIndex]; currentEditRowKeys = DataKeys [rowIndex].Values; currentEditNewValues = GetRowValues (row, false, false); GridViewUpdateEventArgs args = new GridViewUpdateEventArgs (EditIndex, currentEditRowKeys, currentEditOldValues, currentEditNewValues); OnRowUpdating (args); if (!args.Cancel) { DataSourceView view = GetData (); if (view == null) throw new HttpException ("The DataSourceView associated to data bound control was null"); view.Update (currentEditRowKeys, currentEditNewValues, currentEditOldValues, new DataSourceViewOperationCallback (UpdateCallback)); } else EndRowEdit (); } bool UpdateCallback (int recordsAffected, Exception exception) { GridViewUpdatedEventArgs dargs = new GridViewUpdatedEventArgs (recordsAffected, exception, currentEditRowKeys, currentEditOldValues, currentEditNewValues); OnRowUpdated (dargs); if (!dargs.KeepInEditMode) EndRowEdit (); return dargs.ExceptionHandled; } public virtual void DeleteRow (int rowIndex) { GridViewRow row = Rows [rowIndex]; currentEditRowKeys = DataKeys [rowIndex].Values; currentEditNewValues = GetRowValues (row, true, true); GridViewDeleteEventArgs args = new GridViewDeleteEventArgs (rowIndex, currentEditRowKeys, currentEditNewValues); OnRowDeleting (args); if (!args.Cancel) { RequireBinding (); DataSourceView view = GetData (); if (view != null) view.Delete (currentEditRowKeys, currentEditNewValues, new DataSourceViewOperationCallback (DeleteCallback)); else { GridViewDeletedEventArgs dargs = new GridViewDeletedEventArgs (0, null, currentEditRowKeys, currentEditNewValues); OnRowDeleted (dargs); } } } bool DeleteCallback (int recordsAffected, Exception exception) { GridViewDeletedEventArgs dargs = new GridViewDeletedEventArgs (recordsAffected, exception, currentEditRowKeys, currentEditNewValues); OnRowDeleted (dargs); return dargs.ExceptionHandled; } void EndRowEdit () { EditIndex = -1; oldEditValues = new DataKey (new OrderedDictionary ()); currentEditRowKeys = null; currentEditOldValues = null; currentEditNewValues = null; } protected internal override void LoadControlState (object ob) { if (ob == null) return; object[] state = (object[]) ob; base.LoadControlState (state[0]); pageIndex = (int) state[1]; pageCount = (int) state[2]; selectedIndex = (int) state[3]; editIndex = (int) state[4]; sortExpression = (string) state[5]; sortDirection = (SortDirection) state[6]; DataKeyNames = (string []) state [7]; } protected internal override object SaveControlState () { object bstate = base.SaveControlState (); return new object[] { bstate, pageIndex, pageCount, selectedIndex, editIndex, sortExpression, sortDirection, DataKeyNames }; } protected override void TrackViewState() { base.TrackViewState(); if (columns != null) ((IStateManager)columns).TrackViewState(); if (pagerSettings != null) ((IStateManager)pagerSettings).TrackViewState(); if (alternatingRowStyle != null) ((IStateManager)alternatingRowStyle).TrackViewState(); if (footerStyle != null) ((IStateManager)footerStyle).TrackViewState(); if (headerStyle != null) ((IStateManager)headerStyle).TrackViewState(); if (pagerStyle != null) ((IStateManager)pagerStyle).TrackViewState(); if (rowStyle != null) ((IStateManager)rowStyle).TrackViewState(); if (selectedRowStyle != null) ((IStateManager)selectedRowStyle).TrackViewState(); if (editRowStyle != null) ((IStateManager)editRowStyle).TrackViewState(); if (emptyDataRowStyle != null) ((IStateManager)emptyDataRowStyle).TrackViewState(); if (keys != null) ((IStateManager)keys).TrackViewState(); if (autoFieldProperties != null) { foreach (IStateManager sm in autoFieldProperties) sm.TrackViewState (); } } protected override object SaveViewState() { object[] states = new object [14]; states[0] = base.SaveViewState(); states[1] = (columns == null ? null : ((IStateManager)columns).SaveViewState()); states[2] = (pagerSettings == null ? null : ((IStateManager)pagerSettings).SaveViewState()); states[3] = (alternatingRowStyle == null ? null : ((IStateManager)alternatingRowStyle).SaveViewState()); states[4] = (footerStyle == null ? null : ((IStateManager)footerStyle).SaveViewState()); states[5] = (headerStyle == null ? null : ((IStateManager)headerStyle).SaveViewState()); states[6] = (pagerStyle == null ? null : ((IStateManager)pagerStyle).SaveViewState()); states[7] = (rowStyle == null ? null : ((IStateManager)rowStyle).SaveViewState()); states[8] = (selectedRowStyle == null ? null : ((IStateManager)selectedRowStyle).SaveViewState()); states[9] = (editRowStyle == null ? null : ((IStateManager)editRowStyle).SaveViewState()); states[10] = (emptyDataRowStyle == null ? null : ((IStateManager)emptyDataRowStyle).SaveViewState()); states[11] = (keys == null ? null : ((IStateManager)keys).SaveViewState()); states[12] = (oldEditValues == null ? null : ((IStateManager)oldEditValues).SaveViewState()); if (autoFieldProperties != null) { object[] data = new object [autoFieldProperties.Length]; bool allNull = true; for (int n=0; n= 0; i--) { if (states [i] != null) return states; } return null; } protected override void LoadViewState (object savedState) { if (savedState == null) { base.LoadViewState (null); return; } object [] states = (object []) savedState; if (states[13] != null) { object[] data = (object[]) states [13]; autoFieldProperties = new AutoGeneratedFieldProperties [data.Length]; for (int n=0; n