|
//------------------------------------------------------------------------------
// <copyright file="GridView.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
namespace System.Web.UI.WebControls {
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized; //for NameValueCollection
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Diagnostics.CodeAnalysis;
using System.Drawing;
using System.Drawing.Design;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Text;
using System.Web.Security.Cryptography;
using System.Web.UI.Adapters;
using System.Web.Util;
/// <devdoc>
/// <para>
/// Displays data from a data source in a tabular grid. The data source
/// is any object that implements IEnumerable, which includes ADO.NET data,
/// arrays, ArrayLists, DataSourceControl, etc.
/// </para>
/// </devdoc>
[
//Editor("System.Web.UI.Design.WebControls.GridViewComponentEditor, " + AssemblyRef.SystemDesign, typeof(ComponentEditor)),
Designer("System.Web.UI.Design.WebControls.GridViewDesigner, " + AssemblyRef.SystemDesign),
ControlValueProperty("SelectedValue"),
DefaultEvent("SelectedIndexChanged"),
SupportsEventValidation
]
[DataKeyProperty("SelectedPersistedDataKey")]
public class GridView : CompositeDataBoundControl, IPostBackContainer, IPostBackEventHandler, ICallbackContainer,
ICallbackEventHandler, IPersistedSelector, IDataKeysControl, IDataBoundListControl, IFieldControl {
private static readonly object EventPageIndexChanging = new object();
private static readonly object EventPageIndexChanged = new object();
private static readonly object EventRowCancelingEdit = new object();
private static readonly object EventRowCommand = new object();
private static readonly object EventRowCreated = new object();
private static readonly object EventRowDataBound = new object();
private static readonly object EventRowDeleted = new object();
private static readonly object EventRowDeleting = new object();
private static readonly object EventRowEditing = new object();
private static readonly object EventRowUpdated = new object();
private static readonly object EventRowUpdating = new object();
private static readonly object EventSelectedIndexChanging = new object();
private static readonly object EventSelectedIndexChanged = new object();
private static readonly object EventSorted = new object();
private static readonly object EventSorting = new object();
private IEnumerator _storedData;
private object _firstDataRow;
private bool _storedDataValid;
private int _pageCount = -1;
private DataControlFieldCollection _fieldCollection;
private TableItemStyle _headerStyle;
private TableItemStyle _footerStyle;
private TableItemStyle _rowStyle;
private TableItemStyle _alternatingRowStyle;
private TableItemStyle _selectedRowStyle;
private TableItemStyle _editRowStyle;
private TableItemStyle _emptyDataRowStyle;
private TableItemStyle _pagerStyle;
private TableItemStyle _sortedAscendingCellStyle;
private TableItemStyle _sortedDescendingCellStyle;
private TableItemStyle _sortedAscendingHeaderStyle;
private TableItemStyle _sortedDescendingHeaderStyle;
private PagerSettings _pagerSettings;
private ITemplate _pagerTemplate;
private ITemplate _emptyDataTemplate;
private GridViewRow _bottomPagerRow;
private GridViewRow _footerRow;
private GridViewRow _headerRow;
private GridViewRow _topPagerRow;
private ArrayList _rowsArray;
private GridViewRowCollection _rowsCollection;
private DataKeyArray _dataKeyArray;
private ArrayList _dataKeysArrayList;
private DataKeyArray _clientIDRowSuffixArray;
private ArrayList _clientIDRowSuffixArrayList;
private OrderedDictionary _boundFieldValues;
private string[] _dataKeyNames;
private string[] _clientIDRowSuffix;
private DataKey _persistedDataKey;
private int _editIndex = -1;
private int _selectedIndex = -1;
private int _pageIndex;
private string _sortExpression = String.Empty;
private SortDirection _sortDirection = SortDirection.Ascending;
private string _sortExpressionSerialized;
private string _modelValidationGroup;
private IAutoFieldGenerator _columnsGenerator;
private GridViewColumnsGenerator _defaultColumnsGenerator = new GridViewColumnsGenerator();
private IOrderedDictionary _updateKeys;
private IOrderedDictionary _updateOldValues;
private IOrderedDictionary _updateNewValues;
private IOrderedDictionary _deleteKeys;
private IOrderedDictionary _deleteValues;
private int _deletedRowIndex;
private bool _renderClientScript;
private bool _renderClientScriptValid = false;
IStateFormatter2 _stateFormatter;
/// <devdoc>
/// <para>
/// Initializes a new instance of the <see cref='System.Web.UI.WebControls.GridView'/> class.
/// </para>
/// </devdoc>
public GridView() {
}
internal GridView(IStateFormatter2 stateFormatter) {
_stateFormatter = stateFormatter;
}
/// <summary>
/// The name of the method on the page which is called when this Control does an update operation.
/// </summary>
[
DefaultValue(""),
Themeable(false),
WebCategory("Data"),
WebSysDescription(SR.DataBoundControl_UpdateMethod)
]
public new virtual string UpdateMethod {
get {
return base.UpdateMethod;
}
set {
base.UpdateMethod = value;
}
}
/// <summary>
/// The name of the method on the page which is called when this Control does a delete operation.
/// </summary>
[
DefaultValue(""),
Themeable(false),
WebCategory("Data"),
WebSysDescription(SR.DataBoundControl_DeleteMethod)
]
public new virtual string DeleteMethod {
get {
return base.DeleteMethod;
}
set {
base.DeleteMethod = value;
}
}
/// <devdoc>
/// <para>Gets or sets a value that indicates whether custom paging is allowed.</para>
/// </devdoc>
[
WebCategory("Paging"),
DefaultValue(false),
WebSysDescription(SR.GridView_AllowCustomPaging)
]
public virtual bool AllowCustomPaging {
get {
object o = ViewState["AllowCustomPaging"];
if (o != null)
return (bool)o;
return false;
}
set {
ViewState["AllowCustomPaging"] = value;
}
}
/// <devdoc>
/// <para>Gets or sets a value that indicates whether paging is allowed.</para>
/// </devdoc>
[
WebCategory("Paging"),
DefaultValue(false),
WebSysDescription(SR.GridView_AllowPaging)
]
public virtual bool AllowPaging {
get {
object o = ViewState["AllowPaging"];
if (o != null)
return (bool)o;
return false;
}
set {
bool oldValue = AllowPaging;
if (value != oldValue) {
ViewState["AllowPaging"] = value;
if (Initialized) {
RequiresDataBinding = true;
}
}
}
}
/// <devdoc>
/// <para>Gets or sets a value that indicates whether sorting is allowed.</para>
/// </devdoc>
[
WebCategory("Behavior"),
DefaultValue(false),
WebSysDescription(SR.GridView_AllowSorting)
]
public virtual bool AllowSorting {
get {
object o = ViewState["AllowSorting"];
if (o != null)
return (bool)o;
return false;
}
set {
bool oldValue = AllowSorting;
if (value != oldValue) {
ViewState["AllowSorting"] = value;
if (Initialized) {
RequiresDataBinding = true;
}
}
}
}
/// <devdoc>
/// <para>Gets the style properties for alternating rows in the
/// <see cref='System.Web.UI.WebControls.GridView'/>. This
/// property is read-only. </para>
/// </devdoc>
[
WebCategory("Styles"),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
NotifyParentProperty(true),
PersistenceMode(PersistenceMode.InnerProperty),
WebSysDescription(SR.GridView_AlternatingRowStyle)
]
public TableItemStyle AlternatingRowStyle {
get {
if (_alternatingRowStyle == null) {
_alternatingRowStyle = new TableItemStyle();
if (IsTrackingViewState)
((IStateManager)_alternatingRowStyle).TrackViewState();
}
return _alternatingRowStyle;
}
}
/// <devdoc>
/// <para>Gets or sets a value that indicates whether a delete field will automatically
/// be created.</para>
/// </devdoc>
[
WebCategory("Behavior"),
DefaultValue(false),
WebSysDescription(SR.GridView_AutoGenerateDeleteButton)
]
public virtual bool AutoGenerateDeleteButton {
get {
object o = ViewState["AutoGenerateDeleteButton"];
if (o != null)
return (bool)o;
return false;
}
set {
bool oldValue = AutoGenerateDeleteButton;
if (value != oldValue) {
ViewState["AutoGenerateDeleteButton"] = value;
if (Initialized) {
RequiresDataBinding = true;
}
}
}
}
/// <devdoc>
/// <para>Gets or sets a value that indicates whether an edit field will automatically
/// be created.</para>
/// </devdoc>
[
WebCategory("Behavior"),
DefaultValue(false),
WebSysDescription(SR.GridView_AutoGenerateEditButton)
]
public virtual bool AutoGenerateEditButton {
get {
object o = ViewState["AutoGenerateEditButton"];
if (o != null)
return (bool)o;
return false;
}
set {
bool oldValue = AutoGenerateEditButton;
if (value != oldValue) {
ViewState["AutoGenerateEditButton"] = value;
if (Initialized) {
RequiresDataBinding = true;
}
}
}
}
/// <devdoc>
/// <para>Gets or sets a value that indicates whether a select button will automatically
/// be created.</para>
/// </devdoc>
[
WebCategory("Behavior"),
DefaultValue(false),
WebSysDescription(SR.GridView_AutoGenerateSelectButton)
]
public virtual bool AutoGenerateSelectButton {
get {
object o = ViewState["AutoGenerateSelectButton"];
if (o != null)
return (bool)o;
return false;
}
set {
bool oldValue = AutoGenerateSelectButton;
if (value != oldValue) {
ViewState["AutoGenerateSelectButton"] = value;
if (Initialized) {
RequiresDataBinding = true;
}
}
}
}
/// <devdoc>
/// <para>Gets or sets a value that indicates whether fields will automatically
/// be created for each bound data field.</para>
/// </devdoc>
[
WebCategory("Behavior"),
DefaultValue(true),
WebSysDescription(SR.DataControls_AutoGenerateColumns)
]
public virtual bool AutoGenerateColumns {
get {
object o = ViewState["AutoGenerateColumns"];
if (o != null)
return (bool)o;
return true;
}
set {
bool oldValue = AutoGenerateColumns;
if (value != oldValue) {
ViewState["AutoGenerateColumns"] = value;
if (Initialized) {
RequiresDataBinding = true;
}
}
}
}
/// <devdoc>
/// <para>Gets or sets the URL of an image to display in the
/// background of the <see cref='System.Web.UI.WebControls.GridView'/>.</para>
/// </devdoc>
[
WebCategory("Appearance"),
DefaultValue(""),
Editor("System.Web.UI.Design.ImageUrlEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)),
UrlProperty(),
WebSysDescription(SR.WebControl_BackImageUrl)
]
public virtual string BackImageUrl {
get {
if (ControlStyleCreated == false) {
return String.Empty;
}
return ((TableStyle)ControlStyle).BackImageUrl;
}
set {
((TableStyle)ControlStyle).BackImageUrl = value;
}
}
[
Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
]
public virtual GridViewRow BottomPagerRow {
get {
if (_bottomPagerRow == null) {
EnsureChildControls();
}
return _bottomPagerRow;
}
}
private IOrderedDictionary BoundFieldValues {
get {
if (_boundFieldValues == null) {
int capacity = Columns.Count;
if (AutoGenerateColumns) {
capacity += 10;
}
_boundFieldValues = new OrderedDictionary(capacity);
}
return _boundFieldValues;
}
}
[
Localizable(true),
DefaultValue(""),
WebCategory("Accessibility"),
WebSysDescription(SR.DataControls_Caption)
]
public virtual string Caption {
get {
string s = (string)ViewState["Caption"];
return (s != null) ? s : String.Empty;
}
set {
ViewState["Caption"] = value;
}
}
[
DefaultValue(TableCaptionAlign.NotSet),
WebCategory("Accessibility"),
WebSysDescription(SR.WebControl_CaptionAlign)
]
public virtual TableCaptionAlign CaptionAlign {
get {
object o = ViewState["CaptionAlign"];
return (o != null) ? (TableCaptionAlign)o : TableCaptionAlign.NotSet;
}
set {
if ((value < TableCaptionAlign.NotSet) ||
(value > TableCaptionAlign.Right)) {
throw new ArgumentOutOfRangeException("value");
}
ViewState["CaptionAlign"] = value;
}
}
/// <devdoc>
/// <para>Indicates the amount of space between cells.</para>
/// </devdoc>
[
WebCategory("Layout"),
DefaultValue(-1),
WebSysDescription(SR.GridView_CellPadding)
]
public virtual int CellPadding {
get {
if (ControlStyleCreated == false) {
return -1;
}
return ((TableStyle)ControlStyle).CellPadding;
}
set {
((TableStyle)ControlStyle).CellPadding = value;
}
}
/// <devdoc>
/// <para>Gets or sets the amount of space between the contents of
/// a cell and the cell's border.</para>
/// </devdoc>
[
WebCategory("Layout"),
DefaultValue(0),
WebSysDescription(SR.GridView_CellSpacing)
]
public virtual int CellSpacing {
get {
if (ControlStyleCreated == false) {
return 0;
}
return ((TableStyle)ControlStyle).CellSpacing;
}
set {
((TableStyle)ControlStyle).CellSpacing = value;
}
}
/// <devdoc>
/// <para>Gets a collection of <see cref='System.Web.UI.WebControls.DataControlField'/> controls in the <see cref='System.Web.UI.WebControls.GridView'/>. This property is read-only.</para>
/// </devdoc>
[
DefaultValue(null),
Editor("System.Web.UI.Design.WebControls.DataControlFieldTypeEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)),
MergableProperty(false),
PersistenceMode(PersistenceMode.InnerProperty),
WebCategory("Default"),
WebSysDescription(SR.DataControls_Columns)
]
public virtual DataControlFieldCollection Columns {
get {
if (_fieldCollection == null) {
_fieldCollection = new DataControlFieldCollection();
_fieldCollection.FieldsChanged += new EventHandler(OnFieldsChanged);
if (IsTrackingViewState)
((IStateManager)_fieldCollection).TrackViewState();
}
return _fieldCollection;
}
}
[
Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
]
public IAutoFieldGenerator ColumnsGenerator {
get {
return _columnsGenerator;
}
set {
_columnsGenerator = value;
}
}
private IAutoFieldGenerator ColumnsGeneratorInternal {
get {
return ColumnsGenerator ?? _defaultColumnsGenerator;
}
}
/// <devdoc>
/// An array of ordered dictionaries that represents each key
/// </devdoc>
private ArrayList DataKeysArrayList {
get {
if (_dataKeysArrayList == null) {
_dataKeysArrayList = new ArrayList();
}
return _dataKeysArrayList;
}
}
private ArrayList ClientIDRowSuffixArrayList {
get {
if (_clientIDRowSuffixArrayList == null) {
_clientIDRowSuffixArrayList = new ArrayList();
}
return _clientIDRowSuffixArrayList;
}
}
/// <devdoc>
/// </devdoc>
[
Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
WebSysDescription(SR.GridView_DataKeys)
]
public virtual DataKeyArray DataKeys {
get {
if (_dataKeyArray == null) {
_dataKeyArray = new DataKeyArray(this.DataKeysArrayList);
if (IsTrackingViewState)
((IStateManager)_dataKeyArray).TrackViewState();
}
return _dataKeyArray;
}
}
[SuppressMessage("Microsoft.Naming", "CA1706:ShortAcronymsShouldBeUppercase", MessageId = "Member")]
[
Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
]
public DataKeyArray ClientIDRowSuffixDataKeys {
get {
if (_clientIDRowSuffixArray == null) {
_clientIDRowSuffixArray = new DataKeyArray(this.ClientIDRowSuffixArrayList);
}
return _clientIDRowSuffixArray;
}
}
[
DefaultValue(null),
Editor("System.Web.UI.Design.WebControls.DataFieldEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)),
TypeConverterAttribute(typeof(StringArrayConverter)),
WebCategory("Data"),
WebSysDescription(SR.DataControls_DataKeyNames),
]
public virtual string[] DataKeyNames {
get {
object o = _dataKeyNames;
if (o != null) {
return (string[])((string[])o).Clone();
}
return new string[0];
}
set {
if (!DataBoundControlHelper.CompareStringArrays(value, DataKeyNamesInternal)) {
if (value != null) {
_dataKeyNames = (string[])value.Clone();
}
else {
_dataKeyNames = null;
}
ClearDataKeys();
if (Initialized) {
RequiresDataBinding = true;
}
}
}
}
// This version doesn't clone the array
private string[] DataKeyNamesInternal {
get {
object o = _dataKeyNames;
if (o != null) {
return (string[])o;
}
return new string[0];
}
}
/// <devdoc>
/// <para>Gets or sets the ordinal index of the row to be edited.</para>
/// </devdoc>
[
WebCategory("Default"),
DefaultValue(-1),
WebSysDescription(SR.GridView_EditIndex)
]
public virtual int EditIndex {
get {
return _editIndex;
}
set {
if (value < -1) {
throw new ArgumentOutOfRangeException("value");
}
int oldValue = EditIndex;
if (oldValue != value) {
if (value == -1) {
BoundFieldValues.Clear();
}
_editIndex = value;
if (Initialized) {
RequiresDataBinding = true;
}
}
}
}
/// <devdoc>
/// <para>Gets the style properties of the row to be edited. This property is read-only.</para>
/// </devdoc>
[
WebCategory("Styles"),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
NotifyParentProperty(true),
PersistenceMode(PersistenceMode.InnerProperty),
WebSysDescription(SR.GridView_EditRowStyle)
]
public TableItemStyle EditRowStyle {
get {
if (_editRowStyle == null) {
_editRowStyle = new TableItemStyle();
if (IsTrackingViewState)
((IStateManager)_editRowStyle).TrackViewState();
}
return _editRowStyle;
}
}
[
WebCategory("Behavior"),
DefaultValue(true),
WebSysDescription(SR.DataBoundControl_EnableModelValidation)
]
public virtual bool EnableModelValidation {
get {
object o = ViewState["EnableModelValidation"];
if (o != null) {
return (bool)o;
}
return true;
}
set {
ViewState["EnableModelValidation"] = value;
}
}
[
WebCategory("Behavior"),
DefaultValue(false),
WebSysDescription(SR.GridView_EnablePersistedSelection)
]
public virtual bool EnablePersistedSelection {
get {
object o = ViewState["EnablePersistedSelection"];
if (o != null) {
return (bool)o;
}
return false;
}
set {
ViewState["EnablePersistedSelection"] = value;
}
}
[
WebCategory("Behavior"),
DefaultValue(false),
WebSysDescription(SR.GridView_EnableSortingAndPagingCallbacks)
]
public virtual bool EnableSortingAndPagingCallbacks {
get {
object o = ViewState["EnableSortingAndPagingCallbacks"];
if (o != null) {
return (bool)o;
}
return false;
}
set {
ViewState["EnableSortingAndPagingCallbacks"] = value;
}
}
private int FirstDisplayedPageIndex {
get {
object o = ViewState["FirstDisplayedPageIndex"];
if (o != null) {
return (int)o;
}
return -1;
}
set {
ViewState["FirstDisplayedPageIndex"] = value;
}
}
/// <devdoc>
/// <para>Gets the style properties for null rows in the
/// <see cref='System.Web.UI.WebControls.GridView'/>. This
/// property is read-only. </para>
/// </devdoc>
[
WebCategory("Styles"),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
NotifyParentProperty(true),
PersistenceMode(PersistenceMode.InnerProperty),
WebSysDescription(SR.GridView_EmptyDataRowStyle)
]
public TableItemStyle EmptyDataRowStyle {
get {
if (_emptyDataRowStyle == null) {
_emptyDataRowStyle = new TableItemStyle();
if (IsTrackingViewState)
((IStateManager)_emptyDataRowStyle).TrackViewState();
}
return _emptyDataRowStyle;
}
}
/// <devdoc>
/// <para>Indicates the template to use when no records are returned from the datasource within the GridView.
/// </devdoc>
[
Browsable(false),
DefaultValue(null),
PersistenceMode(PersistenceMode.InnerProperty),
TemplateContainer(typeof(GridViewRow)),
WebSysDescription(SR.View_EmptyDataTemplate)
]
public virtual ITemplate EmptyDataTemplate {
get {
return _emptyDataTemplate;
}
set {
_emptyDataTemplate = value;
}
}
/// <devdoc>
/// <para>The header text displayed if no EmptyDataTemplate is defined.
/// </devdoc>
[
Localizable(true),
WebCategory("Appearance"),
DefaultValue(""),
WebSysDescription(SR.View_EmptyDataText),
]
public virtual String EmptyDataText {
get {
object o = ViewState["EmptyDataText"];
if (o != null) {
return (string)o;
}
return String.Empty;
}
set {
ViewState["EmptyDataText"] = value;
}
}
[
Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
]
public virtual GridViewRow FooterRow {
get {
if (_footerRow == null) {
EnsureChildControls();
}
return _footerRow;
}
}
/// <devdoc>
/// <para>Gets the style properties of the footer row. This property is read-only.</para>
/// </devdoc>
[
WebCategory("Styles"),
DefaultValue(null),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
NotifyParentProperty(true),
PersistenceMode(PersistenceMode.InnerProperty),
WebSysDescription(SR.DataControls_FooterStyle),
]
public TableItemStyle FooterStyle {
get {
if (_footerStyle == null) {
_footerStyle = new TableItemStyle();
if (IsTrackingViewState)
((IStateManager)_footerStyle).TrackViewState();
}
return _footerStyle;
}
}
/// <devdoc>
/// <para>Gets or sets a value that specifies the grid line style.</para>
/// </devdoc>
[
WebCategory("Appearance"),
DefaultValue(GridLines.Both),
WebSysDescription(SR.DataControls_GridLines)
]
public virtual GridLines GridLines {
get {
if (ControlStyleCreated == false) {
return GridLines.Both;
}
return ((TableStyle)ControlStyle).GridLines;
}
set {
((TableStyle)ControlStyle).GridLines = value;
}
}
[
Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
]
public virtual GridViewRow HeaderRow {
get {
if (_headerRow == null) {
EnsureChildControls();
}
return _headerRow;
}
}
/// <devdoc>
/// <para>Gets the style properties of the header row. This property is read-only.</para>
/// </devdoc>
[
WebCategory("Styles"),
DefaultValue(null),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
NotifyParentProperty(true),
PersistenceMode(PersistenceMode.InnerProperty),
WebSysDescription(SR.DataControls_HeaderStyle)
]
public TableItemStyle HeaderStyle {
get {
if (_headerStyle == null) {
_headerStyle = new TableItemStyle();
if (IsTrackingViewState)
((IStateManager)_headerStyle).TrackViewState();
}
return _headerStyle;
}
}
/// <devdoc>
/// <para>Gets or sets a value that specifies the alignment of a rows with respect
/// surrounding text.</para>
/// </devdoc>
[
Category("Layout"),
DefaultValue(HorizontalAlign.NotSet),
WebSysDescription(SR.WebControl_HorizontalAlign)
]
public virtual HorizontalAlign HorizontalAlign {
get {
if (ControlStyleCreated == false) {
return HorizontalAlign.NotSet;
}
return ((TableStyle)ControlStyle).HorizontalAlign;
}
set {
((TableStyle)ControlStyle).HorizontalAlign = value;
}
}
/// <summary>
/// Determines if the specified data type can be bound to.
/// Note : Staring from 4.5, This method is no more being used as a criteria for generating rows when AutoGenerateColumns=true.
/// This could become obsolete in future versions.
/// </summary>
public virtual bool IsBindableType(Type type) {
return DataBoundControlHelper.IsBindableType(type, enableEnums: RenderingCompatibility >= VersionUtil.Framework45);
}
/// <devdoc>
/// <para>Gets the total number of pages to be displayed. This property is read-only.</para>
/// </devdoc>
[
Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
WebSysDescription(SR.GridView_PageCount)
]
public virtual int PageCount {
get {
if (_pageCount < 0) {
// If someone reads this value before it is initialized we just return 0
return 0;
}
return _pageCount;
}
}
/// <devdoc>
/// <para>Gets or sets the ordinal index of the currently displayed page. </para>
/// </devdoc>
[
Browsable(true),
DefaultValue(0),
WebCategory("Paging"),
WebSysDescription(SR.GridView_PageIndex)
]
public virtual int PageIndex {
get {
return _pageIndex;
}
set {
if (value < 0) {
throw new ArgumentOutOfRangeException("value");
}
int oldValue = PageIndex;
if (oldValue != value) {
_pageIndex = value;
if (Initialized) {
RequiresDataBinding = true;
}
}
}
}
/// <devdoc>
/// <para>Gets the settings of the pager buttons for the
/// <see cref='System.Web.UI.WebControls.GridView'/>. This
/// property is read-only.</para>
/// </devdoc>
[
WebCategory("Paging"),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
NotifyParentProperty(true),
PersistenceMode(PersistenceMode.InnerProperty),
WebSysDescription(SR.GridView_PagerSettings)
]
public virtual PagerSettings PagerSettings {
get {
if (_pagerSettings == null) {
_pagerSettings = new PagerSettings();
if (IsTrackingViewState) {
((IStateManager)_pagerSettings).TrackViewState();
}
_pagerSettings.PropertyChanged += new EventHandler(OnPagerPropertyChanged);
}
return _pagerSettings;
}
}
/// <devdoc>
/// <para>Gets the style properties of the pager rows for the
/// <see cref='System.Web.UI.WebControls.GridView'/>. This
/// property is read-only.</para>
/// </devdoc>
[
WebCategory("Styles"),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
NotifyParentProperty(true),
PersistenceMode(PersistenceMode.InnerProperty),
WebSysDescription(SR.WebControl_PagerStyle)
]
public TableItemStyle PagerStyle {
get {
if (_pagerStyle == null) {
_pagerStyle = new TableItemStyle();
if (IsTrackingViewState)
((IStateManager)_pagerStyle).TrackViewState();
}
return _pagerStyle;
}
}
/// <devdoc>
/// <para>Indicates the template to use for a pager item within the GridView.
/// </devdoc>
[
Browsable(false),
DefaultValue(null),
PersistenceMode(PersistenceMode.InnerProperty),
TemplateContainer(typeof(GridViewRow)),
WebSysDescription(SR.View_PagerTemplate)
]
public virtual ITemplate PagerTemplate {
get {
return _pagerTemplate;
}
set {
_pagerTemplate = value;
}
}
/// <devdoc>
/// <para>Gets or sets the number of rows to display on a single page.</para>
/// </devdoc>
[
WebCategory("Paging"),
DefaultValue(10),
WebSysDescription(SR.GridView_PageSize),
]
public virtual int PageSize {
get {
object o = ViewState["PageSize"];
if (o != null)
return (int)o;
return 10;
}
set {
if (value < 1) {
throw new ArgumentOutOfRangeException("value");
}
int oldValue = PageSize;
if (oldValue != value) {
ViewState["PageSize"] = value;
if (Initialized) {
RequiresDataBinding = true;
}
}
}
}
[SuppressMessage("Microsoft.Naming", "CA1706:ShortAcronymsShouldBeUppercase", MessageId = "Member")]
[
DefaultValue(null),
TypeConverterAttribute(typeof(StringArrayConverter)),
WebCategory("Data"),
]
public virtual string[] ClientIDRowSuffix {
get {
object o = _clientIDRowSuffix;
if (o != null) {
return (string[])((string[])o).Clone();
}
return new string[0];
}
set {
if (!DataBoundControlHelper.CompareStringArrays(value, ClientIDRowSuffixInternal)) {
if (value != null) {
_clientIDRowSuffix = (string[])value.Clone();
}
else {
_clientIDRowSuffix = null;
}
_clientIDRowSuffixArrayList = null;
if (Initialized) {
RequiresDataBinding = true;
}
}
}
}
private string[] ClientIDRowSuffixInternal {
get {
object o = _clientIDRowSuffix;
if (o != null) {
return (string[])o;
}
return new string[0];
}
}
/// <devdoc>
/// <para>The column to be used as the scope=row header.</para>
/// </devdoc>
[
DefaultValue(""),
TypeConverterAttribute("System.Web.UI.Design.DataColumnSelectionConverter, " + AssemblyRef.SystemDesign),
WebCategory("Accessibility"),
WebSysDescription(SR.GridView_RowHeaderColumn)
]
public virtual string RowHeaderColumn {
get {
object o = ViewState["RowHeaderColumn"];
return o == null ? String.Empty : (string)o;
}
set {
ViewState["RowHeaderColumn"] = value;
}
}
/// <devdoc>
/// <para>Gets a collection of <see cref='System.Web.UI.WebControls.GridViewRow'/> objects representing the individual
/// rows within the control.
/// This property is read-only.</para>
/// </devdoc>
[
Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
WebSysDescription(SR.GridView_Rows)
]
public virtual GridViewRowCollection Rows {
get {
if (_rowsCollection == null) {
if (_rowsArray == null) {
EnsureChildControls();
}
if (_rowsArray == null) {
_rowsArray = new ArrayList();
}
_rowsCollection = new GridViewRowCollection(_rowsArray);
}
return _rowsCollection;
}
}
/// <devdoc>
/// <para>Gets the style properties of the individual rows. This property is read-only.</para>
/// </devdoc>
[
WebCategory("Styles"),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
NotifyParentProperty(true),
PersistenceMode(PersistenceMode.InnerProperty),
WebSysDescription(SR.View_RowStyle),
]
public TableItemStyle RowStyle {
get {
if (_rowStyle == null) {
_rowStyle = new TableItemStyle();
if (IsTrackingViewState)
((IStateManager)_rowStyle).TrackViewState();
}
return _rowStyle;
}
}
[
Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
]
public virtual DataKey SelectedDataKey {
get {
if (DataKeyNamesInternal == null || DataKeyNamesInternal.Length == 0) {
throw new InvalidOperationException(SR.GetString(SR.GridView_DataKeyNamesMustBeSpecified, ID));
}
DataKeyArray keys = DataKeys;
int selectedIndex = SelectedIndex;
if (keys != null && selectedIndex < keys.Count && selectedIndex > -1) {
return keys[selectedIndex];
}
return null;
}
}
/// <devdoc>
/// <para>Gets or sets the index of the currently selected row.</para>
/// </devdoc>
[
Bindable(true),
DefaultValue(-1),
WebSysDescription(SR.GridView_SelectedIndex)
]
public virtual int SelectedIndex {
get {
return _selectedIndex;
}
set {
if (value < -1) {
throw new ArgumentOutOfRangeException("value");
}
int oldSelectedIndex = _selectedIndex;
_selectedIndex = value;
if ((DataKeyNamesInternal.Length > 0) && EnablePersistedSelection) {
// update the virtual selection to use the new selection
SelectedPersistedDataKey = SelectedDataKey;
}
if (_rowsArray != null) {
GridViewRow row;
if ((oldSelectedIndex != -1) && (_rowsArray.Count > oldSelectedIndex)) {
row = (GridViewRow)_rowsArray[oldSelectedIndex];
row.RowType = DataControlRowType.DataRow;
row.RowState &= ~DataControlRowState.Selected; // turn off selected bit
}
if ((value != -1) && (_rowsArray.Count > value)) {
row = (GridViewRow)_rowsArray[value];
row.RowState |= DataControlRowState.Selected; // turn on selected bit
}
}
}
}
[
Browsable(false)
]
public object SelectedValue {
get {
DataKey selectedDataKey = SelectedDataKey;
if (selectedDataKey != null) {
return SelectedDataKey.Value;
}
return null;
}
}
/// <devdoc>
/// <para>Gets the selected row in the <see cref='System.Web.UI.WebControls.GridView'/>. This property is read-only.</para>
/// </devdoc>
[
Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
WebSysDescription(SR.GridView_SelectedRow)
]
public virtual GridViewRow SelectedRow {
get {
int index = SelectedIndex;
GridViewRow row = null;
if (index != -1) {
row = Rows[index];
}
return row;
}
}
/// <devdoc>
/// <para>Gets the style properties of the currently selected row. This property is read-only.</para>
/// </devdoc>
[
WebCategory("Styles"),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
NotifyParentProperty(true),
PersistenceMode(PersistenceMode.InnerProperty),
WebSysDescription(SR.GridView_SelectedRowStyle)
]
public TableItemStyle SelectedRowStyle {
get {
if (_selectedRowStyle == null) {
_selectedRowStyle = new TableItemStyle();
if (IsTrackingViewState)
((IStateManager)_selectedRowStyle).TrackViewState();
}
return _selectedRowStyle;
}
}
/// <devdoc>
/// <para>Gets or sets a value that specifies whether the footer is displayed in the
/// <see cref='System.Web.UI.WebControls.GridView'/>.</para>
/// </devdoc>
[
WebCategory("Appearance"),
DefaultValue(false),
WebSysDescription(SR.DataControls_ShowFooter)
]
public virtual bool ShowFooter {
get {
object o = ViewState["ShowFooter"];
if (o != null)
return (bool)o;
return false;
}
set {
bool oldValue = ShowFooter;
if (value != oldValue) {
ViewState["ShowFooter"] = value;
if (Initialized) {
RequiresDataBinding = true;
}
}
}
}
/// <devdoc>
/// <para>Gets or sets a value that specifies whether the header is displayed in the
/// <see cref='System.Web.UI.WebControls.GridView'/>.</para>
/// </devdoc>
[
WebCategory("Appearance"),
DefaultValue(true),
WebSysDescription(SR.DataControls_ShowHeader)
]
public virtual bool ShowHeader {
get {
object o = ViewState["ShowHeader"];
if (o != null)
return (bool)o;
return true;
}
set {
bool oldValue = ShowHeader;
if (value != oldValue) {
ViewState["ShowHeader"] = value;
if (Initialized) {
RequiresDataBinding = true;
}
}
}
}
[
WebCategory("Appearance"),
DefaultValue(false),
WebSysDescription(SR.GridView_ShowHeaderWhenEmpty)
]
public virtual bool ShowHeaderWhenEmpty {
get {
object o = ViewState["ShowHeaderWhenEmpty"];
if (o != null)
return (bool)o;
return false;
}
set {
bool oldValue = ShowHeaderWhenEmpty;
if (value != oldValue) {
ViewState["ShowHeaderWhenEmpty"] = value;
if (Initialized) {
RequiresDataBinding = true;
}
}
}
}
/// <summary>
/// Indicates the direction of the sort for the current column in the
/// <see cref='System.Web.UI.WebControls.GridView'/>.
/// </summary>
[
Browsable(false),
DefaultValue(SortDirection.Ascending),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
PersistenceMode(PersistenceMode.InnerProperty),
WebSysDescription(SR.GridView_SortDirection)
]
public virtual SortDirection SortDirection {
get {
return SortDirectionInternal;
}
}
/// <summary>
/// Internal member for setting sort direction
/// </summary>
private SortDirection SortDirectionInternal {
get {
return _sortDirection;
}
set {
if (value < SortDirection.Ascending || value > SortDirection.Descending) {
throw new ArgumentOutOfRangeException("value");
}
if (_sortDirection != value) {
_sortDirection = value;
if (Initialized) {
RequiresDataBinding = true;
}
}
}
}
/// <summary>
/// Gets a value that specifies the current column being sorted on in the
/// <see cref='System.Web.UI.WebControls.GridView'/>.
/// </summary>
[
Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
WebSysDescription(SR.GridView_SortExpression)
]
public virtual string SortExpression {
get {
return SortExpressionInternal;
}
}
/// <summary>
/// Internal member for setting sort expression
/// </summary>
private string SortExpressionInternal {
get {
return _sortExpression;
}
set {
if (_sortExpression != value) {
_sortExpression = value;
if (Initialized) {
RequiresDataBinding = true;
}
}
}
}
[
WebCategory("Styles"),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
NotifyParentProperty(true),
PersistenceMode(PersistenceMode.InnerProperty),
WebSysDescription(SR.GridView_SortedAscendingCellStyle)
]
public TableItemStyle SortedAscendingCellStyle {
get {
if (_sortedAscendingCellStyle == null) {
_sortedAscendingCellStyle = new TableItemStyle();
if (IsTrackingViewState)
((IStateManager)_sortedAscendingCellStyle).TrackViewState();
}
return _sortedAscendingCellStyle;
}
}
[
WebCategory("Styles"),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
NotifyParentProperty(true),
PersistenceMode(PersistenceMode.InnerProperty),
WebSysDescription(SR.GridView_SortedAscendingHeaderStyle)
]
public TableItemStyle SortedAscendingHeaderStyle {
get {
if (_sortedAscendingHeaderStyle == null) {
_sortedAscendingHeaderStyle = new TableItemStyle();
if (IsTrackingViewState)
((IStateManager)_sortedAscendingHeaderStyle).TrackViewState();
}
return _sortedAscendingHeaderStyle;
}
}
[
WebCategory("Styles"),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
NotifyParentProperty(true),
PersistenceMode(PersistenceMode.InnerProperty),
WebSysDescription(SR.GridView_SortedDescendingCellStyle)
]
public TableItemStyle SortedDescendingCellStyle {
get {
if (_sortedDescendingCellStyle == null) {
_sortedDescendingCellStyle = new TableItemStyle();
if (IsTrackingViewState)
((IStateManager)_sortedDescendingCellStyle).TrackViewState();
}
return _sortedDescendingCellStyle;
}
}
[
WebCategory("Styles"),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
NotifyParentProperty(true),
PersistenceMode(PersistenceMode.InnerProperty),
WebSysDescription(SR.GridView_SortedDescendingHeaderStyle)
]
public TableItemStyle SortedDescendingHeaderStyle {
get {
if (_sortedDescendingHeaderStyle == null) {
_sortedDescendingHeaderStyle = new TableItemStyle();
if (IsTrackingViewState)
((IStateManager)_sortedDescendingHeaderStyle).TrackViewState();
}
return _sortedDescendingHeaderStyle;
}
}
private IStateFormatter2 StateFormatter {
get {
if (_stateFormatter == null) {
_stateFormatter = Page.CreateStateFormatter();
}
return _stateFormatter;
}
}
protected override HtmlTextWriterTag TagKey {
get {
return EnableSortingAndPagingCallbacks ?
HtmlTextWriterTag.Div : HtmlTextWriterTag.Table;
}
}
[
Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
]
public virtual GridViewRow TopPagerRow {
get {
if (_topPagerRow == null) {
EnsureChildControls();
}
return _topPagerRow;
}
}
[
DefaultValue(true),
WebCategory("Accessibility"),
WebSysDescription(SR.Table_UseAccessibleHeader)
]
public virtual bool UseAccessibleHeader {
get {
object o = ViewState["UseAccessibleHeader"];
if (o != null)
return (bool)o;
return true;
}
set {
bool oldValue = UseAccessibleHeader;
if (oldValue != value) {
ViewState["UseAccessibleHeader"] = value;
if (Initialized) {
RequiresDataBinding = true;
}
}
}
}
/// <devdoc>
/// Gets or sets the number of rows to display in the
/// <see cref='System.Web.UI.WebControls.DataGrid'/>.
/// </devdoc>
[
Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
WebSysDescription(SR.GridView_VirtualItemCount)
]
public virtual int VirtualItemCount {
get {
object o = ViewState["VirtualItemCount"];
if (o != null)
return (int)o;
return 0;
}
set {
if (value < 0) {
throw new ArgumentOutOfRangeException("value");
}
ViewState["VirtualItemCount"] = value;
}
}
[
Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
]
public virtual DataKey SelectedPersistedDataKey {
get {
return _persistedDataKey;
}
set {
_persistedDataKey = value;
if (IsTrackingViewState && (_persistedDataKey != null)) {
((IStateManager)_persistedDataKey).TrackViewState();
}
}
}
/// <devdoc>
/// <para>Occurs when a control bubbles an event to the <see cref='System.Web.UI.WebControls.GridView'/> with a
/// <see langword='delete'/>.</para>
/// </devdoc>
[
WebCategory("Action"),
WebSysDescription(SR.DataControls_OnRowDeleted)
]
public event GridViewDeletedEventHandler RowDeleted {
add {
Events.AddHandler(EventRowDeleted, value);
}
remove {
Events.RemoveHandler(EventRowDeleted, value);
}
}
/// <devdoc>
/// <para>Occurs when a control bubbles an event to the <see cref='System.Web.UI.WebControls.GridView'/> with a
/// <see langword='update'/>.</para>
/// </devdoc>
[
WebCategory("Action"),
WebSysDescription(SR.DataControls_OnItemUpdated)
]
public event GridViewUpdatedEventHandler RowUpdated {
add {
Events.AddHandler(EventRowUpdated, value);
}
remove {
Events.RemoveHandler(EventRowUpdated, value);
}
}
/// <devdoc>
/// <para>Occurs when a control bubbles an event to the <see cref='System.Web.UI.WebControls.GridView'/> with a
/// <see langword='Command'/> property of
/// <see langword='cancel'/>.</para>
/// </devdoc>
[
WebCategory("Action"),
WebSysDescription(SR.GridView_OnRowCancelingEdit)
]
public event GridViewCancelEditEventHandler RowCancelingEdit {
add {
Events.AddHandler(EventRowCancelingEdit, value);
}
remove {
Events.RemoveHandler(EventRowCancelingEdit, value);
}
}
/// <devdoc>
/// <para>Occurs when a control bubbles an event to the <see cref='System.Web.UI.WebControls.GridView'/> with a
/// <see langword='delete'/>.</para>
/// </devdoc>
[
WebCategory("Action"),
WebSysDescription(SR.DataControls_OnItemDeleting)
]
public event GridViewDeleteEventHandler RowDeleting {
add {
Events.AddHandler(EventRowDeleting, value);
}
remove {
Events.RemoveHandler(EventRowDeleting, value);
}
}
/// <devdoc>
/// <para>Occurs when a control bubbles an event to the <see cref='System.Web.UI.WebControls.GridView'/> with a
/// <see langword='Command'/> property of
/// <see langword='edit'/>.</para>
/// </devdoc>
[
WebCategory("Action"),
WebSysDescription(SR.GridView_OnRowEditing)
]
public event GridViewEditEventHandler RowEditing {
add {
Events.AddHandler(EventRowEditing, value);
}
remove {
Events.RemoveHandler(EventRowEditing, value);
}
}
/// <devdoc>
/// <para>Occurs the one of the pager buttons is clicked.</para>
/// </devdoc>
[
WebCategory("Action"),
WebSysDescription(SR.GridView_OnPageIndexChanged)
]
public event EventHandler PageIndexChanged {
add {
Events.AddHandler(EventPageIndexChanged, value);
}
remove {
Events.RemoveHandler(EventPageIndexChanged, value);
}
}
/// <devdoc>
/// <para>Occurs the one of the pager buttons is clicked.</para>
/// </devdoc>
[
WebCategory("Action"),
WebSysDescription(SR.GridView_OnPageIndexChanging)
]
public event GridViewPageEventHandler PageIndexChanging {
add {
Events.AddHandler(EventPageIndexChanging, value);
}
remove {
Events.RemoveHandler(EventPageIndexChanging, value);
}
}
/// <devdoc>
/// <para>Occurs when an row on the list is selected.</para>
/// </devdoc>
[
WebCategory("Action"),
WebSysDescription(SR.GridView_OnSelectedIndexChanged)
]
public event EventHandler SelectedIndexChanged {
add {
Events.AddHandler(EventSelectedIndexChanged, value);
}
remove {
Events.RemoveHandler(EventSelectedIndexChanged, value);
}
}
/// <devdoc>
/// <para>Occurs when an row on the list is selected.</para>
/// </devdoc>
[
WebCategory("Action"),
WebSysDescription(SR.GridView_OnSelectedIndexChanging)
]
public event GridViewSelectEventHandler SelectedIndexChanging {
add {
Events.AddHandler(EventSelectedIndexChanging, value);
}
remove {
Events.RemoveHandler(EventSelectedIndexChanging, value);
}
}
/// <devdoc>
/// <para>Occurs when a field is sorted.</para>
/// </devdoc>
[
WebCategory("Action"),
WebSysDescription(SR.GridView_OnSorted)
]
public event EventHandler Sorted {
add {
Events.AddHandler(EventSorted, value);
}
remove {
Events.RemoveHandler(EventSorted, value);
}
}
/// <devdoc>
/// <para>Occurs when a field is sorting.</para>
/// </devdoc>
[
WebCategory("Action"),
WebSysDescription(SR.GridView_OnSorting)
]
public event GridViewSortEventHandler Sorting {
add {
Events.AddHandler(EventSorting, value);
}
remove {
Events.RemoveHandler(EventSorting, value);
}
}
/// <devdoc>
/// <para>Occurs when a control bubbles an event to the <see cref='System.Web.UI.WebControls.GridView'/> with a
/// <see langword='update'/>.</para>
/// </devdoc>
[
WebCategory("Action"),
WebSysDescription(SR.DataControls_OnItemUpdating)
]
public event GridViewUpdateEventHandler RowUpdating {
add {
Events.AddHandler(EventRowUpdating, value);
}
remove {
Events.RemoveHandler(EventRowUpdating, value);
}
}
/// <devdoc>
/// <para>Occurs when a control bubbles an event to the <see cref='System.Web.UI.WebControls.GridView'/> not covered by
/// <see langword='edit'/>, <see langword='cancel'/>, <see langword='delete'/> or
/// <see langword='update'/>.</para>
/// </devdoc>
[
WebCategory("Action"),
WebSysDescription(SR.GridView_OnRowCommand)
]
public event GridViewCommandEventHandler RowCommand {
add {
Events.AddHandler(EventRowCommand, value);
}
remove {
Events.RemoveHandler(EventRowCommand, value);
}
}
/// <devdoc>
/// <para>Occurs on the server when a control a created.</para>
/// </devdoc>
[
WebCategory("Behavior"),
WebSysDescription(SR.GridView_OnRowCreated)
]
public event GridViewRowEventHandler RowCreated {
add {
Events.AddHandler(EventRowCreated, value);
}
remove {
Events.RemoveHandler(EventRowCreated, value);
}
}
/// <devdoc>
/// <para>Occurs when an row is data bound to the control.</para>
/// </devdoc>
[
WebCategory("Data"),
WebSysDescription(SR.GridView_OnRowDataBound)
]
public event GridViewRowEventHandler RowDataBound {
add {
Events.AddHandler(EventRowDataBound, value);
}
remove {
Events.RemoveHandler(EventRowDataBound, value);
}
}
/// <internalonly/>
/// <devdoc>
/// Caches the fact that we have already consumed the first row from the enumeration
/// and must use it first during our row creation.
/// </devdoc>
internal void StoreEnumerator(IEnumerator dataSource, object firstDataRow) {
this._storedData = dataSource;
this._firstDataRow = firstDataRow;
this._storedDataValid = true;
}
/// <devdoc>
/// <para>Builds the callback argument used in DataControlLinkButtons.</para>
/// </devdoc>
private string BuildCallbackArgument(string sortExpression, SortDirection sortDirection) {
return "\"" + PageIndex + "|" + (int)sortDirection + "|" + StateFormatter.Serialize(sortExpression, Purpose.WebForms_GridView_SortExpression) + "|\"";
}
/// <devdoc>
/// <para>Builds the callback argument used in DataControlLinkButtons.</para>
/// </devdoc>
private string BuildCallbackArgument(int pageIndex) {
if (String.IsNullOrEmpty(_sortExpressionSerialized)) {
_sortExpressionSerialized = StateFormatter.Serialize(SortExpression, Purpose.WebForms_GridView_SortExpression);
}
return "\"" + pageIndex + "|" + (int)SortDirection + "|" + _sortExpressionSerialized + "|\"";
}
private void ClearDataKeys() {
_dataKeysArrayList = null;
}
/// <devdoc>
/// Create a single autogenerated row. This function can be overridden to create a different AutoGeneratedField.
/// </devdoc>
[Obsolete("This is kept for backward compatibility - this API is no more used")]
protected virtual AutoGeneratedField CreateAutoGeneratedColumn(AutoGeneratedFieldProperties fieldProperties) {
AutoGeneratedField field = new AutoGeneratedField(fieldProperties.DataField);
string name = fieldProperties.Name;
((IStateManager)field).TrackViewState();
field.HeaderText = name;
field.SortExpression = name;
field.ReadOnly = fieldProperties.IsReadOnly;
field.DataType = fieldProperties.Type;
return field;
}
/// <internalonly/>
/// <devdoc>
/// <para>Creates the control hierarchy that is used to render the Smart.
/// This is called whenever a control hierarchy is needed and the
/// ChildControlsCreated property is false.
/// The implementation assumes that all the children in the controls
/// collection have already been cleared.</para>
/// </devdoc>
protected override int CreateChildControls(IEnumerable dataSource, bool dataBinding) {
PagedDataSource pagedDataSource = null;
if (dataBinding) {
bool allowPaging = AllowPaging;
DataSourceView view = GetData();
DataSourceSelectArguments arguments = SelectArguments;
if (view == null) {
throw new HttpException(SR.GetString(SR.DataBoundControl_NullView, ID));
}
bool useServerPaging = allowPaging && view.CanPage;
if (allowPaging && !view.CanPage) {
if (dataSource != null && !(dataSource is ICollection)) {
arguments.StartRowIndex = checked(PageSize * PageIndex);
arguments.MaximumRows = PageSize;
// This should throw an exception saying the data source can't page.
// We do this because the data source can provide a better error message than we can.
view.Select(arguments, SelectCallback);
}
}
if (useServerPaging) {
if (view.CanRetrieveTotalRowCount) {
pagedDataSource = CreateServerPagedDataSource(arguments.TotalRowCount);
}
else {
ICollection dataSourceCollection = dataSource as ICollection;
if (dataSourceCollection == null) {
throw new HttpException(SR.GetString(SR.DataBoundControl_NeedICollectionOrTotalRowCount, GetType().Name));
}
int priorPagesRecordCount = checked(PageIndex * PageSize);
pagedDataSource = CreateServerPagedDataSource(checked(priorPagesRecordCount + dataSourceCollection.Count));
}
}
else {
pagedDataSource = CreatePagedDataSource();
}
}
else {
pagedDataSource = CreatePagedDataSource();
}
IEnumerator pagedDataSourceEnumerator = null;
int count = 0;
ArrayList keyArray = DataKeysArrayList;
ArrayList suffixArray = ClientIDRowSuffixArrayList;
ICollection fields = null;
int itemCount = -1; // number of items in the collection. We need to know to decide if we need a null row.
int rowsArrayCapacity = 0;
ICollection collection = dataSource as ICollection;
if (dataBinding) {
keyArray.Clear();
suffixArray.Clear();
if (dataSource != null) {
// If we got to here, it's because the data source view said it could page, but then returned
// something that wasn't an ICollection. Probably a data source control author error.
if ((collection == null) && (pagedDataSource.IsPagingEnabled && !pagedDataSource.IsServerPagingEnabled)) {
throw new HttpException(SR.GetString(SR.GridView_Missing_VirtualItemCount, ID));
}
}
}
else {
if (collection == null) {
throw new HttpException(SR.GetString(SR.DataControls_DataSourceMustBeCollectionWhenNotDataBinding));
}
}
_pageCount = 0;
if (dataSource != null) {
pagedDataSource.DataSource = dataSource;
if (pagedDataSource.IsPagingEnabled && dataBinding) {
// Fix up the page index if we have gone past the page count
int pagedDataSourcePageCount = pagedDataSource.PageCount;
Debug.Assert(pagedDataSource.CurrentPageIndex >= 0);
if (pagedDataSource.CurrentPageIndex >= pagedDataSourcePageCount) {
int lastPageIndex = pagedDataSourcePageCount - 1;
pagedDataSource.CurrentPageIndex = _pageIndex = lastPageIndex;
}
}
fields = CreateColumns(dataBinding ? pagedDataSource : null, dataBinding);
if (collection != null) {
itemCount = collection.Count;
int pageSize = pagedDataSource.IsPagingEnabled ? pagedDataSource.PageSize : collection.Count;
rowsArrayCapacity = pageSize;
if (dataBinding) {
keyArray.Capacity = pageSize;
suffixArray.Capacity = pageSize;
}
// PagedDataSource has strange nehavior here. If DataSourceCount is 0 but paging is enabled,
// it returns a PageCount of 1, which is inconsistent with DetailsView and FormView.
// We don't want to change PagedDataSource for back compat reasons.
if (pagedDataSource.DataSourceCount == 0) {
_pageCount = 0;
}
else {
_pageCount = pagedDataSource.PageCount;
}
}
}
_rowsArray = new ArrayList(rowsArrayCapacity);
_rowsCollection = null;
_dataKeyArray = null;
_clientIDRowSuffixArray = null;
Table table = CreateChildTable();
Controls.Add(table);
TableRowCollection rows = table.Rows;
//
if (dataSource == null) {
if (EmptyDataTemplate != null || EmptyDataText.Length > 0) {
CreateRow(-1, -1, DataControlRowType.EmptyDataRow, DataControlRowState.Normal, dataBinding, null, new DataControlField[0], rows, null);
}
else {
Controls.Clear();
}
return 0;
}
int fieldCount = 0;
if (fields != null)
fieldCount = fields.Count;
DataControlField[] displayFields = new DataControlField[fieldCount];
if (fieldCount > 0) {
fields.CopyTo(displayFields, 0);
bool requiresDataBinding = false;
for (int c = 0; c < displayFields.Length; c++) {
if (displayFields[c].Initialize(AllowSorting, this)) {
requiresDataBinding = true;
}
if (DetermineRenderClientScript()) {
displayFields[c].ValidateSupportsCallback();
}
}
if (requiresDataBinding) {
RequiresDataBinding = true;
}
}
GridViewRow row;
DataControlRowType rowType;
DataControlRowState rowState;
int index = 0;
int dataSourceIndex = 0;
string[] dataKeyNames = DataKeyNamesInternal;
bool storeKeys = (dataBinding && (dataKeyNames.Length != 0));
bool storeSuffix = (dataBinding && ClientIDRowSuffixInternal.Length != 0);
bool createPager = pagedDataSource.IsPagingEnabled;
int editIndex = EditIndex;
if (itemCount == -1) {
if (_storedDataValid) {
if (_firstDataRow != null) {
itemCount = 1;
}
else {
itemCount = 0;
}
}
else {
// make sure there's at least one item in the source.
IEnumerator e = dataSource.GetEnumerator();
if (e.MoveNext()) {
object sampleItem = e.Current;
StoreEnumerator(e, sampleItem);
itemCount = 1;
}
else {
itemCount = 0;
}
}
}
if (itemCount == 0) {
bool controlsCreated = false;
if (ShowHeader && ShowHeaderWhenEmpty && displayFields.Length > 0) {
_headerRow = CreateRow(-1, -1, DataControlRowType.Header, DataControlRowState.Normal, dataBinding, null, displayFields, rows, null);
controlsCreated = true;
}
if (EmptyDataTemplate != null || EmptyDataText.Length > 0) {
CreateRow(-1, -1, DataControlRowType.EmptyDataRow, DataControlRowState.Normal, dataBinding, null, displayFields, rows, null);
controlsCreated = true;
}
if (!controlsCreated) {
Controls.Clear();
}
_storedDataValid = false;
_firstDataRow = null;
return 0;
}
if (fieldCount > 0) {
if (pagedDataSource.IsPagingEnabled)
dataSourceIndex = pagedDataSource.FirstIndexInPage;
if (createPager && PagerSettings.Visible && _pagerSettings.IsPagerOnTop) {
_topPagerRow = CreateRow(-1, -1, DataControlRowType.Pager, DataControlRowState.Normal, dataBinding, null, displayFields, rows, pagedDataSource);
}
_headerRow = CreateRow(-1, -1, DataControlRowType.Header, DataControlRowState.Normal, dataBinding, null, displayFields, rows, null);
if (!ShowHeader) {
_headerRow.Visible = false;
}
if (storeKeys) {
// Reset the selected index if we have a persisted datakey so we
// can figure out what index to select based on the key
ResetPersistedSelectedIndex();
}
if (_storedDataValid) {
pagedDataSourceEnumerator = _storedData;
if (_firstDataRow != null) {
if (storeKeys) {
OrderedDictionary keyTable = new OrderedDictionary(dataKeyNames.Length);
foreach (string keyName in dataKeyNames) {
object keyValue = DataBinder.GetPropertyValue(_firstDataRow, keyName);
keyTable.Add(keyName, keyValue);
}
if (keyArray.Count == index) {
keyArray.Add(new DataKey(keyTable, dataKeyNames));
}
else {
keyArray[index] = new DataKey(keyTable, dataKeyNames);
}
}
if (storeSuffix) {
OrderedDictionary suffixTable = new OrderedDictionary(ClientIDRowSuffixInternal.Length);
foreach (string suffixName in ClientIDRowSuffixInternal) {
object suffixValue = DataBinder.GetPropertyValue(_firstDataRow, suffixName);
suffixTable.Add(suffixName, suffixValue);
}
if (suffixArray.Count == index) {
suffixArray.Add(new DataKey(suffixTable, ClientIDRowSuffixInternal));
}
else {
suffixArray[index] = new DataKey(suffixTable, ClientIDRowSuffixInternal);
}
}
if (storeKeys && EnablePersistedSelection) {
if (index < keyArray.Count) {
SetPersistedDataKey(index, (DataKey)keyArray[index]);
}
}
rowType = DataControlRowType.DataRow;
rowState = DataControlRowState.Normal;
if (index == editIndex)
rowState |= DataControlRowState.Edit;
if (index == _selectedIndex)
rowState |= DataControlRowState.Selected;
row = CreateRow(0, dataSourceIndex, rowType, rowState, dataBinding, _firstDataRow, displayFields, rows, null);
_rowsArray.Add(row);
count++;
index++;
dataSourceIndex++;
_storedDataValid = false;
_firstDataRow = null;
}
}
else {
pagedDataSourceEnumerator = pagedDataSource.GetEnumerator();
}
rowType = DataControlRowType.DataRow;
while (pagedDataSourceEnumerator.MoveNext()) {
object dataRow = pagedDataSourceEnumerator.Current;
if (storeKeys) {
OrderedDictionary keyTable = new OrderedDictionary(dataKeyNames.Length);
foreach (string keyName in dataKeyNames) {
object keyValue = DataBinder.GetPropertyValue(dataRow, keyName);
keyTable.Add(keyName, keyValue);
}
if (keyArray.Count == index) {
keyArray.Add(new DataKey(keyTable, dataKeyNames));
}
else {
keyArray[index] = new DataKey(keyTable, dataKeyNames);
}
}
if (storeSuffix) {
OrderedDictionary suffixTable = new OrderedDictionary(ClientIDRowSuffixInternal.Length);
foreach (string suffixName in ClientIDRowSuffixInternal) {
object suffixValue = DataBinder.GetPropertyValue(dataRow, suffixName);
suffixTable.Add(suffixName, suffixValue);
}
if (suffixArray.Count == index) {
suffixArray.Add(new DataKey(suffixTable, ClientIDRowSuffixInternal));
}
else {
suffixArray[index] = new DataKey(suffixTable, ClientIDRowSuffixInternal);
}
}
if (storeKeys && EnablePersistedSelection) {
if (index < keyArray.Count) {
SetPersistedDataKey(index, (DataKey)keyArray[index]);
}
}
rowState = DataControlRowState.Normal;
if (index == editIndex)
rowState |= DataControlRowState.Edit;
if (index == _selectedIndex)
rowState |= DataControlRowState.Selected;
if (index % 2 != 0) {
rowState |= DataControlRowState.Alternate;
}
row = CreateRow(index, dataSourceIndex, rowType, rowState, dataBinding, dataRow, displayFields, rows, null);
_rowsArray.Add(row);
count++;
dataSourceIndex++;
index++;
}
if (index == 0) {
CreateRow(-1, -1, DataControlRowType.EmptyDataRow, DataControlRowState.Normal, dataBinding, null, displayFields, rows, null);
}
_footerRow = CreateRow(-1, -1, DataControlRowType.Footer, DataControlRowState.Normal, dataBinding, null, displayFields, rows, null);
if (!ShowFooter) {
_footerRow.Visible = false;
}
if (createPager && PagerSettings.Visible && _pagerSettings.IsPagerOnBottom) {
_bottomPagerRow = CreateRow(-1, -1, DataControlRowType.Pager, DataControlRowState.Normal, dataBinding, null, displayFields, rows, pagedDataSource);
}
}
int createdRowsCount = -1;
if (dataBinding) {
if (pagedDataSourceEnumerator != null) {
if (pagedDataSource.IsPagingEnabled) {
_pageCount = pagedDataSource.PageCount;
if (pagedDataSource.IsCustomPagingEnabled) {
// DevDiv 782891: We didn't well handle GridView paging in the scenario
// in which custom paging was enabled. The root cause was that we mixed up
// createdRowsCount with pagedDataSource.DataSourceCount.
createdRowsCount = count;
}
else {
createdRowsCount = pagedDataSource.DataSourceCount;
}
}
else {
_pageCount = 1;
createdRowsCount = count;
}
}
else {
_pageCount = 0;
}
}
if (PageCount == 1) { // don't show the pager if there's just one row.
if (_topPagerRow != null) {
_topPagerRow.Visible = false;
}
if (_bottomPagerRow != null) {
_bottomPagerRow.Visible = false;
}
}
return createdRowsCount;
}
/// <internalonly/>
/// <devdoc>
/// <para>Creates new child table, which contains all rows and controls.</para>
/// </devdoc>
protected virtual Table CreateChildTable() {
return new ChildTable(String.IsNullOrEmpty(ID) ? null : ClientID);
}
/// <internalonly/>
/// <devdoc>
/// <para>Creates new control style.</para>
/// </devdoc>
protected override Style CreateControlStyle() {
TableStyle controlStyle = new TableStyle();
// initialize defaults that are different from TableStyle
controlStyle.GridLines = GridLines.Both;
controlStyle.CellSpacing = 0;
return controlStyle;
}
/// <devdoc>
/// Creates the set of fields to be used to build up the control
/// hierarchy.
/// When AutoGenerateColumns is true, the fields are created to match the
/// datasource and are appended to the set of fields defined in the Fields
/// collection.
/// </devdoc>
protected virtual ICollection CreateColumns(PagedDataSource dataSource, bool useDataSource) {
ArrayList fieldsArray = new ArrayList();
bool autoGenEditButton = AutoGenerateEditButton;
bool autoGenDeleteButton = AutoGenerateDeleteButton;
bool autoGenSelectButton = AutoGenerateSelectButton;
if (autoGenEditButton || autoGenDeleteButton || autoGenSelectButton) {
CommandField commandField = new CommandField();
commandField.ButtonType = ButtonType.Link;
if (autoGenEditButton) {
commandField.ShowEditButton = true;
}
if (autoGenDeleteButton) {
commandField.ShowDeleteButton = true;
}
if (autoGenSelectButton) {
commandField.ShowSelectButton = true;
}
fieldsArray.Add(commandField);
}
foreach (DataControlField f in Columns) {
fieldsArray.Add(f);
}
if (AutoGenerateColumns == true) {
if (ColumnsGeneratorInternal is GridViewColumnsGenerator) {
((GridViewColumnsGenerator)ColumnsGeneratorInternal).DataItem = dataSource;
((GridViewColumnsGenerator)ColumnsGeneratorInternal).InDataBinding = useDataSource;
}
fieldsArray.AddRange(ColumnsGeneratorInternal.GenerateFields(this));
}
return fieldsArray;
}
protected override DataSourceSelectArguments CreateDataSourceSelectArguments() {
DataSourceSelectArguments arguments = new DataSourceSelectArguments();
DataSourceView view = GetData();
bool useServerPaging = AllowPaging && view.CanPage;
string sortExpression = SortExpressionInternal;
if (SortDirectionInternal == SortDirection.Descending && !String.IsNullOrEmpty(sortExpression)) {
sortExpression += " DESC";
}
arguments.SortExpression = sortExpression;
// decide if we should use server-side paging
if (useServerPaging) {
if (view.CanRetrieveTotalRowCount) {
arguments.RetrieveTotalRowCount = true;
arguments.MaximumRows = PageSize;
}
else {
arguments.MaximumRows = -1;
}
arguments.StartRowIndex = checked(PageSize * PageIndex);
}
return arguments;
}
/// <devdoc>
/// Creates the pager for NextPrev and NextPrev with First and Last styles
/// </devdoc>
private void CreateNextPrevPager(TableRow row, PagedDataSource pagedDataSource, bool addFirstLastPageButtons) {
PagerSettings pagerSettings = PagerSettings;
string prevPageImageUrl = pagerSettings.PreviousPageImageUrl;
string nextPageImageUrl = pagerSettings.NextPageImageUrl;
bool isFirstPage = pagedDataSource.IsFirstPage;
bool isLastPage = pagedDataSource.IsLastPage;
if (addFirstLastPageButtons && !isFirstPage) {
TableCell cell = new TableCell();
row.Cells.Add(cell);
string firstPageImageUrl = pagerSettings.FirstPageImageUrl;
IButtonControl firstButton;
if (firstPageImageUrl.Length > 0) {
firstButton = new DataControlImageButton(this);
((DataControlImageButton)firstButton).ImageUrl = firstPageImageUrl;
((DataControlImageButton)firstButton).AlternateText = HttpUtility.HtmlDecode(pagerSettings.FirstPageText);
((DataControlImageButton)firstButton).EnableCallback(BuildCallbackArgument(0));
}
else {
firstButton = new DataControlPagerLinkButton(this);
((DataControlPagerLinkButton)firstButton).Text = pagerSettings.FirstPageText;
((DataControlPagerLinkButton)firstButton).EnableCallback(BuildCallbackArgument(0));
}
firstButton.CommandName = DataControlCommands.PageCommandName;
firstButton.CommandArgument = DataControlCommands.FirstPageCommandArgument;
cell.Controls.Add((Control)firstButton);
}
if (!isFirstPage) {
TableCell cell = new TableCell();
row.Cells.Add(cell);
IButtonControl prevButton;
if (prevPageImageUrl.Length > 0) {
prevButton = new DataControlImageButton(this);
((DataControlImageButton)prevButton).ImageUrl = prevPageImageUrl;
((DataControlImageButton)prevButton).AlternateText = HttpUtility.HtmlDecode(pagerSettings.PreviousPageText);
((DataControlImageButton)prevButton).EnableCallback(BuildCallbackArgument(PageIndex - 1));
}
else {
prevButton = new DataControlPagerLinkButton(this);
((DataControlPagerLinkButton)prevButton).Text = pagerSettings.PreviousPageText;
((DataControlPagerLinkButton)prevButton).EnableCallback(BuildCallbackArgument(PageIndex - 1));
}
prevButton.CommandName = DataControlCommands.PageCommandName;
prevButton.CommandArgument = DataControlCommands.PreviousPageCommandArgument;
cell.Controls.Add((Control)prevButton);
}
if (!isLastPage) {
TableCell cell = new TableCell();
row.Cells.Add(cell);
IButtonControl nextButton;
if (nextPageImageUrl.Length > 0) {
nextButton = new DataControlImageButton(this);
((DataControlImageButton)nextButton).ImageUrl = nextPageImageUrl;
((DataControlImageButton)nextButton).AlternateText = HttpUtility.HtmlDecode(pagerSettings.NextPageText);
((DataControlImageButton)nextButton).EnableCallback(BuildCallbackArgument(PageIndex + 1));
}
else {
nextButton = new DataControlPagerLinkButton(this);
((DataControlPagerLinkButton)nextButton).Text = pagerSettings.NextPageText;
((DataControlPagerLinkButton)nextButton).EnableCallback(BuildCallbackArgument(PageIndex + 1));
}
nextButton.CommandName = DataControlCommands.PageCommandName;
nextButton.CommandArgument = DataControlCommands.NextPageCommandArgument;
cell.Controls.Add((Control)nextButton);
}
if (addFirstLastPageButtons && !isLastPage) {
TableCell cell = new TableCell();
row.Cells.Add(cell);
string lastPageImageUrl = pagerSettings.LastPageImageUrl;
IButtonControl lastButton;
if (lastPageImageUrl.Length > 0) {
lastButton = new DataControlImageButton(this);
((DataControlImageButton)lastButton).ImageUrl = lastPageImageUrl;
((DataControlImageButton)lastButton).AlternateText = HttpUtility.HtmlDecode(pagerSettings.LastPageText);
((DataControlImageButton)lastButton).EnableCallback(BuildCallbackArgument(pagedDataSource.PageCount - 1));
}
else {
lastButton = new DataControlPagerLinkButton(this);
((DataControlPagerLinkButton)lastButton).Text = pagerSettings.LastPageText;
((DataControlPagerLinkButton)lastButton).EnableCallback(BuildCallbackArgument(pagedDataSource.PageCount - 1));
}
lastButton.CommandName = DataControlCommands.PageCommandName;
lastButton.CommandArgument = DataControlCommands.LastPageCommandArgument;
cell.Controls.Add((Control)lastButton);
}
}
/// <devdoc>
/// Creates the pager for NextPrev and NextPrev with First and Last styles
/// </devdoc>
private void CreateNumericPager(TableRow row, PagedDataSource pagedDataSource, bool addFirstLastPageButtons) {
PagerSettings pagerSettings = PagerSettings;
int pages = pagedDataSource.PageCount;
int currentPage = pagedDataSource.CurrentPageIndex + 1;
int pageSetSize = pagerSettings.PageButtonCount;
int pagesShown = pageSetSize;
int firstDisplayedPage = FirstDisplayedPageIndex + 1; // first page displayed on last postback
// ensure the number of pages we show isn't more than the number of pages that do exist
if (pages < pagesShown)
pagesShown = pages;
// initialize to the first page set, i.e., pages 1 through number of pages shown
int firstPage = 1;
int lastPage = pagesShown;
if (currentPage > lastPage) {
// The current page is not in the first page set, then we need to slide the
// range of pages shown by adjusting firstPage and lastPage
int currentPageSet = pagedDataSource.CurrentPageIndex / pageSetSize;
bool currentPageInLastDisplayRange = currentPage - firstDisplayedPage >= 0 && currentPage - firstDisplayedPage < pageSetSize;
if (firstDisplayedPage > 0 && currentPageInLastDisplayRange) {
firstPage = firstDisplayedPage;
}
else {
firstPage = currentPageSet * pageSetSize + 1;
}
lastPage = firstPage + pageSetSize - 1;
// now bring back lastPage into the range if its exceeded the number of pages
if (lastPage > pages)
lastPage = pages;
// if theres room to show more pages from the previous page set, then adjust
// the first page accordingly
if (lastPage - firstPage + 1 < pageSetSize) {
firstPage = Math.Max(1, lastPage - pageSetSize + 1);
}
FirstDisplayedPageIndex = firstPage - 1;
}
LinkButton button;
if (addFirstLastPageButtons && currentPage != 1 && firstPage != 1) {
TableCell cell = new TableCell();
row.Cells.Add(cell);
string firstPageImageUrl = pagerSettings.FirstPageImageUrl;
IButtonControl firstButton;
if (firstPageImageUrl.Length > 0) {
firstButton = new DataControlImageButton(this);
((DataControlImageButton)firstButton).ImageUrl = firstPageImageUrl;
((DataControlImageButton)firstButton).AlternateText = HttpUtility.HtmlDecode(pagerSettings.FirstPageText);
((DataControlImageButton)firstButton).EnableCallback(BuildCallbackArgument(0));
}
else {
firstButton = new DataControlPagerLinkButton(this);
((DataControlPagerLinkButton)firstButton).Text = pagerSettings.FirstPageText;
((DataControlPagerLinkButton)firstButton).EnableCallback(BuildCallbackArgument(0));
}
firstButton.CommandName = DataControlCommands.PageCommandName;
firstButton.CommandArgument = DataControlCommands.FirstPageCommandArgument;
cell.Controls.Add((Control)firstButton);
}
if (firstPage != 1) {
TableCell cell = new TableCell();
row.Cells.Add(cell);
button = new DataControlPagerLinkButton(this);
button.Text = "...";
button.CommandName = DataControlCommands.PageCommandName;
button.CommandArgument = (firstPage - 1).ToString(NumberFormatInfo.InvariantInfo);
((DataControlPagerLinkButton)button).EnableCallback(BuildCallbackArgument(firstPage - 2));
cell.Controls.Add(button);
}
for (int i = firstPage; i <= lastPage; i++) {
TableCell cell = new TableCell();
row.Cells.Add(cell);
string pageString = (i).ToString(NumberFormatInfo.InvariantInfo);
if (i == currentPage) {
Label label = new Label();
label.Text = pageString;
cell.Controls.Add(label);
}
else {
button = new DataControlPagerLinkButton(this);
button.Text = pageString;
button.CommandName = DataControlCommands.PageCommandName;
button.CommandArgument = pageString;
((DataControlPagerLinkButton)button).EnableCallback(BuildCallbackArgument(i - 1));
cell.Controls.Add(button);
}
}
if (pages > lastPage) {
TableCell cell = new TableCell();
row.Cells.Add(cell);
button = new DataControlPagerLinkButton(this);
button.Text = "...";
button.CommandName = DataControlCommands.PageCommandName;
button.CommandArgument = (lastPage + 1).ToString(NumberFormatInfo.InvariantInfo);
((DataControlPagerLinkButton)button).EnableCallback(BuildCallbackArgument(lastPage));
cell.Controls.Add(button);
}
bool isLastPageShown = lastPage == pages;
if (addFirstLastPageButtons && currentPage != pages && !isLastPageShown) {
TableCell cell = new TableCell();
row.Cells.Add(cell);
string lastPageImageUrl = pagerSettings.LastPageImageUrl;
IButtonControl lastButton;
if (lastPageImageUrl.Length > 0) {
lastButton = new DataControlImageButton(this);
((DataControlImageButton)lastButton).ImageUrl = lastPageImageUrl;
((DataControlImageButton)lastButton).AlternateText = HttpUtility.HtmlDecode(pagerSettings.LastPageText);
((DataControlImageButton)lastButton).EnableCallback(BuildCallbackArgument(pagedDataSource.PageCount - 1));
}
else {
lastButton = new DataControlPagerLinkButton(this);
((DataControlPagerLinkButton)lastButton).Text = pagerSettings.LastPageText;
((DataControlPagerLinkButton)lastButton).EnableCallback(BuildCallbackArgument(pagedDataSource.PageCount - 1));
}
lastButton.CommandName = DataControlCommands.PageCommandName;
lastButton.CommandArgument = DataControlCommands.LastPageCommandArgument;
cell.Controls.Add((Control)lastButton);
}
}
private GridViewRow CreateRow(int rowIndex, int dataSourceIndex, DataControlRowType rowType, DataControlRowState rowState, bool dataBind, object dataItem, DataControlField[] fields, TableRowCollection rows, PagedDataSource pagedDataSource) {
GridViewRow row = CreateRow(rowIndex, dataSourceIndex, rowType, rowState);
GridViewRowEventArgs e = new GridViewRowEventArgs(row);
if (rowType != DataControlRowType.Pager) {
InitializeRow(row, fields);
}
else {
InitializePager(row, fields.Length, pagedDataSource);
}
if (dataBind) {
row.DataItem = dataItem;
}
OnRowCreated(e);
rows.Add(row);
if (dataBind) {
row.DataBind();
OnRowDataBound(e);
row.DataItem = null;
}
return row;
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
protected virtual GridViewRow CreateRow(int rowIndex, int dataSourceIndex, DataControlRowType rowType, DataControlRowState rowState) {
return new GridViewRow(rowIndex, dataSourceIndex, rowType, rowState);
}
private PagedDataSource CreatePagedDataSource() {
PagedDataSource pagedDataSource = new PagedDataSource();
pagedDataSource.CurrentPageIndex = PageIndex;
pagedDataSource.PageSize = PageSize;
pagedDataSource.AllowPaging = AllowPaging;
pagedDataSource.AllowCustomPaging = AllowCustomPaging;
pagedDataSource.AllowServerPaging = false;
pagedDataSource.VirtualCount = VirtualItemCount;
return pagedDataSource;
}
private PagedDataSource CreateServerPagedDataSource(int totalRowCount) {
PagedDataSource pagedDataSource = new PagedDataSource();
pagedDataSource.CurrentPageIndex = PageIndex;
pagedDataSource.PageSize = PageSize;
pagedDataSource.AllowPaging = AllowPaging;
pagedDataSource.AllowCustomPaging = false;
pagedDataSource.AllowServerPaging = true;
pagedDataSource.VirtualCount = totalRowCount;
return pagedDataSource;
}
/// Data bound controls should override PerformDataBinding instead
/// of DataBind. If DataBind if overridden, the OnDataBinding and OnDataBound events will
/// fire in the wrong order. However, for backwards compat on ListControl and AdRotator, we
/// can't seal this method. It is sealed on all new BaseDataBoundControl-derived controls.
public override sealed void DataBind() {
base.DataBind();
}
public virtual void DeleteRow(int rowIndex) {
// use EnableModelVadliation as the causesValdiation param because the hosting page should not
// be validated unless model validation is going to be used
ResetModelValidationGroup(EnableModelValidation, String.Empty);
HandleDelete(null, rowIndex);
}
private bool DetermineRenderClientScript() {
// In a client script-enabled control, always determine whether to render the
// client script-based functionality.
// The decision should be based on browser capabilities.
if (!_renderClientScriptValid) {
_renderClientScript = false;
if (EnableSortingAndPagingCallbacks && (Context != null) && (Page != null) && (Page.RequestInternal != null) && Page.Request.Browser.SupportsCallback && !IsParentedToUpdatePanel) {
HttpBrowserCapabilities browserCaps = Page.Request.Browser;
bool hasEcmaScript = browserCaps.EcmaScriptVersion.Major > 0;
bool hasDOM = browserCaps.W3CDomVersion.Major > 0;
bool isHtml4 = !StringUtil.EqualsIgnoreCase(browserCaps["tagwriter"], typeof(Html32TextWriter).FullName);
_renderClientScript = hasEcmaScript && hasDOM && isHtml4;
}
_renderClientScriptValid = true;
}
return _renderClientScript;
}
protected virtual void ExtractRowValues(IOrderedDictionary fieldValues, GridViewRow row, bool includeReadOnlyFields, bool includePrimaryKey) {
if (fieldValues == null) {
Debug.Assert(false, "GridView::ExtractRowValues- must hand in a valid reference to an IDictionary.");
return;
}
ICollection fields = CreateColumns(null, false);
int fieldCount = fields.Count;
object[] fieldsArray = new object[fieldCount];
string[] dataKeyNames = DataKeyNamesInternal;
fields.CopyTo(fieldsArray, 0);
// Field and row cell count should match, but if there was no data, or if the user removed some row cells,
// these may no longer match. Make sure we don't exceed the bounds.
for (int i = 0; i < fieldCount && i < row.Cells.Count; i++) {
if (!((DataControlField)fieldsArray[i]).Visible) {
continue;
}
OrderedDictionary newValues = new OrderedDictionary();
((DataControlField)fieldsArray[i]).ExtractValuesFromCell(newValues, row.Cells[i] as DataControlFieldCell, row.RowState, includeReadOnlyFields);
foreach (DictionaryEntry entry in newValues) {
if (includePrimaryKey || (Array.IndexOf(dataKeyNames, entry.Key) == -1)) {
fieldValues[entry.Key] = entry.Value;
}
}
}
}
protected virtual string GetCallbackResult() {
StringWriter stringWriter = new StringWriter(CultureInfo.InvariantCulture);
//
HtmlTextWriter writer = new HtmlTextWriter(stringWriter);
IStateFormatter2 formatter = StateFormatter;
RenderTableContents(writer);
writer.Flush();
writer.Close();
string dataKeysString = formatter.Serialize(SaveDataKeysState(), Purpose.WebForms_GridView_DataKeys);
string sortExpressionString = formatter.Serialize(SortExpression, Purpose.WebForms_GridView_SortExpression);
// this should return the html that goes in the panel, plus the new page and sort info.
return Convert.ToString(PageIndex, CultureInfo.InvariantCulture) + "|" + Convert.ToString((int)SortDirection, CultureInfo.InvariantCulture) + "|" + sortExpressionString + "|" + dataKeysString + "|" + stringWriter.ToString();
}
protected virtual string GetCallbackScript(IButtonControl buttonControl, string argument) {
if (DetermineRenderClientScript()) {
if (String.IsNullOrEmpty(argument)) {
if (buttonControl.CommandName == DataControlCommands.SortCommandName) {
argument = BuildCallbackArgument(buttonControl.CommandArgument, SortDirection);
}
}
if (Page != null) {
Page.ClientScript.RegisterForEventValidation(UniqueID, argument);
}
string clientCallbackReference = "javascript:__gv" + ClientID + ".callback";
return clientCallbackReference + "(" + argument + "); return false;";
}
return null;
}
private int GetRowIndex(GridViewRow row, string commandArgument) {
if (row != null) {
return row.RowIndex;
}
return Convert.ToInt32(commandArgument, CultureInfo.InvariantCulture);
}
private bool TryGetRowIndex(GridViewRow row, string commandArgument, out int rowIndex) {
if (row != null) {
rowIndex = row.RowIndex;
return true;
}
return Int32.TryParse(commandArgument, NumberStyles.Integer, CultureInfo.InvariantCulture, out rowIndex);
}
private void HandleCancel(int rowIndex) {
bool isBoundToDataSourceControl = IsDataBindingAutomatic;
GridViewCancelEditEventArgs e = new GridViewCancelEditEventArgs(rowIndex);
OnRowCancelingEdit(e);
if (e.Cancel) {
return;
}
if (isBoundToDataSourceControl) {
EditIndex = -1;
}
RequiresDataBinding = true;
}
private void HandleDelete(GridViewRow row, int rowIndex) {
DataSourceView view = null;
bool isBoundToDataSourceControl = IsDataBindingAutomatic;
if (isBoundToDataSourceControl) {
view = GetData();
if (view == null) {
throw new HttpException(SR.GetString(SR.GridView_DataSourceReturnedNullView, ID));
}
}
if (row == null && rowIndex < Rows.Count) {
row = Rows[rowIndex];
}
GridViewDeleteEventArgs e = new GridViewDeleteEventArgs(rowIndex);
if (row != null) {
ExtractRowValues(e.Values, row, true/*includeReadOnlyFields*/, false/*includePrimaryKey*/);
}
if (DataKeys.Count > rowIndex) {
foreach (DictionaryEntry entry in DataKeys[rowIndex].Values) {
e.Keys.Add(entry.Key, entry.Value);
if (e.Values.Contains(entry.Key)) {
e.Values.Remove(entry.Key);
}
}
}
OnRowDeleting(e);
if (e.Cancel) {
return;
}
_deletedRowIndex = rowIndex;
if (isBoundToDataSourceControl) {
_deleteKeys = e.Keys;
_deleteValues = e.Values;
view.Delete(e.Keys, e.Values, HandleDeleteCallback);
}
}
private bool HandleDeleteCallback(int affectedRows, Exception ex) {
GridViewDeletedEventArgs sea = new GridViewDeletedEventArgs(affectedRows, ex);
sea.SetKeys(_deleteKeys);
sea.SetValues(_deleteValues);
OnRowDeleted(sea);
_deleteKeys = null;
_deleteValues = null;
if (ex != null && !sea.ExceptionHandled) {
// If there is no validator in the validation group that could make sense
// of the error, return false to proceed with standard exception handling.
// But if there is one, we want to let it display its error instead of throwing.
if (PageIsValidAfterModelException()) {
return false;
}
}
EditIndex = -1;
if (affectedRows > 0) {
// Patch up the current page. We might have deleted the last records on the last page, so move
// to the right page.
// DevDiv 782891: We didn't handle GridView paging well in the scenario
// in which custom paging was enabled. The root cause was that we mixed up
// createdRowsCount with pagedDataSource.DataSourceCount.
int rowCount;
if (this.AllowPaging && this.AllowCustomPaging) {
// Under this condition, the value of ViewState[ItemCountViewStateKey] indicates
// created rows count other than total row count.
rowCount = (int)VirtualItemCount;
}
else {
rowCount = (int)ViewState[ItemCountViewStateKey];
}
// Can't have negative rowCount
int expectedRowCount = Math.Max(0, rowCount - affectedRows);
if (AllowPaging) {
// Calculate the expected page count
int expectedPageCount = 0;
checked {
// Correctly calculate the expectedPageCount. Special case: We want there to always be at least one page even if there are no items
// so that we can always *safely* calculate the pageindex as expectedRowCount - 1
expectedPageCount = Math.Max(1, (expectedRowCount + PageSize - 1) / PageSize);
}
// Adjust the pageIndex based on the expected page count
_pageIndex = Math.Min(_pageIndex, expectedPageCount - 1);
Debug.Assert(_pageIndex >= 0, "Page index should never be negative!");
}
if (SelectedIndex >= 0) {
if (expectedRowCount == 0) {
// There is nothing to select
SelectedIndex = -1;
}
else {
// Calculate the selected index in terms of the row number in the total rows
int selectedRow = AllowPaging ? (PageIndex * PageSize) + SelectedIndex : SelectedIndex;
// If the selected index is no longer valid make it the last index
if (selectedRow > expectedRowCount) {
int lastIndex = AllowPaging ? expectedRowCount % PageSize : expectedRowCount;
SelectedIndex = lastIndex;
}
}
}
}
_deletedRowIndex = -1;
RequiresDataBinding = true;
return true;
}
private void HandleEdit(int rowIndex) {
GridViewEditEventArgs e = new GridViewEditEventArgs(rowIndex);
OnRowEditing(e);
if (e.Cancel) {
return;
}
EditIndex = e.NewEditIndex;
RequiresDataBinding = true;
}
private bool HandleEvent(EventArgs e, bool causesValidation, string validationGroup) {
bool handled = false;
ResetModelValidationGroup(causesValidation, validationGroup);
GridViewCommandEventArgs dce = e as GridViewCommandEventArgs;
if (dce != null) {
OnRowCommand(dce);
if (dce.Handled) {
return true;
}
handled = true;
string command = dce.CommandName;
if (StringUtil.EqualsIgnoreCase(command, DataControlCommands.SelectCommandName)) {
HandleSelect(GetRowIndex(dce.Row, (string)dce.CommandArgument));
}
else if (StringUtil.EqualsIgnoreCase(command, DataControlCommands.PageCommandName)) {
string pageNumberArg = (string)dce.CommandArgument;
int newPage = PageIndex;
if (StringUtil.EqualsIgnoreCase(pageNumberArg, DataControlCommands.NextPageCommandArgument)) {
newPage++;
}
else if (StringUtil.EqualsIgnoreCase(pageNumberArg, DataControlCommands.PreviousPageCommandArgument)) {
newPage--;
}
else if (StringUtil.EqualsIgnoreCase(pageNumberArg, DataControlCommands.FirstPageCommandArgument)) {
newPage = 0;
}
else if (StringUtil.EqualsIgnoreCase(pageNumberArg, DataControlCommands.LastPageCommandArgument)) {
newPage = PageCount - 1;
}
else {
// argument is page number, and page index is 1 less than that
newPage = Convert.ToInt32(pageNumberArg, CultureInfo.InvariantCulture) - 1;
}
HandlePage(newPage);
}
else if (StringUtil.EqualsIgnoreCase(command, DataControlCommands.SortCommandName)) {
HandleSort((string)dce.CommandArgument);
}
else if (StringUtil.EqualsIgnoreCase(command, DataControlCommands.EditCommandName)) {
HandleEdit(GetRowIndex(dce.Row, (string)dce.CommandArgument));
}
else if (StringUtil.EqualsIgnoreCase(command, DataControlCommands.UpdateCommandName)) {
HandleUpdate(dce.Row, GetRowIndex(dce.Row, (string)dce.CommandArgument), causesValidation);
}
else if (StringUtil.EqualsIgnoreCase(command, DataControlCommands.CancelCommandName)) {
HandleCancel(GetRowIndex(dce.Row, (string)dce.CommandArgument));
}
else if (StringUtil.EqualsIgnoreCase(command, DataControlCommands.DeleteCommandName)) {
HandleDelete(dce.Row, GetRowIndex(dce.Row, (string)dce.CommandArgument));
}
else {
int rowIndex;
if (TryGetRowIndex(dce.Row, (String)dce.CommandArgument, out rowIndex)) {
handled = HandleCommand(dce.Row, rowIndex, command);
}
}
}
return handled;
}
private bool HandleCommand(GridViewRow row, int rowIndex, string commandName) {
DataSourceView view = null;
if (IsDataBindingAutomatic) {
view = GetData();
if (view == null) {
throw new HttpException(SR.GetString(SR.GridView_DataSourceReturnedNullView, ID));
}
}
else {
return false;
}
if (row == null && rowIndex < Rows.Count) {
row = Rows[rowIndex];
}
if (!view.CanExecute(commandName)) {
return false;
}
OrderedDictionary values = new OrderedDictionary();
OrderedDictionary keys = new OrderedDictionary();
if (row != null) {
ExtractRowValues(values, row, true/*includeReadOnlyFields*/, false/*includePrimaryKey*/);
}
if (DataKeys.Count > rowIndex) {
foreach (DictionaryEntry entry in DataKeys[rowIndex].Values) {
keys.Add(entry.Key, entry.Value);
if (values.Contains(entry.Key)) {
values.Remove(entry.Key);
}
}
}
view.ExecuteCommand(commandName, keys, values, HandleCommandCallback);
return true;
}
private bool HandleCommandCallback(int affectedRows, Exception ex) {
if (ex != null) {
// If there is no validator in the validation group that could make sense
// of the error, return false to proceed with standard exception handling.
// But if there is one, we want to let it display its error instead of throwing.
if (PageIsValidAfterModelException()) {
return false;
}
}
EditIndex = -1;
RequiresDataBinding = true;
return true;
}
private void HandlePage(int newPage) {
if (!AllowPaging) {
return;
}
GridViewPageEventArgs e = new GridViewPageEventArgs(newPage);
OnPageIndexChanging(e);
if (e.Cancel) {
return;
}
if (IsDataBindingAutomatic) {
if (e.NewPageIndex > -1) {
// if the requested page is out of range and we're already on the last page, don't rebind
if ((e.NewPageIndex >= PageCount && _pageIndex == PageCount - 1)) {
return;
}
// DevDiv Bugs 188830: Don't clear data keys if page is out of range, since control won't be rebound.
ClearDataKeys();
EditIndex = -1;
_pageIndex = e.NewPageIndex;
}
else {
return;
}
}
OnPageIndexChanged(EventArgs.Empty);
RequiresDataBinding = true;
}
private void HandleSelect(int rowIndex) {
GridViewSelectEventArgs e = new GridViewSelectEventArgs(rowIndex);
OnSelectedIndexChanging(e);
if (e.Cancel) {
return;
}
SelectedIndex = e.NewSelectedIndex;
OnSelectedIndexChanged(EventArgs.Empty);
}
private void HandleSort(string sortExpression) {
if (!AllowSorting) {
return;
}
SortDirection futureSortDirection = SortDirection.Ascending;
if ((SortExpressionInternal == sortExpression) && (SortDirectionInternal == SortDirection.Ascending)) {
// switch direction
futureSortDirection = SortDirection.Descending;
}
HandleSort(sortExpression, futureSortDirection);
}
private void HandleSort(string sortExpression, SortDirection sortDirection) {
bool isBoundToDataSourceControl = IsDataBindingAutomatic;
GridViewSortEventArgs e = new GridViewSortEventArgs(sortExpression, sortDirection);
OnSorting(e);
if (e.Cancel) {
return;
}
if (isBoundToDataSourceControl) {
ClearDataKeys();
DataSourceView view = GetData();
if (view == null) {
throw new HttpException(SR.GetString(SR.GridView_DataSourceReturnedNullView, ID));
}
EditIndex = -1;
SortExpressionInternal = e.SortExpression;
SortDirectionInternal = e.SortDirection;
_pageIndex = 0;
}
OnSorted(EventArgs.Empty);
RequiresDataBinding = true;
}
private void HandleUpdate(GridViewRow row, int rowIndex, bool causesValidation) {
if (causesValidation && Page != null && !Page.IsValid) {
return;
}
DataSourceView view = null;
bool isBoundToDataSourceControl = IsDataBindingAutomatic;
if (isBoundToDataSourceControl) {
view = GetData();
if (view == null) {
throw new HttpException(SR.GetString(SR.GridView_DataSourceReturnedNullView, ID));
}
}
GridViewUpdateEventArgs e = new GridViewUpdateEventArgs(rowIndex);
foreach (DictionaryEntry entry in BoundFieldValues) {
e.OldValues.Add(entry.Key, entry.Value);
}
if (DataKeys.Count > rowIndex) {
foreach (DictionaryEntry entry in DataKeys[rowIndex].Values) {
e.Keys.Add(entry.Key, entry.Value);
}
}
if (row == null && Rows.Count > rowIndex) {
row = Rows[rowIndex];
}
if (row != null) {
ExtractRowValues(e.NewValues, row, false/*includeReadOnlyFields*/, true/*includePrimaryKey*/);
}
OnRowUpdating(e);
if (e.Cancel) {
return;
}
if (isBoundToDataSourceControl) {
_updateKeys = e.Keys;
_updateOldValues = e.OldValues;
_updateNewValues = e.NewValues;
view.Update(e.Keys, e.NewValues, e.OldValues, HandleUpdateCallback);
}
}
private bool HandleUpdateCallback(int affectedRows, Exception ex) {
GridViewUpdatedEventArgs sea = new GridViewUpdatedEventArgs(affectedRows, ex);
sea.SetKeys(_updateKeys);
sea.SetOldValues(_updateOldValues);
sea.SetNewValues(_updateNewValues);
OnRowUpdated(sea);
_updateKeys = null;
_updateOldValues = null;
_updateNewValues = null;
if (ex != null && !sea.ExceptionHandled) {
// If there is no validator in the validation group that could make sense
// of the error, return false to proceed with standard exception handling.
// But if there is one, we want to let it display its error instead of throwing.
if (PageIsValidAfterModelException()) {
return false;
}
sea.KeepInEditMode = true;
}
if (IsUsingModelBinders && !Page.ModelState.IsValid) {
sea.KeepInEditMode = true;
}
// we need to databind here event if no records were affected because
// changing the EditIndex required a rebind. The event args give the programmer
// the chance to cancel the bind so the edits aren't lost.
if (!sea.KeepInEditMode) {
EditIndex = -1;
RequiresDataBinding = true;
}
return true;
}
/// <devdoc>
/// <para>
/// Creates a GridViewRow that contains the paging UI.
/// The paging UI is a navigation bar that is a built into a single TableCell that
/// spans across all fields of the GridView.
/// </para>
/// </devdoc>
protected virtual void InitializePager(GridViewRow row, int columnSpan, PagedDataSource pagedDataSource) {
TableCell cell = new TableCell();
if (columnSpan > 1) {
cell.ColumnSpan = columnSpan;
}
PagerSettings pagerSettings = PagerSettings;
if (_pagerTemplate != null) {
InitializeTemplateRow(row, columnSpan);
}
else {
PagerTable pagerTable = new PagerTable();
TableRow pagerTableRow = new TableRow();
switch (pagerSettings.Mode) {
case PagerButtons.NextPrevious:
CreateNextPrevPager(pagerTableRow, pagedDataSource, false);
break;
case PagerButtons.Numeric:
CreateNumericPager(pagerTableRow, pagedDataSource, false);
break;
case PagerButtons.NextPreviousFirstLast:
CreateNextPrevPager(pagerTableRow, pagedDataSource, true);
break;
case PagerButtons.NumericFirstLast:
CreateNumericPager(pagerTableRow, pagedDataSource, true);
break;
}
cell.Controls.Add(pagerTable);
pagerTable.Rows.Add(pagerTableRow);
row.Cells.Add(cell);
}
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
protected virtual void InitializeRow(GridViewRow row, DataControlField[] fields) {
DataControlRowType rowType = row.RowType;
DataControlRowState rowState = row.RowState;
int rowIndex = row.RowIndex;
bool useAccessibleHeader = false;
if (rowType == DataControlRowType.EmptyDataRow) {
InitializeTemplateRow(row, fields.Length);
}
else {
TableCellCollection cells = row.Cells;
string rowHeaderColumn = RowHeaderColumn;
if (rowType == DataControlRowType.Header) {
useAccessibleHeader = UseAccessibleHeader;
}
for (int i = 0; i < fields.Length; i++) {
DataControlFieldCell cell;
if ((rowType == DataControlRowType.Header) && useAccessibleHeader) {
cell = new DataControlFieldHeaderCell(fields[i]);
((DataControlFieldHeaderCell)cell).Scope = TableHeaderScope.Column;
((DataControlFieldHeaderCell)cell).AbbreviatedText = fields[i].AccessibleHeaderText;
}
else {
BoundField boundField = fields[i] as BoundField;
if (rowHeaderColumn.Length > 0 && boundField != null && boundField.DataField == rowHeaderColumn) {
cell = new DataControlFieldHeaderCell(fields[i]);
((DataControlFieldHeaderCell)cell).Scope = TableHeaderScope.Row;
}
else {
cell = new DataControlFieldCell(fields[i]);
}
}
DataControlCellType cellType;
switch (rowType) {
case DataControlRowType.Header:
cellType = DataControlCellType.Header;
break;
case DataControlRowType.Footer:
cellType = DataControlCellType.Footer;
break;
default:
cellType = DataControlCellType.DataCell;
break;
}
fields[i].InitializeCell(cell, cellType, rowState, rowIndex);
cells.Add(cell);
}
}
}
private void InitializeTemplateRow(GridViewRow row, int columnSpan) {
TableCell contentCell = null;
ITemplate contentTemplate = null;
switch (row.RowType) {
case DataControlRowType.EmptyDataRow:
if (_emptyDataTemplate != null) {
contentCell = new TableCell();
contentTemplate = _emptyDataTemplate;
}
else {
contentCell = new TableCell();
string emptyDataText = EmptyDataText;
if (emptyDataText.Length > 0) {
contentCell.Text = emptyDataText;
}
}
break;
case DataControlRowType.Pager:
if (_pagerTemplate != null) {
contentCell = new TableCell();
contentTemplate = _pagerTemplate;
}
break;
}
if (contentCell != null) {
if (columnSpan > 1) {
contentCell.ColumnSpan = columnSpan;
}
if (contentTemplate != null) {
contentTemplate.InstantiateIn(contentCell);
}
row.Cells.Add(contentCell);
}
}
/// <devdoc>
/// <para>Loads the control state for those properties that should persist across postbacks
/// even when EnableViewState=false.</para>
/// </devdoc>
protected internal override void LoadControlState(object savedState) {
// Any properties that could have been set in the persistance need to be
// restored to their defaults if they're not in ControlState, or they will
// be restored to their persisted state instead of their empty state.
_editIndex = -1;
_pageIndex = 0;
_selectedIndex = -1;
_sortExpression = String.Empty;
_sortDirection = SortDirection.Ascending;
_dataKeyNames = new string[0];
_pageCount = -1;
object[] state = savedState as object[];
if (state != null) {
base.LoadControlState(state[0]);
if (state[1] != null) {
_editIndex = (int)state[1];
}
if (state[2] != null) {
_pageIndex = (int)state[2];
}
if (state[3] != null) {
_selectedIndex = (int)state[3];
}
if (state[4] != null) {
_sortExpression = (string)state[4];
}
if (state[5] != null) {
_sortDirection = (SortDirection)state[5];
}
if (state[6] != null) {
_dataKeyNames = (string[])state[6];
}
if (state[7] != null) {
LoadDataKeysState(state[7]);
}
if (state[8] != null) {
_pageCount = (int)state[8];
}
if (state[9] != null) {
if ((_dataKeyNames != null) && (_dataKeyNames.Length > 0)) {
_persistedDataKey = new DataKey(new OrderedDictionary(_dataKeyNames.Length), _dataKeyNames);
((IStateManager)_persistedDataKey).LoadViewState(state[9]);
}
}
if (state[10] != null) {
_clientIDRowSuffix = (string[])state[10];
}
if (state[11] != null) {
LoadClientIDRowSuffixDataKeysState(state[11]);
}
}
else {
base.LoadControlState(null);
}
}
private void LoadDataKeysState(object state) {
if (state != null) {
object[] dataKeysState = (object[])state;
string[] dataKeyNames = DataKeyNamesInternal;
int dataKeyNamesLength = dataKeyNames.Length;
ClearDataKeys();
for (int i = 0; i < dataKeysState.Length; i++) {
DataKeysArrayList.Add(new DataKey(new OrderedDictionary(dataKeyNamesLength), dataKeyNames));
((IStateManager)DataKeysArrayList[i]).LoadViewState(dataKeysState[i]);
}
}
}
private void LoadClientIDRowSuffixDataKeysState(object state) {
if (state != null) {
object[] ClientIDRowSuffixDataKeysState = (object[])state;
string[] ClientIDRowSuffix = ClientIDRowSuffixInternal;
int ClientIDRowSuffixLength = ClientIDRowSuffix.Length;
_clientIDRowSuffixArrayList = null;
for (int i = 0; i < ClientIDRowSuffixDataKeysState.Length; i++) {
ClientIDRowSuffixArrayList.Add(new DataKey(new OrderedDictionary(ClientIDRowSuffixLength), ClientIDRowSuffix));
((IStateManager)ClientIDRowSuffixArrayList[i]).LoadViewState(ClientIDRowSuffixDataKeysState[i]);
}
}
}
private bool LoadHiddenFieldState(string pageIndex, string sortDirection, string sortExpressionSerialized, string dataKeysSerialized) {
bool propertiesChanged = false;
int oldPageIndex = Int32.Parse(pageIndex, CultureInfo.InvariantCulture);
SortDirection oldSortDirection = ((SortDirection)Int32.Parse(sortDirection, CultureInfo.InvariantCulture));
string oldSortExpression = String.Empty;
object dataKeys = null;
if (!String.IsNullOrEmpty(sortExpressionSerialized) || !String.IsNullOrEmpty(dataKeysSerialized)) {
if (Page == null) {
throw new InvalidOperationException();
}
if (!String.IsNullOrEmpty(sortExpressionSerialized)) {
oldSortExpression = (string)StateFormatter.Deserialize(sortExpressionSerialized, Purpose.WebForms_GridView_SortExpression);
}
if (!String.IsNullOrEmpty(dataKeysSerialized)) {
dataKeys = StateFormatter.Deserialize(dataKeysSerialized, Purpose.WebForms_GridView_DataKeys);
}
}
if (_pageIndex != oldPageIndex || _sortDirection != oldSortDirection || _sortExpression != oldSortExpression) {
propertiesChanged = true;
_pageIndex = oldPageIndex;
_sortExpression = oldSortExpression;
_sortDirection = oldSortDirection;
if (dataKeys != null) {
if (_dataKeysArrayList != null) {
_dataKeysArrayList.Clear();
}
LoadDataKeysState(dataKeys);
}
}
return propertiesChanged;
}
/// <internalonly/>
/// <devdoc>
/// <para>Loads a saved state of the <see cref='System.Web.UI.WebControls.GridView'/>.</para>
/// </devdoc>
protected override void LoadViewState(object savedState) {
if (savedState != null) {
object[] myState = (object[])savedState;
base.LoadViewState(myState[0]);
if (myState[1] != null)
((IStateManager)Columns).LoadViewState(myState[1]);
if (myState[2] != null)
((IStateManager)PagerStyle).LoadViewState(myState[2]);
if (myState[3] != null)
((IStateManager)HeaderStyle).LoadViewState(myState[3]);
if (myState[4] != null)
((IStateManager)FooterStyle).LoadViewState(myState[4]);
if (myState[5] != null)
((IStateManager)RowStyle).LoadViewState(myState[5]);
if (myState[6] != null)
((IStateManager)AlternatingRowStyle).LoadViewState(myState[6]);
if (myState[7] != null)
((IStateManager)SelectedRowStyle).LoadViewState(myState[7]);
if (myState[8] != null)
((IStateManager)EditRowStyle).LoadViewState(myState[8]);
if (myState[9] != null)
((IStateManager)PagerSettings).LoadViewState(myState[9]);
if (myState[10] != null)
OrderedDictionaryStateHelper.LoadViewState((OrderedDictionary)BoundFieldValues, (ArrayList)myState[10]);
if (myState[11] != null)
((IStateManager)ControlStyle).LoadViewState(myState[11]);
if (myState[12] != null) {
Debug.Assert(ColumnsGeneratorInternal is IStateManager);
((IStateManager)ColumnsGeneratorInternal).LoadViewState(myState[12]);
}
if (myState[13] != null)
((IStateManager)SortedAscendingCellStyle).LoadViewState(myState[13]);
if (myState[14] != null)
((IStateManager)SortedDescendingCellStyle).LoadViewState(myState[14]);
if (myState[15] != null)
((IStateManager)SortedAscendingHeaderStyle).LoadViewState(myState[15]);
if (myState[16] != null)
((IStateManager)SortedDescendingHeaderStyle).LoadViewState(myState[16]);
}
else {
base.LoadViewState(null);
}
}
/// <internalonly/>
/// <devdoc>
/// </devdoc>
protected override bool OnBubbleEvent(object source, EventArgs e) {
bool causesValidation = false;
string validationGroup = String.Empty;
GridViewCommandEventArgs gvcea = e as GridViewCommandEventArgs;
if (gvcea != null) {
IButtonControl button = gvcea.CommandSource as IButtonControl;
if (button != null) {
causesValidation = button.CausesValidation;
validationGroup = button.ValidationGroup;
}
}
return HandleEvent(e, causesValidation, validationGroup);
}
/// <devdoc>
/// This method is called when DataMember, DataSource, or DataSourceID is changed.
/// </devdoc>
protected override void OnDataPropertyChanged() {
_storedDataValid = false;
base.OnDataPropertyChanged();
}
protected override void OnDataSourceViewChanged(object sender, EventArgs e) {
ClearDataKeys();
base.OnDataSourceViewChanged(sender, e);
}
private void OnFieldsChanged(object sender, EventArgs e) {
if (Initialized) {
RequiresDataBinding = true;
}
}
/// <devdoc>
/// GridView initialization.
/// </devdoc>
protected internal override void OnInit(EventArgs e) {
base.OnInit(e);
if (Page != null) {
if (DataKeyNames.Length > 0 && !AutoGenerateColumns) {
Page.RegisterRequiresViewStateEncryption();
}
Page.RegisterRequiresControlState(this);
}
if (!DesignMode && !String.IsNullOrEmpty(ItemType)) {
DataBoundControlHelper.EnableDynamicData(this, ItemType);
}
}
/// <devdoc>
/// <para>Raises the <see langword='PageIndexChanged'/> event.</para>
/// </devdoc>
protected virtual void OnPageIndexChanged(EventArgs e) {
EventHandler handler = (EventHandler)Events[EventPageIndexChanged];
if (handler != null) {
handler(this, e);
}
}
protected override void OnPagePreLoad(object sender, EventArgs e) {
// Load hidden field state here to overwrite control state properties. LoadViewState and LoadControlState
// may not get called if there's no state in them. We should allow the user to
// set EnablePagingCallbacks in Page_Load, so don't request from DetermineRenderClientScript here.
if (Page != null && !Page.IsCallback && Page.RequestValueCollection != null) {
string hiddenFieldID = "__gv" + ClientID + "__hidden";
string hiddenFieldState = Page.RequestValueCollection[hiddenFieldID];
if (!String.IsNullOrEmpty(hiddenFieldState)) {
if (ParseHiddenFieldState(hiddenFieldState)) {
_editIndex = -1;
RequiresDataBinding = true;
}
}
}
base.OnPagePreLoad(sender, e);
}
private void OnPagerPropertyChanged(object sender, EventArgs e) {
if (Initialized) {
RequiresDataBinding = true;
}
}
/// <devdoc>
/// <para>Raises the <see langword='PageIndexChanging'/> event.</para>
/// </devdoc>
protected virtual void OnPageIndexChanging(GridViewPageEventArgs e) {
bool isBoundToDataSourceControl = IsDataBindingAutomatic;
GridViewPageEventHandler handler = (GridViewPageEventHandler)Events[EventPageIndexChanging];
if (handler != null) {
handler(this, e);
}
else {
if (isBoundToDataSourceControl == false && e.Cancel == false) {
throw new HttpException(SR.GetString(SR.GridView_UnhandledEvent, ID, "PageIndexChanging"));
}
}
}
private const string startupScriptFormat = @"
var {0} = new GridView();
{0}.stateField = document.getElementById('{1}');
{0}.panelElement = document.getElementById('{0}__div');
{0}.pageIndex = {3};
{0}.sortExpression = ""{4}"";
{0}.sortDirection = {5};
{0}.setStateField();
{0}.callback = function(arg) {{
{2};
}};";
/// <devdoc>
/// <para>Sets up the callback scripts if client script is supported on the client</para>
/// </devdoc>
protected internal override void OnPreRender(EventArgs e) {
base.OnPreRender(e);
if (DetermineRenderClientScript() && Page != null) {
string clientReference = "__gv" + ClientID;
ClientScriptManager scriptOM = Page.ClientScript;
scriptOM.RegisterClientScriptResource(typeof(GridView), "GridView.js");
// The return value of GetCallbackEventReference looks like this:
// "__doCallBack(controlname, script fx that returns arg, "GridView_OnCallback, context, errorMethod)"
string doCallBackCall = scriptOM.GetCallbackEventReference(this, clientReference + ".getHiddenFieldContents(arg)", "GridView_OnCallback", clientReference);
// Hidden field used to post content from GridView
// back to the server
string hiddenFieldID = clientReference + "__hidden";
scriptOM.RegisterHiddenField(hiddenFieldID, String.Empty);
IStateFormatter2 formatter = StateFormatter;
string sortExpressionSerialized = formatter.Serialize(SortExpression, Purpose.WebForms_GridView_SortExpression);
string startupScript = String.Format(CultureInfo.InvariantCulture, startupScriptFormat, clientReference, hiddenFieldID, doCallBackCall, PageIndex, sortExpressionSerialized, (int)SortDirection);
scriptOM.RegisterStartupScript(typeof(GridView), clientReference, startupScript, true);
}
}
/// <devdoc>
/// <para>Raises the <see langword='CancelCommand '/>event.</para>
/// </devdoc>
protected virtual void OnRowCancelingEdit(GridViewCancelEditEventArgs e) {
bool isBoundToDataSourceControl = IsDataBindingAutomatic;
GridViewCancelEditEventHandler handler = (GridViewCancelEditEventHandler)Events[EventRowCancelingEdit];
if (handler != null) {
handler(this, e);
}
else {
if (isBoundToDataSourceControl == false && e.Cancel == false) {
throw new HttpException(SR.GetString(SR.GridView_UnhandledEvent, ID, "RowCancelingEdit"));
}
}
}
/// <devdoc>
/// <para>Raises the <see langword='RowCommand'/> event.</para>
/// </devdoc>
protected virtual void OnRowCommand(GridViewCommandEventArgs e) {
GridViewCommandEventHandler handler = (GridViewCommandEventHandler)Events[EventRowCommand];
if (handler != null) {
handler(this, e);
}
}
/// <devdoc>
/// <para>Raises the <see langword='RowCreated'/> event.</para>
/// </devdoc>
protected virtual void OnRowCreated(GridViewRowEventArgs e) {
GridViewRowEventHandler handler = (GridViewRowEventHandler)Events[EventRowCreated];
if (handler != null) handler(this, e);
}
/// <devdoc>
/// <para>Raises the <see langword='RowDataBound'/> event.</para>
/// </devdoc>
protected virtual void OnRowDataBound(GridViewRowEventArgs e) {
GridViewRowEventHandler handler = (GridViewRowEventHandler)Events[EventRowDataBound];
if (handler != null) handler(this, e);
}
/// <devdoc>
/// <para>Raises the <see langword='RowDeleted '/>event.</para>
/// </devdoc>
protected virtual void OnRowDeleted(GridViewDeletedEventArgs e) {
GridViewDeletedEventHandler handler = (GridViewDeletedEventHandler)Events[EventRowDeleted];
if (handler != null) handler(this, e);
}
/// <devdoc>
/// <para>Raises the <see langword='Delete'/> event.</para>
/// </devdoc>
protected virtual void OnRowDeleting(GridViewDeleteEventArgs e) {
bool isBoundToDataSourceControl = IsDataBindingAutomatic;
GridViewDeleteEventHandler handler = (GridViewDeleteEventHandler)Events[EventRowDeleting];
if (handler != null) {
handler(this, e);
}
else {
if (isBoundToDataSourceControl == false && e.Cancel == false) {
throw new HttpException(SR.GetString(SR.GridView_UnhandledEvent, ID, "RowDeleting"));
}
}
}
/// <devdoc>
/// <para>Raises the <see langword='EditCommand'/> event.</para>
/// </devdoc>
protected virtual void OnRowEditing(GridViewEditEventArgs e) {
bool isBoundToDataSourceControl = IsDataBindingAutomatic;
GridViewEditEventHandler handler = (GridViewEditEventHandler)Events[EventRowEditing];
if (handler != null) {
handler(this, e);
}
else {
if (isBoundToDataSourceControl == false && e.Cancel == false) {
throw new HttpException(SR.GetString(SR.GridView_UnhandledEvent, ID, "RowEditing"));
}
}
}
/// <devdoc>
/// <para>Raises the <see langword='RowUpdated '/>event.</para>
/// </devdoc>
protected virtual void OnRowUpdated(GridViewUpdatedEventArgs e) {
GridViewUpdatedEventHandler handler = (GridViewUpdatedEventHandler)Events[EventRowUpdated];
if (handler != null) handler(this, e);
}
/// <devdoc>
/// <para>Raises the <see langword='UpdateCommand'/> event.</para>
/// </devdoc>
protected virtual void OnRowUpdating(GridViewUpdateEventArgs e) {
bool isBoundToDataSourceControl = IsDataBindingAutomatic;
GridViewUpdateEventHandler handler = (GridViewUpdateEventHandler)Events[EventRowUpdating];
if (handler != null) {
handler(this, e);
}
else {
if (isBoundToDataSourceControl == false && e.Cancel == false) {
throw new HttpException(SR.GetString(SR.GridView_UnhandledEvent, ID, "RowUpdating"));
}
}
}
/// <devdoc>
/// <para>Raises the <see cref='System.Web.UI.WebControls.GridView.SelectedIndexChanged'/>event of a <see cref='System.Web.UI.WebControls.GridView'/>.</para>
/// </devdoc>
protected virtual void OnSelectedIndexChanged(EventArgs e) {
EventHandler handler = (EventHandler)Events[EventSelectedIndexChanged];
if (handler != null) {
handler(this, e);
}
}
/// <devdoc>
/// <para>Raises the <see cref='System.Web.UI.WebControls.GridView.SelectedIndexChanging'/>event of a <see cref='System.Web.UI.WebControls.GridView'/>.</para>
/// </devdoc>
protected virtual void OnSelectedIndexChanging(GridViewSelectEventArgs e) {
GridViewSelectEventHandler handler = (GridViewSelectEventHandler)Events[EventSelectedIndexChanging];
if (handler != null) {
handler(this, e);
}
}
/// <devdoc>
/// <para>Raises the <see cref='System.Web.UI.WebControls.GridView.Sorted'/>event of a <see cref='System.Web.UI.WebControls.GridView'/>.</para>
/// </devdoc>
protected virtual void OnSorted(EventArgs e) {
EventHandler handler = (EventHandler)Events[EventSorted];
if (handler != null) {
handler(this, e);
}
}
/// <devdoc>
/// <para>Raises the <see langword='SortCommand'/> event.</para>
/// </devdoc>
protected virtual void OnSorting(GridViewSortEventArgs e) {
bool isBoundToDataSourceControl = IsDataBindingAutomatic;
GridViewSortEventHandler handler = (GridViewSortEventHandler)Events[EventSorting];
if (handler != null) {
handler(this, e);
}
else {
if (isBoundToDataSourceControl == false && e.Cancel == false) {
throw new HttpException(SR.GetString(SR.GridView_UnhandledEvent, ID, "Sorting"));
}
}
}
private bool PageIsValidAfterModelException() {
if (_modelValidationGroup == null) {
return true;
}
Page.Validate(_modelValidationGroup);
return Page.IsValid;
}
/// <devdoc>
/// <para>Parses the information in the hidden field for callbacks and sets members to the values
/// in the hidden field. Returns whether properties changed from what was retrieved from controlstate.</para>
/// </devdoc>
private bool ParseHiddenFieldState(string state) {
string[] arguments = state.Split(new char[] { '|' });
if (arguments.Length == 4) {
return LoadHiddenFieldState(arguments[0], arguments[1], arguments[2], arguments[3]);
}
return false;
}
protected internal override void PerformDataBinding(IEnumerable data) {
base.PerformDataBinding(data);
int editIndex = EditIndex;
if (IsDataBindingAutomatic && editIndex != -1 && editIndex < Rows.Count && IsViewStateEnabled) {
BoundFieldValues.Clear();
ExtractRowValues(BoundFieldValues, Rows[editIndex], true/*includeReadOnlyFields*/, false/*includePrimaryKey*/);
}
if (EnablePersistedSelection) {
string[] keyNames = DataKeyNamesInternal;
//we can't have persisted selection without having at least one key name
if ((keyNames == null) || (keyNames.Length == 0)) {
throw new InvalidOperationException(SR.GetString(SR.GridView_PersistedSelectionRequiresDataKeysNames));
}
}
}
private void ApplySortingStyle(TableCell cell, DataControlField field, TableItemStyle ascendingStyle, TableItemStyle descendingStyle) {
if (!String.IsNullOrEmpty(SortExpression) && String.Equals(field.SortExpression, SortExpression, StringComparison.OrdinalIgnoreCase)) {
if (SortDirection == SortDirection.Ascending) {
cell.MergeStyle(ascendingStyle);
}
else {
cell.MergeStyle(descendingStyle);
}
}
}
/// <internalonly/>
/// <devdoc>
/// </devdoc>
protected internal virtual void PrepareControlHierarchy() {
if (Controls.Count == 0)
return;
bool controlStyleCreated = ControlStyleCreated;
Table childTable = (Table)Controls[0];
childTable.CopyBaseAttributes(this);
if (controlStyleCreated && !ControlStyle.IsEmpty) {
childTable.ApplyStyle(ControlStyle);
}
else {
// Since we didn't create a ControlStyle yet, the default
// settings for the default style of the control need to be applied
// to the child table control directly
//
childTable.GridLines = GridLines.Both;
childTable.CellSpacing = 0;
}
childTable.Caption = Caption;
childTable.CaptionAlign = CaptionAlign;
TableRowCollection rows = childTable.Rows;
// the composite alternating row style, so we need to do just one
// merge style on the actual row
Style altRowStyle = null;
if (_alternatingRowStyle != null) {
altRowStyle = new TableItemStyle();
altRowStyle.CopyFrom(_rowStyle);
altRowStyle.CopyFrom(_alternatingRowStyle);
}
else {
altRowStyle = _rowStyle;
}
int visibleColumns = 0;
bool calculateColumns = true;
foreach (GridViewRow row in rows) {
switch (row.RowType) {
case DataControlRowType.Header:
if (ShowHeader && _headerStyle != null) {
row.MergeStyle(_headerStyle);
}
break;
case DataControlRowType.Footer:
if (ShowFooter && _footerStyle != null) {
row.MergeStyle(_footerStyle);
}
break;
case DataControlRowType.Pager:
if (row.Visible && _pagerStyle != null) {
row.MergeStyle(_pagerStyle);
}
break;
case DataControlRowType.DataRow:
if ((row.RowState & DataControlRowState.Edit) != 0) {
// When creating the control hierarchy, we first check if the
// row is in edit mode. So an row may be selected too, and
// so both editRowStyle (more specific) and selectedRowStyle
// are applied.
{
Style s = new TableItemStyle();
if (row.RowIndex % 2 != 0)
s.CopyFrom(altRowStyle);
else
s.CopyFrom(_rowStyle);
if (row.RowIndex == SelectedIndex)
s.CopyFrom(_selectedRowStyle);
s.CopyFrom(_editRowStyle);
row.MergeStyle(s);
}
}
else if ((row.RowState & DataControlRowState.Selected) != 0) {
// When creating the control hierarchy we first check if the
// row is in edit mode, so we know this row cannot be in edit
// mode. The only special characteristic of this row is that
// it is selected.
{
Style s = new TableItemStyle();
if (row.RowIndex % 2 != 0)
s.CopyFrom(altRowStyle);
else
s.CopyFrom(_rowStyle);
s.CopyFrom(_selectedRowStyle);
row.MergeStyle(s);
}
}
else if ((row.RowState & DataControlRowState.Alternate) != 0) {
row.MergeStyle(altRowStyle);
}
else {
row.MergeStyle(_rowStyle);
}
break;
case DataControlRowType.EmptyDataRow:
row.MergeStyle(_emptyDataRowStyle);
break;
}
// Apply the sorting style if the row is not selected or the row is selected and there was no specified SelectedRowStyle
bool applyCellSortingStyles = (row.RowState & DataControlRowState.Selected) == 0 ||
((row.RowState & DataControlRowState.Selected) != 0 && _selectedRowStyle == null);
if ((row.RowType != DataControlRowType.Pager) && (row.RowType != DataControlRowType.EmptyDataRow)) {
foreach (TableCell cell in row.Cells) {
DataControlFieldCell fieldCell = cell as DataControlFieldCell;
if (fieldCell != null) {
DataControlField field = fieldCell.ContainingField;
if (field != null) {
if (field.Visible == false) {
cell.Visible = false;
}
else {
if (row.RowType == DataControlRowType.DataRow && calculateColumns) {
visibleColumns++;
}
Style cellStyle = null;
switch (row.RowType) {
case DataControlRowType.Header:
cellStyle = field.HeaderStyleInternal;
ApplySortingStyle(cell, field, _sortedAscendingHeaderStyle, _sortedDescendingHeaderStyle);
break;
case DataControlRowType.Footer:
cellStyle = field.FooterStyleInternal;
break;
case DataControlRowType.DataRow:
cellStyle = field.ItemStyleInternal;
if (applyCellSortingStyles) {
ApplySortingStyle(cell, field, _sortedAscendingCellStyle, _sortedDescendingCellStyle);
}
break;
default:
cellStyle = field.ItemStyleInternal;
break;
}
if (cellStyle != null) {
cell.MergeStyle(cellStyle);
}
if (row.RowType == DataControlRowType.DataRow) {
foreach (Control control in cell.Controls) {
WebControl webControl = control as WebControl;
Style fieldControlStyle = field.ControlStyleInternal;
if (webControl != null && fieldControlStyle != null && !fieldControlStyle.IsEmpty) {
webControl.ControlStyle.CopyFrom(fieldControlStyle);
}
}
}
}
}
}
}
if (row.RowType == DataControlRowType.DataRow) {
calculateColumns = false;
}
}
}
if (Rows.Count > 0 && visibleColumns != Rows[0].Cells.Count) {
if (_topPagerRow != null && _topPagerRow.Cells.Count > 0) {
_topPagerRow.Cells[0].ColumnSpan = visibleColumns;
}
if (_bottomPagerRow != null && _bottomPagerRow.Cells.Count > 0) {
_bottomPagerRow.Cells[0].ColumnSpan = visibleColumns;
}
}
}
protected virtual void RaiseCallbackEvent(string eventArgument) {
string[] arguments = eventArgument.Split(new char[] { '|' });
Debug.Assert((arguments != null && (arguments.Length == 8)), "An unexpected number of params came through on " + eventArgument);
IStateFormatter2 formatter = StateFormatter;
ValidateEvent(UniqueID, "\"" + arguments[0] + "|" + arguments[1] + "|" + arguments[2] + "|" + arguments[3] + "\"");
LoadHiddenFieldState(arguments[4], arguments[5], arguments[6], arguments[7]);
int pageNumber = Int32.Parse(arguments[0], CultureInfo.InvariantCulture);
string sortExpressionSerialized = arguments[2];
int sortDirection = Int32.Parse(arguments[1], CultureInfo.InvariantCulture);
if (pageNumber == PageIndex) {
// just the sortDirection or sortExpression changed
SortDirection newSortDirection = SortDirection.Ascending;
string sortExpression = (string)formatter.Deserialize(sortExpressionSerialized, Purpose.WebForms_GridView_SortExpression);
if ((sortExpression == SortExpressionInternal) && (SortDirectionInternal == SortDirection.Ascending)) {
newSortDirection = SortDirection.Descending;
}
SortExpressionInternal = sortExpression;
SortDirectionInternal = newSortDirection;
_pageIndex = 0;
}
else {
EditIndex = -1;
_pageIndex = pageNumber;
}
DataBind();
}
protected virtual void RaisePostBackEvent(string eventArgument) {
ValidateEvent(UniqueID, eventArgument);
int separatorIndex = eventArgument.IndexOf('$');
if (separatorIndex < 0) {
return;
}
CommandEventArgs cea = new CommandEventArgs(eventArgument.Substring(0, separatorIndex), eventArgument.Substring(separatorIndex + 1));
GridViewCommandEventArgs gvcea = new GridViewCommandEventArgs(null, this, cea);
HandleEvent(gvcea, false, String.Empty);
}
/// <internalonly/>
/// <devdoc>
/// <para>Displays the control on the client.</para>
/// </devdoc>
protected internal override void Render(HtmlTextWriter writer) {
// we don't render the outer div at design time because the designer surface
// needs a top-level layout element
Render(writer, !DesignMode);
}
private void Render(HtmlTextWriter writer, bool renderPanel) {
if (Page != null) {
Page.VerifyRenderingInServerForm(this);
}
PrepareControlHierarchy();
if (renderPanel) {
string clientID = ClientID;
if (DetermineRenderClientScript()) {
if (clientID == null) {
throw new HttpException(SR.GetString(SR.GridView_MustBeParented));
}
else {
StringBuilder clientPanelNameBuilder = new StringBuilder("__gv", clientID.Length + 9);
clientPanelNameBuilder.Append(clientID);
clientPanelNameBuilder.Append("__div");
writer.AddAttribute(HtmlTextWriterAttribute.Id, clientPanelNameBuilder.ToString(), true);
}
}
writer.RenderBeginTag(HtmlTextWriterTag.Div);
}
RenderContents(writer);
if (renderPanel) {
writer.RenderEndTag();
}
}
private void RenderTableContents(HtmlTextWriter writer) {
Render(writer, false);
}
private void ResetModelValidationGroup(bool causesValidation, string validationGroup) {
_modelValidationGroup = null;
if (causesValidation) {
Page.Validate(validationGroup);
if (EnableModelValidation) {
_modelValidationGroup = validationGroup;
}
}
}
/// <devdoc>
/// <para>Saves the control state for those properties that should persist across postbacks
/// even when EnableViewState=false.</para>
/// </devdoc>
protected internal override object SaveControlState() {
object baseState = base.SaveControlState();
if (baseState != null ||
_pageIndex != 0 ||
_editIndex != -1 ||
_selectedIndex != -1 ||
(_sortExpression != null && _sortExpression.Length != 0) ||
_sortDirection != SortDirection.Ascending ||
(_dataKeyNames != null && _dataKeyNames.Length != 0) ||
(_dataKeysArrayList != null && _dataKeysArrayList.Count > 0) ||
_pageCount != -1) {
object[] state = new object[12];
state[0] = baseState;
state[1] = (_editIndex == -1) ? null : (object)_editIndex;
state[2] = (_pageIndex == 0) ? null : (object)_pageIndex;
state[3] = (_selectedIndex == -1) ? null : (object)_selectedIndex;
state[4] = (_sortExpression == null || _sortExpression.Length == 0) ? null : (object)_sortExpression;
state[5] = (_sortDirection == SortDirection.Ascending) ? null : (object)((int)_sortDirection);
state[6] = (_dataKeyNames == null || _dataKeyNames.Length == 0) ? null : (object)_dataKeyNames;
state[7] = SaveDataKeysState();
state[8] = _pageCount;
state[9] = (_persistedDataKey == null) ? null : ((IStateManager)_persistedDataKey).SaveViewState();
state[10] = (_clientIDRowSuffix == null || _clientIDRowSuffix.Length == 0) ? null : (object)_clientIDRowSuffix;
state[11] = SaveClientIDRowSuffixDataKeysState();
return state;
}
return true; // return a dummy that ensures LoadControlState gets called but minimizes persisted size.
}
private object SaveDataKeysState() {
object keyState = new object();
int dataKeyCount = 0;
if (_dataKeysArrayList != null && _dataKeysArrayList.Count > 0) {
dataKeyCount = _dataKeysArrayList.Count;
keyState = new object[dataKeyCount];
for (int i = 0; i < dataKeyCount; i++) {
((object[])keyState)[i] = ((IStateManager)_dataKeysArrayList[i]).SaveViewState();
}
}
return (_dataKeysArrayList == null || dataKeyCount == 0) ? null : keyState;
}
private object SaveClientIDRowSuffixDataKeysState() {
object keyState = new object();
int dataKeyCount = 0;
if (_clientIDRowSuffixArrayList != null && _clientIDRowSuffixArrayList.Count > 0) {
dataKeyCount = _clientIDRowSuffixArrayList.Count;
keyState = new object[dataKeyCount];
for (int i = 0; i < dataKeyCount; i++) {
((object[])keyState)[i] = ((IStateManager)_clientIDRowSuffixArrayList[i]).SaveViewState();
}
}
return (_clientIDRowSuffixArrayList == null || dataKeyCount == 0) ? null : keyState;
}
/// <internalonly/>
/// <devdoc>
/// <para>Saves the current state of the <see cref='System.Web.UI.WebControls.GridView'/>.</para>
/// </devdoc>
protected override object SaveViewState() {
object baseState = base.SaveViewState();
object fieldState = (_fieldCollection != null) ? ((IStateManager)_fieldCollection).SaveViewState() : null;
object pagerStyleState = (_pagerStyle != null) ? ((IStateManager)_pagerStyle).SaveViewState() : null;
object headerStyleState = (_headerStyle != null) ? ((IStateManager)_headerStyle).SaveViewState() : null;
object footerStyleState = (_footerStyle != null) ? ((IStateManager)_footerStyle).SaveViewState() : null;
object rowStyleState = (_rowStyle != null) ? ((IStateManager)_rowStyle).SaveViewState() : null;
object alternatingRowStyleState = (_alternatingRowStyle != null) ? ((IStateManager)_alternatingRowStyle).SaveViewState() : null;
object selectedRowStyleState = (_selectedRowStyle != null) ? ((IStateManager)_selectedRowStyle).SaveViewState() : null;
object editRowStyleState = (_editRowStyle != null) ? ((IStateManager)_editRowStyle).SaveViewState() : null;
object boundFieldValuesState = (_boundFieldValues != null) ? OrderedDictionaryStateHelper.SaveViewState(_boundFieldValues) : null;
object pagerSettingsState = (_pagerSettings != null) ? ((IStateManager)_pagerSettings).SaveViewState() : null;
object controlState = ControlStyleCreated ? ((IStateManager)ControlStyle).SaveViewState() : null;
object sortedAscendingCellStyleState = (_sortedAscendingCellStyle != null) ? ((IStateManager)_sortedAscendingCellStyle).SaveViewState() : null;
object sortedDescendingCellStyleState = (_sortedDescendingCellStyle != null) ? ((IStateManager)_sortedDescendingCellStyle).SaveViewState() : null;
object sortedAscendingHeaderStyleState = (_sortedAscendingHeaderStyle != null) ? ((IStateManager)_sortedAscendingHeaderStyle).SaveViewState() : null;
object sortedDescendingHeaderStyleState = (_sortedDescendingHeaderStyle != null) ? ((IStateManager)_sortedDescendingHeaderStyle).SaveViewState() : null;
object[] myState = new object[17];
myState[0] = baseState;
myState[1] = fieldState;
myState[2] = pagerStyleState;
myState[3] = headerStyleState;
myState[4] = footerStyleState;
myState[5] = rowStyleState;
myState[6] = alternatingRowStyleState;
myState[7] = selectedRowStyleState;
myState[8] = editRowStyleState;
myState[9] = pagerSettingsState;
myState[10] = boundFieldValuesState;
myState[11] = controlState;
myState[12] = ColumnsGeneratorInternal is IStateManager ? ((IStateManager)ColumnsGeneratorInternal).SaveViewState() : null;
myState[13] = sortedAscendingCellStyleState;
myState[14] = sortedDescendingCellStyleState;
myState[15] = sortedAscendingHeaderStyleState;
myState[16] = sortedDescendingHeaderStyleState;
// note that we always have some state, atleast the RowCount
return myState;
}
private void ResetPersistedSelectedIndex() {
// If there is already a persisted DataKey then we should reset
// the selected index so that we pick a selected index base on
// a row that matches the DataKey if any
if (EnablePersistedSelection && (_persistedDataKey != null)) {
_selectedIndex = -1;
}
}
private void SetPersistedDataKey(int dataItemIndex, DataKey currentKey) {
if (_persistedDataKey == null) {
// If there is no persisted DataKey then set it to the DataKey at the
// the selected index
if (_selectedIndex == dataItemIndex) {
_persistedDataKey = currentKey;
}
}
else if (_persistedDataKey.Equals(currentKey)) {
// Persist the selection by picking the selected index where DataKeys match.
_selectedIndex = dataItemIndex;
}
}
[SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate",
Justification = "A property already exists. This method does additional work.")]
public void SetPageIndex(int rowIndex) {
HandlePage(rowIndex);
}
[SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate",
Justification = "A property already exists. This method does additional work.")]
public void SelectRow(int rowIndex) {
HandleSelect(rowIndex);
}
[SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate",
Justification = "A property already exists. This method does additional work.")]
public void SetEditRow(int rowIndex) {
HandleEdit(rowIndex);
}
private void SelectCallback(IEnumerable data) {
// The data source should have thrown. If we're here, it didn't. We'll throw for it
// with a generic message.
throw new HttpException(SR.GetString(SR.DataBoundControl_DataSourceDoesntSupportPaging, DataSourceID));
}
public virtual void Sort(string sortExpression, SortDirection sortDirection) {
HandleSort(sortExpression, sortDirection);
}
/// <internalonly/>
/// <devdoc>
/// <para>Marks the starting point to begin tracking and saving changes to the
/// control as part of the control viewstate.</para>
/// </devdoc>
protected override void TrackViewState() {
base.TrackViewState();
if (_fieldCollection != null)
((IStateManager)_fieldCollection).TrackViewState();
if (_pagerStyle != null)
((IStateManager)_pagerStyle).TrackViewState();
if (_headerStyle != null)
((IStateManager)_headerStyle).TrackViewState();
if (_footerStyle != null)
((IStateManager)_footerStyle).TrackViewState();
if (_rowStyle != null)
((IStateManager)_rowStyle).TrackViewState();
if (_sortedAscendingCellStyle != null)
((IStateManager)_sortedAscendingCellStyle).TrackViewState();
if (_sortedDescendingCellStyle != null)
((IStateManager)_sortedDescendingCellStyle).TrackViewState();
if (_sortedAscendingHeaderStyle != null)
((IStateManager)_sortedAscendingHeaderStyle).TrackViewState();
if (_sortedDescendingHeaderStyle != null)
((IStateManager)_sortedDescendingHeaderStyle).TrackViewState();
if (_alternatingRowStyle != null)
((IStateManager)_alternatingRowStyle).TrackViewState();
if (_selectedRowStyle != null)
((IStateManager)_selectedRowStyle).TrackViewState();
if (_editRowStyle != null)
((IStateManager)_editRowStyle).TrackViewState();
if (_pagerSettings != null)
((IStateManager)_pagerSettings).TrackViewState();
if (ControlStyleCreated)
((IStateManager)ControlStyle).TrackViewState();
if (_dataKeyArray != null)
((IStateManager)_dataKeyArray).TrackViewState();
}
internal override void UpdateModelDataSourceProperties(ModelDataSource modelDataSource) {
Debug.Assert(modelDataSource != null, "A non-null ModelDataSource should be passed in");
string dataKeyName = DataKeyNamesInternal.Length > 0 ? DataKeyNamesInternal[0] : "";
modelDataSource.UpdateProperties(ItemType, SelectMethod, UpdateMethod, InsertMethod, DeleteMethod, dataKeyName);
}
public virtual void UpdateRow(int rowIndex, bool causesValidation) {
ResetModelValidationGroup(causesValidation, String.Empty);
HandleUpdate(null, rowIndex, causesValidation);
}
#region IPostBackEventHandler implementation
/// <devdoc>
/// Called when a post back event is being raised. GridView uses this to handle creating CommandEventArgs out of our
/// shortened commandargument notation. This prevents us from having to rebuild the control tree just to handle an
/// event.
/// </devdoc>
void IPostBackEventHandler.RaisePostBackEvent(string eventArgument) {
RaisePostBackEvent(eventArgument);
}
#endregion
#region IPostBackContainer implementation
/// <internalonly/>
PostBackOptions IPostBackContainer.GetPostBackOptions(IButtonControl buttonControl) {
if (buttonControl == null) {
throw new ArgumentNullException("buttonControl");
}
if (buttonControl.CausesValidation) {
throw new InvalidOperationException(SR.GetString(SR.CannotUseParentPostBackWhenValidating, this.GetType().Name, ID));
}
PostBackOptions options = new PostBackOptions(this, buttonControl.CommandName + "$" + buttonControl.CommandArgument);
options.RequiresJavaScriptProtocol = true;
return options;
}
#endregion
#region ICallbackContainer implementation
string ICallbackContainer.GetCallbackScript(IButtonControl buttonControl, string argument) {
return GetCallbackScript(buttonControl, argument);
}
#endregion
#region ICallbackEventHandler implementation
void ICallbackEventHandler.RaiseCallbackEvent(string eventArgument) {
RaiseCallbackEvent(eventArgument);
}
// The return value of this function is the argument to the callback handler in
// GetCallbackEventReference.
string ICallbackEventHandler.GetCallbackResult() {
return GetCallbackResult();
}
#endregion
#region IPersistedSelector implementation
[SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes",
Justification = "SelectedPersistedDataKey provides the functionality.")]
DataKey IPersistedSelector.DataKey {
get {
return SelectedPersistedDataKey;
}
set {
SelectedPersistedDataKey = value;
}
}
#endregion
#region IDataKeysControl implementation
DataKeyArray IDataKeysControl.ClientIDRowSuffixDataKeys {
get {
return ClientIDRowSuffixDataKeys;
}
}
#endregion
#region IDataBoundListControl implementation
DataKeyArray IDataBoundListControl.DataKeys {
get {
return DataKeys;
}
}
DataKey IDataBoundListControl.SelectedDataKey {
get {
return SelectedDataKey;
}
}
int IDataBoundListControl.SelectedIndex {
get {
return SelectedIndex;
}
set {
SelectedIndex = value;
}
}
string[] IDataBoundListControl.ClientIDRowSuffix {
get {
return ClientIDRowSuffix;
}
set {
ClientIDRowSuffix = value;
}
}
bool IDataBoundListControl.EnablePersistedSelection {
get {
return EnablePersistedSelection;
}
set {
EnablePersistedSelection = value;
}
}
[SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Justification = "The property is accessible through the DataBoundControl")]
string IDataBoundControl.DataSourceID {
get {
return DataSourceID;
}
set {
DataSourceID = value;
}
}
[SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Justification = "The property is accessible through the DataBoundControl")]
IDataSource IDataBoundControl.DataSourceObject {
get {
return DataSourceObject;
}
}
[SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Justification = "The property is accessible through the DataBoundControl")]
object IDataBoundControl.DataSource {
get {
return DataSource;
}
set {
DataSource = value;
}
}
string[] IDataBoundControl.DataKeyNames {
get {
return DataKeyNames;
}
set {
DataKeyNames = value;
}
}
[SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Justification = "The property is accessible through the DataBoundControl")]
string IDataBoundControl.DataMember {
get {
return DataMember;
}
set {
DataMember = value;
}
}
#endregion
#region IFieldControl implementation
[SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes",
Justification = "The underlying implementation is not meant to be overridden.")]
IAutoFieldGenerator IFieldControl.FieldsGenerator {
get {
return ColumnsGenerator;
}
set {
ColumnsGenerator = value;
}
}
#endregion
}
}
|