// // System.Web.UI.WebControls.DetailsView.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] [ToolboxDataAttribute ("<{0}:DetailsView runat=\"server\" Width=\"125px\" Height=\"50px\">")] [DesignerAttribute ("System.Web.UI.Design.WebControls.DetailsViewDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")] [ControlValuePropertyAttribute ("SelectedValue")] [DefaultEventAttribute ("PageIndexChanging")] [AspNetHostingPermissionAttribute (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] [AspNetHostingPermissionAttribute (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] public class DetailsView: CompositeDataBoundControl, ICallbackEventHandler, ICallbackContainer, IDataItemContainer, INamingContainer, IPostBackEventHandler, IPostBackContainer { object dataItem; Table table; DetailsViewRowCollection rows; DetailsViewRow headerRow; DetailsViewRow footerRow; DetailsViewRow bottomPagerRow; DetailsViewRow topPagerRow; IOrderedDictionary currentEditRowKeys; IOrderedDictionary currentEditNewValues; IOrderedDictionary currentEditOldValues; ITemplate pagerTemplate; ITemplate emptyDataTemplate; ITemplate headerTemplate; ITemplate footerTemplate; PropertyDescriptor[] cachedKeyProperties; readonly string[] emptyKeys = new string[0]; // View state DataControlFieldCollection columns; PagerSettings pagerSettings; TableItemStyle alternatingRowStyle; TableItemStyle editRowStyle; TableItemStyle insertRowStyle; TableItemStyle emptyDataRowStyle; TableItemStyle footerStyle; TableItemStyle headerStyle; TableItemStyle pagerStyle; TableItemStyle rowStyle; TableItemStyle commandRowStyle; TableItemStyle fieldHeaderStyle; IOrderedDictionary _keyTable; DataKey key; DataKey oldEditValues; AutoGeneratedFieldProperties[] autoFieldProperties; private static readonly object PageIndexChangedEvent = new object(); private static readonly object PageIndexChangingEvent = new object(); private static readonly object ItemCommandEvent = new object(); private static readonly object ItemCreatedEvent = new object(); private static readonly object ItemDeletedEvent = new object(); private static readonly object ItemDeletingEvent = new object(); private static readonly object ItemInsertedEvent = new object(); private static readonly object ItemInsertingEvent = new object(); private static readonly object ModeChangingEvent = new object(); private static readonly object ModeChangedEvent = new object(); private static readonly object ItemUpdatedEvent = new object(); private static readonly object ItemUpdatingEvent = new object(); // Control state int pageIndex; DetailsViewMode currentMode = DetailsViewMode.ReadOnly; bool hasCurrentMode; int pageCount; public DetailsView () { rows = new DetailsViewRowCollection (new ArrayList ()); } public event EventHandler PageIndexChanged { add { Events.AddHandler (PageIndexChangedEvent, value); } remove { Events.RemoveHandler (PageIndexChangedEvent, value); } } public event DetailsViewPageEventHandler PageIndexChanging { add { Events.AddHandler (PageIndexChangingEvent, value); } remove { Events.RemoveHandler (PageIndexChangingEvent, value); } } public event DetailsViewCommandEventHandler ItemCommand { add { Events.AddHandler (ItemCommandEvent, value); } remove { Events.RemoveHandler (ItemCommandEvent, value); } } public event EventHandler ItemCreated { add { Events.AddHandler (ItemCreatedEvent, value); } remove { Events.RemoveHandler (ItemCreatedEvent, value); } } public event DetailsViewDeletedEventHandler ItemDeleted { add { Events.AddHandler (ItemDeletedEvent, value); } remove { Events.RemoveHandler (ItemDeletedEvent, value); } } public event DetailsViewDeleteEventHandler ItemDeleting { add { Events.AddHandler (ItemDeletingEvent, value); } remove { Events.RemoveHandler (ItemDeletingEvent, value); } } public event DetailsViewInsertedEventHandler ItemInserted { add { Events.AddHandler (ItemInsertedEvent, value); } remove { Events.RemoveHandler (ItemInsertedEvent, value); } } public event DetailsViewInsertEventHandler ItemInserting { add { Events.AddHandler (ItemInsertingEvent, value); } remove { Events.RemoveHandler (ItemInsertingEvent, value); } } public event DetailsViewModeEventHandler ModeChanging { add { Events.AddHandler (ModeChangingEvent, value); } remove { Events.RemoveHandler (ModeChangingEvent, value); } } public event EventHandler ModeChanged { add { Events.AddHandler (ModeChangedEvent, value); } remove { Events.RemoveHandler (ModeChangedEvent, value); } } public event DetailsViewUpdatedEventHandler ItemUpdated { add { Events.AddHandler (ItemUpdatedEvent, value); } remove { Events.RemoveHandler (ItemUpdatedEvent, value); } } public event DetailsViewUpdateEventHandler ItemUpdating { add { Events.AddHandler (ItemUpdatingEvent, value); } remove { Events.RemoveHandler (ItemUpdatingEvent, 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 (DetailsViewPageEventArgs e) { if (Events != null) { DetailsViewPageEventHandler eh = (DetailsViewPageEventHandler) Events [PageIndexChangingEvent]; if (eh != null) eh (this, e); } } protected virtual void OnItemCommand (DetailsViewCommandEventArgs e) { if (Events != null) { DetailsViewCommandEventHandler eh = (DetailsViewCommandEventHandler) Events [ItemCommandEvent]; if (eh != null) eh (this, e); } } protected virtual void OnItemCreated (EventArgs e) { if (Events != null) { EventHandler eh = (EventHandler) Events [ItemCreatedEvent]; if (eh != null) eh (this, e); } } protected virtual void OnItemDeleted (DetailsViewDeletedEventArgs e) { if (Events != null) { DetailsViewDeletedEventHandler eh = (DetailsViewDeletedEventHandler) Events [ItemDeletedEvent]; if (eh != null) eh (this, e); } } protected virtual void OnItemInserted (DetailsViewInsertedEventArgs e) { if (Events != null) { DetailsViewInsertedEventHandler eh = (DetailsViewInsertedEventHandler) Events [ItemInsertedEvent]; if (eh != null) eh (this, e); } } protected virtual void OnItemInserting (DetailsViewInsertEventArgs e) { if (Events != null) { DetailsViewInsertEventHandler eh = (DetailsViewInsertEventHandler) Events [ItemInsertingEvent]; if (eh != null) eh (this, e); } } protected virtual void OnItemDeleting (DetailsViewDeleteEventArgs e) { if (Events != null) { DetailsViewDeleteEventHandler eh = (DetailsViewDeleteEventHandler) Events [ItemDeletingEvent]; if (eh != null) eh (this, e); } } protected virtual void OnModeChanged (EventArgs e) { if (Events != null) { EventHandler eh = (EventHandler) Events [ModeChangedEvent]; if (eh != null) eh (this, e); } } protected virtual void OnModeChanging (DetailsViewModeEventArgs e) { if (Events != null) { DetailsViewModeEventHandler eh = (DetailsViewModeEventHandler) Events [ModeChangingEvent]; if (eh != null) eh (this, e); } } protected virtual void OnItemUpdated (DetailsViewUpdatedEventArgs e) { if (Events != null) { DetailsViewUpdatedEventHandler eh = (DetailsViewUpdatedEventHandler) Events [ItemUpdatedEvent]; if (eh != null) eh (this, e); } } protected virtual void OnItemUpdating (DetailsViewUpdateEventArgs e) { if (Events != null) { DetailsViewUpdateEventHandler eh = (DetailsViewUpdateEventHandler) Events [ItemUpdatingEvent]; 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 (); } } [DefaultValueAttribute (null)] [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 AutoGenerateInsertButton { get { object ob = ViewState ["AutoGenerateInsertButton"]; if (ob != null) return (bool) ob; return false; } set { ViewState ["AutoGenerateInsertButton"] = value; RequireBinding (); } } [WebCategoryAttribute ("Behavior")] [DefaultValueAttribute (true)] public virtual bool AutoGenerateRows { get { object ob = ViewState ["AutoGenerateRows"]; if (ob != null) return (bool) ob; return true; } set { ViewState ["AutoGenerateRows"] = 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 DetailsViewRow 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; } } [DefaultValueAttribute (null)] [WebCategoryAttribute ("Styles")] [PersistenceMode (PersistenceMode.InnerProperty)] [NotifyParentProperty (true)] [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)] public TableItemStyle CommandRowStyle { get { if (commandRowStyle == null) { commandRowStyle = new TableItemStyle (); if (IsTrackingViewState) commandRowStyle.TrackViewState(); } return commandRowStyle; } } [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)] [BrowsableAttribute (false)] public DetailsViewMode CurrentMode { get { return hasCurrentMode ? currentMode : DefaultMode; } private set { hasCurrentMode = true; currentMode = value; } } DetailsViewMode defaultMode = DetailsViewMode.ReadOnly; [DefaultValueAttribute (DetailsViewMode.ReadOnly)] [WebCategoryAttribute ("Behavior")] public virtual DetailsViewMode DefaultMode { get { return defaultMode; } set { defaultMode = value; RequireBinding (); } } [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 Fields { get { if (columns == null) { columns = new DataControlFieldCollection (); columns.FieldsChanged += new EventHandler (OnFieldsChanged); if (IsTrackingViewState) ((IStateManager)columns).TrackViewState (); } return columns; } } string[] dataKeyNames = null; [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 emptyKeys; else return dataKeyNames; } set { dataKeyNames = value; RequireBinding (); } } IOrderedDictionary KeyTable { get { if (_keyTable == null) { _keyTable = new OrderedDictionary (DataKeyNames.Length); } return _keyTable; } } [BrowsableAttribute (false)] [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)] public virtual DataKey DataKey { get { if (key == null) { key = new DataKey (KeyTable); } return key; } } DataKey OldEditValues { get { if (oldEditValues == null) { oldEditValues = new DataKey (new OrderedDictionary ()); } return oldEditValues; } } [WebCategoryAttribute ("Styles")] [PersistenceMode (PersistenceMode.InnerProperty)] [NotifyParentProperty (true)] [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)] [DefaultValueAttribute (null)] 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)] [DefaultValueAttribute (null)] public TableItemStyle EmptyDataRowStyle { get { if (emptyDataRowStyle == null) { emptyDataRowStyle = new TableItemStyle (); if (IsTrackingViewState) emptyDataRowStyle.TrackViewState(); } return emptyDataRowStyle; } } [DefaultValue (null)] [TemplateContainer (typeof(DetailsView), 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 EnablePagingCallbacks { get { object ob = ViewState ["EnablePagingCallbacks"]; if (ob != null) return (bool) ob; return false; } set { ViewState ["EnablePagingCallbacks"] = value; RequireBinding (); } } [WebCategoryAttribute ("Styles")] [PersistenceMode (PersistenceMode.InnerProperty)] [NotifyParentProperty (true)] [DefaultValue (null)] [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)] public TableItemStyle FieldHeaderStyle { get { if (fieldHeaderStyle == null) { fieldHeaderStyle = new TableItemStyle (); if (IsTrackingViewState) fieldHeaderStyle.TrackViewState(); } return fieldHeaderStyle; } } [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)] [BrowsableAttribute (false)] public virtual DetailsViewRow FooterRow { get { EnsureChildControls (); return footerRow; } } [DefaultValue (null)] [TemplateContainer (typeof(DetailsView), BindingDirection.OneWay)] [PersistenceMode (PersistenceMode.InnerProperty)] [Browsable (false)] public virtual ITemplate FooterTemplate { get { return footerTemplate; } set { footerTemplate = value; RequireBinding (); } } [LocalizableAttribute (true)] [WebCategoryAttribute ("Appearance")] [DefaultValueAttribute ("")] public virtual string FooterText { get { object ob = ViewState ["FooterText"]; if (ob != null) return (string) ob; return string.Empty; } set { ViewState ["FooterText"] = value; RequireBinding (); } } [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 DetailsViewRow HeaderRow { get { EnsureChildControls (); return headerRow; } } [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; } } [DefaultValue (null)] [TemplateContainer (typeof(DetailsView), BindingDirection.OneWay)] [PersistenceMode (PersistenceMode.InnerProperty)] [Browsable (false)] public virtual ITemplate HeaderTemplate { get { return headerTemplate; } set { headerTemplate = value; RequireBinding (); } } [LocalizableAttribute (true)] [WebCategoryAttribute ("Appearance")] [DefaultValueAttribute ("")] public virtual string HeaderText { get { object ob = ViewState ["HeaderText"]; if (ob != null) return (string) ob; return string.Empty; } set { ViewState ["HeaderText"] = value; RequireBinding (); } } [Category ("Layout")] [DefaultValueAttribute (HorizontalAlign.NotSet)] public virtual HorizontalAlign HorizontalAlign { get { if (ControlStyleCreated) return ((TableStyle) ControlStyle).HorizontalAlign; return HorizontalAlign.NotSet; } set { ((TableStyle) ControlStyle).HorizontalAlign = value; } } [WebCategoryAttribute ("Styles")] [PersistenceMode (PersistenceMode.InnerProperty)] [NotifyParentProperty (true)] [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)] [DefaultValueAttribute (null)] public TableItemStyle InsertRowStyle { get { if (insertRowStyle == null) { insertRowStyle = new TableItemStyle (); if (IsTrackingViewState) insertRowStyle.TrackViewState(); } return insertRowStyle; } } [BrowsableAttribute (false)] [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)] public virtual int PageCount { get { return pageCount; } } [WebCategoryAttribute ("Paging")] [BindableAttribute (true, BindingDirection.OneWay)] [DefaultValueAttribute (0)] public virtual int PageIndex { get { return pageIndex; } set { if (value < 0) throw new ArgumentOutOfRangeException ("PageIndex must be non-negative"); if (value == pageIndex) return; pageIndex = 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)] [TemplateContainer (typeof (DetailsView), BindingDirection.OneWay)] [PersistenceMode (PersistenceMode.InnerProperty)] [Browsable (false)] public virtual ITemplate PagerTemplate { get { return pagerTemplate; } set { pagerTemplate = value; RequireBinding (); } } [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)] [BrowsableAttribute (false)] public virtual DetailsViewRowCollection Rows { get { EnsureChildControls (); return rows; } } [WebCategoryAttribute ("Styles")] [PersistenceMode (PersistenceMode.InnerProperty)] [NotifyParentProperty (true)] [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)] [DefaultValue (null)] public TableItemStyle RowStyle { get { if (rowStyle == null) { rowStyle = new TableItemStyle (); if (IsTrackingViewState) rowStyle.TrackViewState(); } return rowStyle; } } [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)] [BrowsableAttribute (false)] public object SelectedValue { get { return DataKey.Value; } } [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)] [BrowsableAttribute (false)] public virtual DetailsViewRow TopPagerRow { get { EnsureDataBound (); return topPagerRow; } } [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)] [BrowsableAttribute (false)] public virtual object DataItem { get { EnsureDataBound (); return dataItem; } } [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)] [BrowsableAttribute (false)] public int DataItemCount { get { return PageCount; } } [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)] [BrowsableAttribute (false)] public virtual int DataItemIndex { get { return PageIndex; } } int IDataItemContainer.DisplayIndex { get { return PageIndex; } } public virtual bool IsBindableType (Type type) { return type.IsPrimitive || type == typeof (string) || type == typeof (DateTime) || type == typeof (Guid) || type == typeof (Decimal); } protected override DataSourceSelectArguments CreateDataSourceSelectArguments () { DataSourceSelectArguments arg = new DataSourceSelectArguments (); DataSourceView view = GetData (); if (AllowPaging && view.CanPage) { arg.StartRowIndex = PageIndex; if (view.CanRetrieveTotalRowCount) { arg.RetrieveTotalRowCount = true; arg.MaximumRows = 1; } else { arg.MaximumRows = -1; } } return arg; } protected virtual ICollection CreateFieldSet (object dataItem, bool useDataSource) { ArrayList fields = new ArrayList (); if (AutoGenerateRows) { if (useDataSource) { if (dataItem != null) fields.AddRange (CreateAutoGeneratedRows (dataItem)); } else { if (autoFieldProperties != null) { foreach (AutoGeneratedFieldProperties props in autoFieldProperties) fields.Add (CreateAutoGeneratedRow (props)); } } } fields.AddRange (Fields); if (AutoGenerateEditButton || AutoGenerateDeleteButton || AutoGenerateInsertButton) { CommandField field = new CommandField (); field.ShowEditButton = AutoGenerateEditButton; field.ShowDeleteButton = AutoGenerateDeleteButton; field.ShowInsertButton = AutoGenerateInsertButton; fields.Add (field); } return fields; } protected virtual ICollection CreateAutoGeneratedRows (object dataItem) { ArrayList list = new ArrayList (); autoFieldProperties = CreateAutoFieldProperties (dataItem); foreach (AutoGeneratedFieldProperties props in autoFieldProperties) list.Add (CreateAutoGeneratedRow (props)); return list; } protected virtual AutoGeneratedField CreateAutoGeneratedRow (AutoGeneratedFieldProperties fieldProperties) { return new AutoGeneratedField (fieldProperties); } AutoGeneratedFieldProperties[] CreateAutoFieldProperties (object dataItem) { PropertyDescriptorCollection props = TypeDescriptor.GetProperties (dataItem); ArrayList retVal = new ArrayList(); 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 DetailsViewRow CreateRow (int rowIndex, DataControlRowType rowType, DataControlRowState rowState) { DetailsViewRow row; if (rowType == DataControlRowType.Pager) row = new DetailsViewPagerRow (rowIndex, rowType, rowState); else row = new DetailsViewRow (rowIndex, rowType, rowState); OnItemCreated (EventArgs.Empty); return row; } void RequireBinding () { if (Initialized) { RequiresDataBinding = true; } } protected virtual Table CreateTable () { return new ContainedTable (this); } protected override Style CreateControlStyle () { TableStyle style = new TableStyle (ViewState); style.GridLines = GridLines.Both; style.CellSpacing = 0; return style; } 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 = 1; dataSource.CurrentPageIndex = PageIndex; if (view.CanPage) { dataSource.AllowServerPaging = true; if (SelectArguments.RetrieveTotalRowCount) dataSource.VirtualCount = SelectArguments.TotalRowCount; } } pageCount = dataSource.DataSourceCount; } else { dataSource = new PagedDataSource (); dataSource.DataSource = data; if (AllowPaging) { dataSource.AllowPaging = true; dataSource.PageSize = 1; dataSource.CurrentPageIndex = PageIndex; } } bool showPager = AllowPaging && (PageCount > 1); Controls.Clear (); table = CreateTable (); Controls.Add (table); ArrayList list = new ArrayList (); // Gets the current data item IEnumerator e = dataSource.GetEnumerator (); if (e.MoveNext ()) dataItem = e.Current; else dataItem = null; // Creates the set of fields to show ICollection fieldCollection = CreateFieldSet (dataItem, dataBinding); DataControlField[] fields = new DataControlField [fieldCollection.Count]; fieldCollection.CopyTo (fields, 0); foreach (DataControlField field in fields) { field.Initialize (false, this); if (EnablePagingCallbacks) field.ValidateSupportsCallback (); } // Main table creation headerRow = CreateRow (-1, DataControlRowType.Header, DataControlRowState.Normal); DataControlFieldCell headerCell = new DataControlFieldCell (null); headerCell.ColumnSpan = 2; if (headerTemplate != null) headerTemplate.InstantiateIn (headerCell); else headerCell.Text = HeaderText; headerRow.Cells.Add (headerCell); table.Rows.Add (headerRow); if (showPager && PagerSettings.Position == PagerPosition.Top || PagerSettings.Position == PagerPosition.TopAndBottom) { topPagerRow = CreateRow (-1, DataControlRowType.Pager, DataControlRowState.Normal); InitializePager (topPagerRow, dataSource); table.Rows.Add (topPagerRow); } if (dataSource.Count > 0) { foreach (DataControlField field in fields) { DataControlRowState rstate = GetRowState (list.Count); DetailsViewRow row = CreateRow (PageIndex, DataControlRowType.DataRow, rstate); InitializeRow (row, field); table.Rows.Add (row); list.Add (row); } } else { table.Rows.Add (CreateEmptyrRow ()); } rows = new DetailsViewRowCollection (list); footerRow = CreateRow (-1, DataControlRowType.Footer, DataControlRowState.Normal); DataControlFieldCell footerCell = new DataControlFieldCell (null); footerCell.ColumnSpan = 2; if (footerTemplate != null) footerTemplate.InstantiateIn (footerCell); else footerCell.Text = FooterText; footerRow.Cells.Add (footerCell); table.Rows.Add (footerRow); if (showPager && PagerSettings.Position == PagerPosition.Bottom || PagerSettings.Position == PagerPosition.TopAndBottom) { bottomPagerRow = CreateRow (-1, DataControlRowType.Pager, DataControlRowState.Normal); InitializePager (bottomPagerRow, dataSource); table.Rows.Add (bottomPagerRow); } if (dataBinding) DataBind (false); return dataSource.DataSourceCount; } protected override void EnsureDataBound () { base.EnsureDataBound (); } DataControlRowState GetRowState (int index) { DataControlRowState rstate = (index % 2) == 0 ? DataControlRowState.Normal : DataControlRowState.Alternate; if (CurrentMode == DetailsViewMode.Edit) rstate |= DataControlRowState.Edit; else if (CurrentMode == DetailsViewMode.Insert) rstate |= DataControlRowState.Insert; return rstate; } protected virtual void InitializePager (DetailsViewRow row, PagedDataSource dataSource) { TableCell cell = new TableCell (); cell.ColumnSpan = 2; if (pagerTemplate != null) pagerTemplate.InstantiateIn (cell); else cell.Controls.Add (PagerSettings.CreatePagerControl (dataSource.CurrentPageIndex, dataSource.PageCount)); row.Cells.Add (cell); } DetailsViewRow CreateEmptyrRow () { DetailsViewRow row = CreateRow (-1, DataControlRowType.EmptyDataRow, DataControlRowState.Normal); TableCell cell = new TableCell (); cell.ColumnSpan = 2; if (emptyDataTemplate != null) emptyDataTemplate.InstantiateIn (cell); else cell.Text = EmptyDataText; row.Cells.Add (cell); return row; } protected virtual void InitializeRow (DetailsViewRow row, DataControlField field) { row.ContainingField = field; DataControlFieldCell cell; if (field.ShowHeader) { cell = new DataControlFieldCell (field); row.Cells.Add (cell); field.InitializeCell (cell, DataControlCellType.Header, row.RowState, row.RowIndex); } cell = new DataControlFieldCell (field); if (!field.ShowHeader) cell.ColumnSpan = 2; row.Cells.Add (cell); field.InitializeCell (cell, DataControlCellType.DataCell, row.RowState, row.RowIndex); if (CurrentMode == DetailsViewMode.Insert && !field.InsertVisible) row.Visible = false; } void FillRowDataKey (object dataItem) { KeyTable.Clear (); if (cachedKeyProperties == null) { PropertyDescriptorCollection props = TypeDescriptor.GetProperties (dataItem); cachedKeyProperties = new PropertyDescriptor [DataKeyNames.Length]; for (int n=0; n 0) ShowPage (PageIndex - 1); break; case DataControlCommands.EditCommandName: ChangeMode (DetailsViewMode.Edit); break; case DataControlCommands.NewCommandName: ChangeMode (DetailsViewMode.Insert); break; case DataControlCommands.UpdateCommandName: UpdateItem (param, true); break; case DataControlCommands.CancelCommandName: CancelEdit (); break; case DataControlCommands.DeleteCommandName: DeleteItem (); break; case DataControlCommands.InsertCommandName: InsertItem (true); break; } } void ShowPage (int newIndex) { DetailsViewPageEventArgs args = new DetailsViewPageEventArgs (newIndex); OnPageIndexChanging (args); if (!args.Cancel) { if (args.NewPageIndex < 0 || args.NewPageIndex >= PageCount) return; EndRowEdit (false); PageIndex = args.NewPageIndex; OnPageIndexChanged (EventArgs.Empty); } } public void ChangeMode (DetailsViewMode newMode) { DetailsViewModeEventArgs args = new DetailsViewModeEventArgs (newMode, false); OnModeChanging (args); if (!args.Cancel) { CurrentMode = args.NewMode; OnModeChanged (EventArgs.Empty); RequireBinding (); } } void CancelEdit () { DetailsViewModeEventArgs args = new DetailsViewModeEventArgs (DetailsViewMode.ReadOnly, true); OnModeChanging (args); if (!args.Cancel) { EndRowEdit (); } } public virtual void UpdateItem (bool causesValidation) { UpdateItem (null, causesValidation); } void UpdateItem (string param, bool causesValidation) { if (causesValidation && Page != null) Page.Validate (); if (CurrentMode != DetailsViewMode.Edit) throw new HttpException (); currentEditOldValues = OldEditValues.Values; currentEditRowKeys = DataKey.Values; currentEditNewValues = GetRowValues (false, false); DetailsViewUpdateEventArgs args = new DetailsViewUpdateEventArgs (param, currentEditRowKeys, currentEditOldValues, currentEditNewValues); OnItemUpdating (args); if (!args.Cancel) { DataSourceView view = GetData (); if (view == null) throw new HttpException ("The DataSourceView associated to data bound control was null"); if (view.CanUpdate) view.Update (currentEditRowKeys, currentEditNewValues, currentEditOldValues, new DataSourceViewOperationCallback (UpdateCallback)); } else EndRowEdit (); } bool UpdateCallback (int recordsAffected, Exception exception) { DetailsViewUpdatedEventArgs dargs = new DetailsViewUpdatedEventArgs (recordsAffected, exception, currentEditRowKeys, currentEditOldValues, currentEditNewValues); OnItemUpdated (dargs); if (!dargs.KeepInEditMode) EndRowEdit (); return dargs.ExceptionHandled; } public virtual void InsertItem (bool causesValidation) { InsertItem (null, causesValidation); } void InsertItem (string param, bool causesValidation) { if (causesValidation && Page != null) Page.Validate (); if (CurrentMode != DetailsViewMode.Insert) throw new HttpException (); currentEditNewValues = GetRowValues (false, true); DetailsViewInsertEventArgs args = new DetailsViewInsertEventArgs (param, currentEditNewValues); OnItemInserting (args); if (!args.Cancel) { DataSourceView view = GetData (); if (view == null) throw new HttpException ("The DataSourceView associated to data bound control was null"); if (view.CanInsert) view.Insert (currentEditNewValues, new DataSourceViewOperationCallback (InsertCallback)); } else EndRowEdit (); } bool InsertCallback (int recordsAffected, Exception exception) { DetailsViewInsertedEventArgs dargs = new DetailsViewInsertedEventArgs (recordsAffected, exception, currentEditNewValues); OnItemInserted (dargs); if (!dargs.KeepInInsertMode) EndRowEdit (); return dargs.ExceptionHandled; } public virtual void DeleteItem () { currentEditRowKeys = DataKey.Values; currentEditNewValues = GetRowValues (true, true); DetailsViewDeleteEventArgs args = new DetailsViewDeleteEventArgs (PageIndex, currentEditRowKeys, currentEditNewValues); OnItemDeleting (args); if (!args.Cancel) { if (PageIndex == PageCount - 1) PageIndex --; RequireBinding (); DataSourceView view = GetData (); if (view != null && view.CanDelete) view.Delete (currentEditRowKeys, currentEditNewValues, new DataSourceViewOperationCallback (DeleteCallback)); else { DetailsViewDeletedEventArgs dargs = new DetailsViewDeletedEventArgs (0, null, currentEditRowKeys, currentEditNewValues); OnItemDeleted (dargs); } } } bool DeleteCallback (int recordsAffected, Exception exception) { DetailsViewDeletedEventArgs dargs = new DetailsViewDeletedEventArgs (recordsAffected, exception, currentEditRowKeys, currentEditNewValues); OnItemDeleted (dargs); return dargs.ExceptionHandled; } void EndRowEdit () { EndRowEdit (true); } void EndRowEdit (bool switchToDefaultMode) { if (switchToDefaultMode) ChangeMode (DefaultMode); oldEditValues = new DataKey (new OrderedDictionary ()); currentEditRowKeys = null; currentEditOldValues = null; currentEditNewValues = null; RequireBinding (); } 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]; CurrentMode = (DetailsViewMode) state[3]; dataKeyNames = (string[]) state[4]; defaultMode = (DetailsViewMode) state[5]; if (state [6] != null) ((IStateManager) DataKey).LoadViewState (state [6]); if (state [7] != null) ((IStateManager) OldEditValues).LoadViewState (state [7]); } protected internal override object SaveControlState () { object bstate = base.SaveControlState (); return new object[] { bstate, pageIndex, pageCount, CurrentMode, dataKeyNames, defaultMode, (key == null ? null : ((IStateManager)key).SaveViewState()), (oldEditValues == null ? null : ((IStateManager) oldEditValues).SaveViewState ()) }; } 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 (editRowStyle != null) ((IStateManager)editRowStyle).TrackViewState(); if (insertRowStyle != null) ((IStateManager)insertRowStyle).TrackViewState(); if (emptyDataRowStyle != null) ((IStateManager)emptyDataRowStyle).TrackViewState(); if (key != null) ((IStateManager)key).TrackViewState(); if (autoFieldProperties != null) { foreach (IStateManager sm in autoFieldProperties) sm.TrackViewState (); } } protected override object SaveViewState() { object[] states = new object [12]; 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] = (insertRowStyle == null ? null : ((IStateManager)insertRowStyle).SaveViewState()); states[9] = (editRowStyle == null ? null : ((IStateManager)editRowStyle).SaveViewState()); states[10] = (emptyDataRowStyle == null ? null : ((IStateManager)emptyDataRowStyle).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[11] != null) { object[] data = (object[]) states [11]; autoFieldProperties = new AutoGeneratedFieldProperties [data.Length]; for (int n=0; n