Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / xsp / System / Extensions / UI / WebControls / ListView.cs / 1407647 / ListView.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Collections.Specialized; using System.ComponentModel; using System.Diagnostics.CodeAnalysis; using System.Drawing; using System.Drawing.Design; using System.Globalization; using System.Web; using System.Web.Resources; using System.Web.UI; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; namespace System.Web.UI.WebControls { [DefaultProperty("SelectedValue")] [Designer("System.Web.UI.Design.WebControls.ListViewDesigner, " + AssemblyRef.SystemWebExtensionsDesign)] [ControlValueProperty("SelectedValue")] [DefaultEvent("SelectedIndexChanged")] [SupportsEventValidation] [ToolboxBitmap(typeof(ListView), "ListView.bmp")] [DataKeyProperty("SelectedPersistedDataKey")] public class ListView : DataBoundControl, INamingContainer, IPageableItemContainer, IPersistedSelector, IDataKeysControl, IDataBoundListControl, IWizardSideBarListControl { internal const string ItemCountViewStateKey = "_!ItemCount"; private ITemplate _itemTemplate; private ITemplate _editItemTemplate; private ITemplate _insertItemTemplate; private ITemplate _layoutTemplate; private ITemplate _selectedItemTemplate; private ITemplate _groupTemplate; private ITemplate _itemSeparatorTemplate; private ITemplate _groupSeparatorTemplate; private ITemplate _emptyItemTemplate; private ITemplate _emptyDataTemplate; private ITemplate _alternatingItemTemplate; private static readonly object EventTotalRowCountAvailable = new object(); private static readonly object EventPagePropertiesChanged = new object(); private static readonly object EventPagePropertiesChanging = new object(); private static readonly object EventItemCanceling = new object(); private static readonly object EventItemCommand = new object(); private static readonly object EventItemCreated = new object(); private static readonly object EventItemDataBound = new object(); private static readonly object EventItemDeleted = new object(); private static readonly object EventItemDeleting = new object(); private static readonly object EventItemEditing = new object(); private static readonly object EventItemInserted = new object(); private static readonly object EventItemInserting = new object(); private static readonly object EventItemUpdated = new object(); private static readonly object EventItemUpdating = new object(); private static readonly object EventLayoutCreated = 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 static readonly object EventWizardListItemDataBound = new object(); private bool _performingSelect; private int _editIndex = -1; private int _selectedIndex = -1; private int _groupItemCount = 1; private string _modelValidationGroup; private string _sortExpression = String.Empty; private SortDirection _sortDirection = SortDirection.Ascending; private int _startRowIndex = 0; private int _maximumRows = -1; private int _totalRowCount = -1; private IList_itemList; private ListViewItem _insertItem; private string[] _dataKeyNames; private string[] _clientIDRowSuffix; private DataKeyArray _dataKeyArray; private ArrayList _dataKeysArrayList; private DataKeyArray _clientIDRowSuffixArray; private ArrayList _clientIDRowSuffixArrayList; private OrderedDictionary _boundFieldValues; private DataKey _persistedDataKey; private int _deletedItemIndex; private IOrderedDictionary _deleteKeys; private IOrderedDictionary _deleteValues; private IOrderedDictionary _insertValues; private IOrderedDictionary _updateKeys; private IOrderedDictionary _updateOldValues; private IOrderedDictionary _updateNewValues; private int _autoIDIndex = 0; private const string _automaticIDPrefix = "ctrl"; private bool _instantiatedEmptyDataTemplate = false; // Keep track of where we instantiated templates when we're not using grouping private int _noGroupsOriginalIndexOfItemPlaceholderInContainer = -1; private int _noGroupsItemCreatedCount; private Control _noGroupsItemPlaceholderContainer; // Keep track of where we instantiated templates when we're using grouping private int _groupsOriginalIndexOfGroupPlaceholderInContainer = -1; private int _groupsItemCreatedCount; private Control _groupsGroupPlaceholderContainer; public ListView() { } // Override style properties and throw from setter, and set Browsable(false). // Don't throw from getters because designer calls getters through reflection. [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never) ] public override string AccessKey { get { return base.AccessKey; } set { throw new NotSupportedException(AtlasWeb.ListView_StylePropertiesNotSupported); } } [ Browsable(false), DefaultValue(null), PersistenceMode(PersistenceMode.InnerProperty), TemplateContainer(typeof(ListViewDataItem), BindingDirection.TwoWay), ResourceDescription("ListView_AlternatingItemTemplate") ] public virtual ITemplate AlternatingItemTemplate { get { return _alternatingItemTemplate; } set { _alternatingItemTemplate = value; } } // Override style properties and throw from setter, and set Browsable(false). // Don't throw from getters because designer calls getters through reflection. [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never) ] public override Color BackColor { get { return base.BackColor; } set { throw new NotSupportedException(AtlasWeb.ListView_StylePropertiesNotSupported); } } // Override style properties and throw from setter, and set Browsable(false). // Don't throw from getters because designer calls getters through reflection. [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never) ] public override Color BorderColor { get { return base.BorderColor; } set { throw new NotSupportedException(AtlasWeb.ListView_StylePropertiesNotSupported); } } // Override style properties and throw from setter, and set Browsable(false). // Don't throw from getters because designer calls getters through reflection. [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never) ] public override Unit BorderWidth { get { return base.BorderWidth; } set { throw new NotSupportedException(AtlasWeb.ListView_StylePropertiesNotSupported); } } // Override style properties and throw from setter, and set Browsable(false). // Don't throw from getters because designer calls getters through reflection. [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never) ] public override BorderStyle BorderStyle { get { return base.BorderStyle; } set { throw new NotSupportedException(AtlasWeb.ListView_StylePropertiesNotSupported); } } private IOrderedDictionary BoundFieldValues { get { if (_boundFieldValues == null) { _boundFieldValues = new OrderedDictionary(); } return _boundFieldValues; } } public override ControlCollection Controls { get { EnsureChildControls(); return base.Controls; } } /// /// [ Category("Behavior"), DefaultValue(true), ResourceDescription("ListView_ConvertEmptyStringToNull"), ] public virtual bool ConvertEmptyStringToNull { get { object o = ViewState["ConvertEmptyStringToNull"]; if (o != null) { return (bool)o; } return true; } set { ViewState["ConvertEmptyStringToNull"] = value; } } // Override style properties and throw from setter, and set Browsable(false). // Don't throw from getters because designer calls getters through reflection. [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never), CssClassPropertyAttribute ] public override string CssClass { get { return base.CssClass; } set { throw new NotSupportedException(AtlasWeb.ListView_StylePropertiesNotSupported); } } ///Gets or sets the property that determines whether the control treats empty string as /// null when the item values are extracted. ////// An array of ordered dictionaries that represents each key /// private ArrayList DataKeysArrayList { get { if (_dataKeysArrayList == null) { _dataKeysArrayList = new ArrayList(); } return _dataKeysArrayList; } } private ArrayList ClientIDRowSuffixArrayList { get { if (_clientIDRowSuffixArrayList == null) { _clientIDRowSuffixArrayList = new ArrayList(); } return _clientIDRowSuffixArrayList; } } [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), ResourceDescription("ListView_DataKeys") ] public virtual DataKeyArray DataKeys { get { if (_dataKeyArray == null) { _dataKeyArray = new DataKeyArray(this.DataKeysArrayList); if (IsTrackingViewState) ((IStateManager)_dataKeyArray).TrackViewState(); } return _dataKeyArray; } } [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "ID"), ] 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)), Category("Data"), ResourceDescription("ListView_DataKeyNames"), SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Justification = "Required by ASP.NET parser."), TypeConverterAttribute(typeof(StringArrayConverter)), ] 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(); SetRequiresDataBindingIfInitialized(); } } } // This version doesn't clone the array private string[] DataKeyNamesInternal { get { object o = _dataKeyNames; if (o != null) { return (string[])o; } return new string[0]; } } [ Category("Default"), DefaultValue(-1), ResourceDescription("ListView_EditIndex") ] public virtual int EditIndex { get { return _editIndex; } set { if (value < -1) { throw new ArgumentOutOfRangeException("value"); } if (value != _editIndex) { if (value == -1) { BoundFieldValues.Clear(); } _editIndex = value; SetRequiresDataBindingIfInitialized(); } } } [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), ResourceDescription("ListView_EditItem") ] public virtual ListViewItem EditItem { get { if (_editIndex > -1 && _editIndex < Items.Count) { return Items[_editIndex]; } return null; } } [ Browsable(false), DefaultValue(null), PersistenceMode(PersistenceMode.InnerProperty), TemplateContainer(typeof(ListViewDataItem), BindingDirection.TwoWay), ResourceDescription("ListView_EditItemTemplate"), ] public virtual ITemplate EditItemTemplate { get { return _editItemTemplate; } set { _editItemTemplate = value; } } [ Browsable(false), DefaultValue(null), PersistenceMode(PersistenceMode.InnerProperty), TemplateContainer(typeof(ListView)), ResourceDescription("ListView_EmptyDataTemplate"), ] public virtual ITemplate EmptyDataTemplate { get { return _emptyDataTemplate; } set { _emptyDataTemplate = value; } } [ Browsable(false), DefaultValue(null), PersistenceMode(PersistenceMode.InnerProperty), TemplateContainer(typeof(ListViewItem)), ResourceDescription("ListView_EmptyItemTemplate"), ] public virtual ITemplate EmptyItemTemplate { get { return _emptyItemTemplate; } set { _emptyItemTemplate = value; } } [ WebCategory("Behavior"), DefaultValue(true), ResourceDescription("ListView_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), ResourceDescription("ListView_EnablePersistedSelection") ] public virtual bool EnablePersistedSelection { get { object o = ViewState["EnablePersistedSelection"]; if (o != null) { return (bool)o; } return false; } set { ViewState["EnablePersistedSelection"] = value; } } // Override style properties and throw from setter, and set Browsable(false). // Don't throw from getters because designer calls getters through reflection. [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never) ] public override FontInfo Font { get { return base.Font; } } // Override style properties and throw from setter, and set Browsable(false). // Don't throw from getters because designer calls getters through reflection. [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never) ] public override Color ForeColor { get { return base.ForeColor; } set { throw new NotSupportedException(AtlasWeb.ListView_StylePropertiesNotSupported); } } [ DefaultValue("groupPlaceholder"), Category("Behavior"), ResourceDescription("ListView_GroupPlaceholderID"), SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "ID") ] public virtual String GroupPlaceholderID { get { object o = ViewState["GroupPlaceholderID"]; if (o != null) { return (String)o; } return "groupPlaceholder"; } set { if (String.IsNullOrEmpty(value)) { throw new ArgumentOutOfRangeException("value", String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_ContainerNameMustNotBeEmpty, "GroupPlaceholderID")); } ViewState["GroupPlaceholderID"] = value; } } [ Category("Default"), DefaultValue(1), ResourceDescription("ListView_GroupItemCount"), ] public virtual int GroupItemCount { get { return _groupItemCount; } set { if (value < 1) { throw new ArgumentOutOfRangeException("value"); } _groupItemCount = value; SetRequiresDataBindingIfInitialized(); } } [ Browsable(false), DefaultValue(null), PersistenceMode(PersistenceMode.InnerProperty), TemplateContainer(typeof(ListViewItem)), ResourceDescription("ListView_GroupSeparatorTemplate"), ] public virtual ITemplate GroupSeparatorTemplate { get { return _groupSeparatorTemplate; } set { _groupSeparatorTemplate = value; } } [ Browsable(false), DefaultValue(null), PersistenceMode(PersistenceMode.InnerProperty), TemplateContainer(typeof(ListViewItem)), ResourceDescription("ListView_GroupTemplate"), ] public virtual ITemplate GroupTemplate { get { return _groupTemplate; } set { _groupTemplate = value; } } // Override style properties and throw from setter, and set Browsable(false). // Don't throw from getters because designer calls getters through reflection. [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never) ] public override Unit Height { get { return base.Height; } set { throw new NotSupportedException(AtlasWeb.ListView_StylePropertiesNotSupported); } } [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), ResourceDescription("ListView_InsertItem") ] public virtual ListViewItem InsertItem { get { return _insertItem; } } [ Category("Default"), DefaultValue(InsertItemPosition.None), ResourceDescription("ListView_InsertItemPosition") ] public virtual InsertItemPosition InsertItemPosition { get { object o = ViewState["InsertItemPosition"]; if (o != null) { return (InsertItemPosition)o; } return InsertItemPosition.None; } set { if (InsertItemPosition != value) { ViewState["InsertItemPosition"] = value; SetRequiresDataBindingIfInitialized(); } } } [ Browsable(false), DefaultValue(null), PersistenceMode(PersistenceMode.InnerProperty), TemplateContainer(typeof(ListViewItem), BindingDirection.TwoWay), ResourceDescription("ListView_InsertItemTemplate"), ] public virtual ITemplate InsertItemTemplate { get { return _insertItemTemplate; } set { _insertItemTemplate = value; } } [ DefaultValue("itemPlaceholder"), Category("Behavior"), ResourceDescription("ListView_ItemPlaceholderID"), SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "ID") ] public virtual String ItemPlaceholderID { get { object o = ViewState["ItemPlaceholderID"]; if (o != null) { return (String)o; } return "itemPlaceholder"; } set { if (String.IsNullOrEmpty(value)) { throw new ArgumentOutOfRangeException("value", String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_ContainerNameMustNotBeEmpty, "ItemPlaceholderID")); } ViewState["ItemPlaceholderID"] = value; } } [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), ResourceDescription("ListView_Items") ] public virtual IListItems { get { if (_itemList == null) { _itemList = new List (); } return _itemList; } } [ Browsable(false), DefaultValue(null), PersistenceMode(PersistenceMode.InnerProperty), TemplateContainer(typeof(ListViewItem)), ResourceDescription("ListView_ItemSeparatorTemplate"), ] public virtual ITemplate ItemSeparatorTemplate { get { return _itemSeparatorTemplate; } set { _itemSeparatorTemplate = value; } } [ Browsable(false), DefaultValue(null), PersistenceMode(PersistenceMode.InnerProperty), TemplateContainer(typeof(ListViewDataItem), BindingDirection.TwoWay), ResourceDescription("ListView_ItemTemplate"), SuppressMessage("Microsoft.Security", "CA2119:SealMethodsThatSatisfyPrivateInterfaces", Justification = "Interface denotes existence of property, not used for security.") ] public virtual ITemplate ItemTemplate { get { return _itemTemplate; } set { _itemTemplate = value; } } [ Browsable(false), DefaultValue(null), PersistenceMode(PersistenceMode.InnerProperty), TemplateContainer(typeof(ListView)), ResourceDescription("ListView_LayoutTemplate"), ] public virtual ITemplate LayoutTemplate { get { return _layoutTemplate; } set { _layoutTemplate = value; } } [ 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]; } } [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) ] public virtual DataKey SelectedDataKey { get { if (DataKeyNamesInternal == null || DataKeyNamesInternal.Length == 0) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_DataKeyNamesMustBeSpecified, ID)); } DataKeyArray keys = DataKeys; int selectedIndex = SelectedIndex; if (keys != null && selectedIndex < keys.Count && selectedIndex > -1) { return keys[selectedIndex]; } return null; } } [ Category("Default"), DefaultValue(-1), ResourceDescription("ListView_SelectedIndex"), SuppressMessage("Microsoft.Security", "CA2119:SealMethodsThatSatisfyPrivateInterfaces", Justification = "Interface denotes existence of property, not used for security.") ] public virtual int SelectedIndex { get { return _selectedIndex; } set { if (value < -1) { throw new ArgumentOutOfRangeException("value"); } if (value != _selectedIndex) { // update the virtual selection to use the new selection _selectedIndex = value; if (EnablePersistedSelection && (DataKeyNamesInternal.Length > 0)) { SelectedPersistedDataKey = SelectedDataKey; } // we're going to rebind here for a new template SetRequiresDataBindingIfInitialized(); } } } [ Browsable(false), DefaultValue(null), PersistenceMode(PersistenceMode.InnerProperty), TemplateContainer(typeof(ListViewDataItem), BindingDirection.TwoWay), ResourceDescription("ListView_SelectedItemTemplate"), ] public virtual ITemplate SelectedItemTemplate { get { return _selectedItemTemplate; } set { _selectedItemTemplate = value; } } [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) ] public object SelectedValue { get { DataKey selectedDataKey = SelectedDataKey; if (selectedDataKey != null) { return SelectedDataKey.Value; } return null; } } [ Browsable(false), DefaultValue(SortDirection.Ascending), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), PersistenceMode(PersistenceMode.InnerProperty), ResourceDescription("ListView_SortDirection"), ResourceCategory("Sorting"), ] public virtual SortDirection SortDirection { get { return SortDirectionInternal; } } /// /// Internal member for setting sort direction /// private SortDirection SortDirectionInternal { get { return _sortDirection; } set { if (value < SortDirection.Ascending || value > SortDirection.Descending) { throw new ArgumentOutOfRangeException("value"); } if (_sortDirection != value) { _sortDirection = value; SetRequiresDataBindingIfInitialized(); } } } ////// Gets a value that specifies the current column being sorted on in the /// [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), ResourceDescription("ListView_SortExpression"), ResourceCategory("Sorting"), ] public virtual string SortExpression { get { return SortExpressionInternal; } } ///. /// /// Internal member for setting sort expression /// private string SortExpressionInternal { get { return _sortExpression; } set { if (_sortExpression != value) { _sortExpression = value; SetRequiresDataBindingIfInitialized(); } } } // Override style properties and throw from setter, and set Browsable(false). // Don't throw from getters because designer calls getters through reflection. [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never) ] public override short TabIndex { get { return base.TabIndex; } set { throw new NotSupportedException(AtlasWeb.ListView_StylePropertiesNotSupported); } } // Override style properties and throw from setter, and set Browsable(false). // Don't throw from getters because designer calls getters through reflection. [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never) ] public override string ToolTip { get { return base.ToolTip; } set { throw new NotSupportedException(AtlasWeb.ListView_StylePropertiesNotSupported); } } [ Browsable(false) ] public virtual DataKey SelectedPersistedDataKey { get { return _persistedDataKey; } set { _persistedDataKey = value; if (IsTrackingViewState && (_persistedDataKey != null)) { ((IStateManager)_persistedDataKey).TrackViewState(); } } } // Override style properties and throw from setter, and set Browsable(false). // Don't throw from getters because designer calls getters through reflection. [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never) ] public override Unit Width { get { return base.Width; } set { throw new NotSupportedException(AtlasWeb.ListView_StylePropertiesNotSupported); } } ////// [ Category("Action"), ResourceDescription("ListView_OnItemDeleted") ] public event EventHandlerOccurs when a control bubbles an event to the ///with a /// . ItemDeleted { add { Events.AddHandler(EventItemDeleted, value); } remove { Events.RemoveHandler(EventItemDeleted, value); } } /// /// [ Category("Action"), ResourceDescription("ListView_OnItemInserted") ] public event EventHandlerOccurs when a control bubbles an event to the ///with a /// . ItemInserted { add { Events.AddHandler(EventItemInserted, value); } remove { Events.RemoveHandler(EventItemInserted, value); } } /// /// [ Category("Action"), ResourceDescription("ListView_OnItemUpdated") ] public event EventHandlerOccurs when a control bubbles an event to the ///with a /// . ItemUpdated { add { Events.AddHandler(EventItemUpdated, value); } remove { Events.RemoveHandler(EventItemUpdated, value); } } /// /// [ Category("Action"), ResourceDescription("ListView_OnItemCanceling") ] public event EventHandlerOccurs when a control bubbles an event to the ///with a /// property of /// . ItemCanceling { add { Events.AddHandler(EventItemCanceling, value); } remove { Events.RemoveHandler(EventItemCanceling, value); } } /// Occurs when a control bubbles an event to the /// [ Category("Action"), ResourceDescription("ListView_OnItemCommand") ] public event EventHandlernot covered by /// , , or /// . ItemCommand { add { Events.AddHandler(EventItemCommand, value); } remove { Events.RemoveHandler(EventItemCommand, value); } } /// /// [ Category("Behavior"), ResourceDescription("ListView_OnItemCreated") ] public event EventHandlerOccurs on the server when a control a created. ///ItemCreated { add { Events.AddHandler(EventItemCreated, value); } remove { Events.RemoveHandler(EventItemCreated, value); } } /// /// [ Category("Data"), ResourceDescription("ListView_OnItemDataBound") ] public event EventHandlerOccurs when an Item is data bound to the control. ///ItemDataBound { add { Events.AddHandler(EventItemDataBound, value); } remove { Events.RemoveHandler(EventItemDataBound, value); } } /// /// [ Category("Action"), ResourceDescription("ListView_OnItemDeleting") ] public event EventHandlerOccurs when a control bubbles an event to the ///with a /// . ItemDeleting { add { Events.AddHandler(EventItemDeleting, value); } remove { Events.RemoveHandler(EventItemDeleting, value); } } /// /// [ Category("Action"), ResourceDescription("ListView_OnItemEditing") ] public event EventHandlerOccurs when a control bubbles an event to the ///with a /// property of /// . ItemEditing { add { Events.AddHandler(EventItemEditing, value); } remove { Events.RemoveHandler(EventItemEditing, value); } } /// /// [ Category("Action"), ResourceDescription("ListView_OnItemInserting") ] public event EventHandlerOccurs when a control bubbles an event to the ///with a /// . ItemInserting { add { Events.AddHandler(EventItemInserting, value); } remove { Events.RemoveHandler(EventItemInserting, value); } } /// /// [ Category("Action"), ResourceDescription("ListView_OnItemUpdating") ] public event EventHandlerOccurs when a control bubbles an event to the ///with a /// . ItemUpdating { add { Events.AddHandler(EventItemUpdating, value); } remove { Events.RemoveHandler(EventItemUpdating, value); } } /// /// [ Category("Behavior"), ResourceDescription("ListView_OnLayoutCreated") ] public event EventHandler LayoutCreated { add { Events.AddHandler(EventLayoutCreated, value); } remove { Events.RemoveHandler(EventLayoutCreated, value); } } ///Occurs on the server when a control layout is created. ////// [ Category("Behavior"), ResourceDescription("ListView_OnPagePropertiesChanged") ] public event EventHandler PagePropertiesChanged { add { Events.AddHandler(EventPagePropertiesChanged, value); } remove { Events.RemoveHandler(EventPagePropertiesChanged, value); } } ///Occurs on the server when the page properties have changed. ////// [ Category("Behavior"), ResourceDescription("ListView_OnPagePropertiesChanging") ] public event EventHandlerOccurs on the server when the page properties are changing. ///PagePropertiesChanging { add { Events.AddHandler(EventPagePropertiesChanging, value); } remove { Events.RemoveHandler(EventPagePropertiesChanging, value); } } /// /// [ Category("Action"), ResourceDescription("ListView_OnSelectedIndexChanged") ] public event EventHandler SelectedIndexChanged { add { Events.AddHandler(EventSelectedIndexChanged, value); } remove { Events.RemoveHandler(EventSelectedIndexChanged, value); } } ///Occurs when an Item on the list is selected. ////// [ Category("Action"), ResourceDescription("ListView_OnSelectedIndexChanging") ] public event EventHandlerOccurs when an Item on the list is selected. ///SelectedIndexChanging { add { Events.AddHandler(EventSelectedIndexChanging, value); } remove { Events.RemoveHandler(EventSelectedIndexChanging, value); } } /// /// [ Category("Action"), ResourceDescription("ListView_OnSorted") ] public event EventHandler Sorted { add { Events.AddHandler(EventSorted, value); } remove { Events.RemoveHandler(EventSorted, value); } } ///Occurs when a field is sorted. ////// [ Category("Action"), ResourceDescription("ListView_OnSorting") ] public event EventHandlerOccurs when a field is sorting. ///Sorting { add { Events.AddHandler(EventSorting, value); } remove { Events.RemoveHandler(EventSorting, value); } } protected virtual void AddControlToContainer(Control control, Control container, int addLocation) { // The ListView packages up everything in the ItemTemplate in a ListViewDataItem or ListViewItem. // The ListViewItem is being added to the control tree. Since ListViewItems can't be children of HtmlTables or // HtmlTableRows, we put them in a derived HtmlTable or HtmlTableRow, which just renders out its children. // Since ListViewItems don't have any rendering, only the child HtmlTableRow or HtmlTableCell will be rendered. if (container is HtmlTable) { ListViewTableRow listViewTableRow = new ListViewTableRow(); container.Controls.AddAt(addLocation, listViewTableRow); listViewTableRow.Controls.Add(control); } else { if (container is HtmlTableRow) { ListViewTableCell listViewTableCell = new ListViewTableCell(); container.Controls.AddAt(addLocation, listViewTableCell); listViewTableCell.Controls.Add(control); } else { container.Controls.AddAt(addLocation, control); } } } private void AutoIDControl(Control control) { // We have to do our own auto-id'ing because we create the LayoutTemplate, add controls // to the item or group container, then clear those controls out when we bind again. // Because the item or group container isn't necessarily a naming container, clearing // out its controls collection doesn't reset the auto-id counter and you get new ids. // On postback, controls that have post data won't be found because their generated // ids won't match the prior ones. By creating our own auto-id'ing, we don't get // Control's auto-id, and we can reset the auto id index when we remove all items from // the item or group container. control.ID = _automaticIDPrefix + _autoIDIndex++.ToString(CultureInfo.InvariantCulture); } private void ClearDataKeys() { _dataKeysArrayList = null; } /// /// Overriden by DataBoundControl to determine if the control should /// recreate its control hierarchy based on values in view state. /// If the control hierarchy should be created, i.e. view state does /// exist, it calls CreateChildControls with a dummy (empty) data source /// which is usable for enumeration purposes only. /// protected internal override void CreateChildControls() { object controlCount = ViewState[ItemCountViewStateKey]; if (controlCount == null && RequiresDataBinding) { EnsureDataBound(); } if (controlCount != null && ((int)controlCount) != -1) { object[] dummyDataSource = new object[(int)controlCount]; CreateChildControls(dummyDataSource, false); ClearChildViewState(); } } ////// Performs the work of creating the control hierarchy based on a data source. /// When dataBinding is true, the specified data source contains real /// data, and the data is supposed to be pushed into the UI. /// When dataBinding is false, the specified data source is a dummy data /// source, that allows enumerating the right number of items, but the items /// themselves are null and do not contain data. In this case, the recreated /// control hierarchy reinitializes its state from view state. /// It enables a DataBoundControl to encapsulate the logic of creating its /// control hierarchy in both modes into a single code path. /// /// /// The data source to be used to enumerate items. /// /// /// Whether the method has been called from DataBind or not. /// ////// The number of items created based on the data source. Put another way, its /// the number of items enumerated from the data source. /// protected virtual int CreateChildControls(IEnumerable dataSource, bool dataBinding) { ListViewPagedDataSource pagedDataSource = null; // Create the LayoutTemplate so the pager control in it can set page properties. // We'll only create the layout template once. EnsureLayoutTemplate(); RemoveItems(); // if we should render the insert item, make a dummy empty datasource and go through // the regular code path. if (dataSource == null && InsertItemPosition != InsertItemPosition.None) { dataSource = new object[0]; } bool usePaging = (_startRowIndex > 0 || _maximumRows > 0); if (dataBinding) { DataSourceView view = GetData(); DataSourceSelectArguments arguments = SelectArguments; if (view == null) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_NullView, ID)); } bool useServerPaging = view.CanPage && usePaging; if (!view.CanPage && useServerPaging) { if (dataSource != null && !(dataSource is ICollection)) { arguments.StartRowIndex = _startRowIndex; arguments.MaximumRows = _maximumRows; // 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) { int totalRowCount; if (view.CanRetrieveTotalRowCount) { totalRowCount = arguments.TotalRowCount; } else { ICollection dataSourceCollection = dataSource as ICollection; if (dataSourceCollection == null) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_NeedICollectionOrTotalRowCount, GetType().Name)); } totalRowCount = checked(_startRowIndex + dataSourceCollection.Count); } pagedDataSource = CreateServerPagedDataSource(totalRowCount); } else { pagedDataSource = CreatePagedDataSource(); } } else { pagedDataSource = CreatePagedDataSource(); } ArrayList keyArray = DataKeysArrayList; ArrayList suffixArray = ClientIDRowSuffixArrayList; _dataKeyArray = null; _clientIDRowSuffixArray = null; ICollection collection = dataSource as ICollection; if (dataBinding) { keyArray.Clear(); suffixArray.Clear(); if ((dataSource != null) && (collection == null) && !pagedDataSource.IsServerPagingEnabled && usePaging) { // 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. throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_Missing_VirtualItemCount, ID)); } } else { if (collection == null) { throw new InvalidOperationException(AtlasWeb.ListView_DataSourceMustBeCollectionWhenNotDataBinding); } } if (dataSource != null) { pagedDataSource.DataSource = dataSource; if (dataBinding && usePaging) { keyArray.Capacity = pagedDataSource.DataSourceCount; suffixArray.Capacity = pagedDataSource.DataSourceCount; } if (_groupTemplate != null) { _itemList = CreateItemsInGroups(pagedDataSource, dataBinding, InsertItemPosition, keyArray); if (dataBinding && ClientIDRowSuffixInternal != null && ClientIDRowSuffixInternal.Length != 0) { CreateSuffixArrayList(pagedDataSource, suffixArray); } } else { if (GroupItemCount != 1) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_GroupItemCountNoGroupTemplate, ID, GroupPlaceholderID)); } _itemList = CreateItemsWithoutGroups(pagedDataSource, dataBinding, InsertItemPosition, keyArray); if(dataBinding && ClientIDRowSuffixInternal != null && ClientIDRowSuffixInternal.Length != 0) { CreateSuffixArrayList(pagedDataSource, suffixArray); } } _totalRowCount = usePaging ? pagedDataSource.DataSourceCount : _itemList.Count; OnTotalRowCountAvailable(new PageEventArgs(_startRowIndex, _maximumRows, _totalRowCount)); if (_itemList.Count == 0) { if (InsertItemPosition == InsertItemPosition.None) { // remove the layout template Controls.Clear(); CreateEmptyDataItem(); } } } else { // remove the layout template Controls.Clear(); CreateEmptyDataItem(); } return _totalRowCount; } // Style properties won't be honored on ListView, so throw if someone tries to set any style properties protected override Style CreateControlStyle() { // The designer reflects on properties at design time. Don't throw then. if (!DesignMode) { throw new NotSupportedException(AtlasWeb.ListView_StyleNotSupported); } return base.CreateControlStyle(); } protected override DataSourceSelectArguments CreateDataSourceSelectArguments() { DataSourceSelectArguments arguments = new DataSourceSelectArguments(); DataSourceView view = GetData(); bool useServerPaging = 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 = _maximumRows; } else { arguments.MaximumRows = -1; } arguments.StartRowIndex = _startRowIndex; } return arguments; } protected virtual void CreateEmptyDataItem() { if (_emptyDataTemplate != null) { _instantiatedEmptyDataTemplate = true; ListViewItem item = CreateItem(ListViewItemType.EmptyItem); AutoIDControl(item); InstantiateEmptyDataTemplate(item); OnItemCreated(new ListViewItemEventArgs(item)); AddControlToContainer(item, this, 0); } } protected virtual ListViewItem CreateEmptyItem() { if (_emptyItemTemplate != null) { ListViewItem emptyItem = CreateItem(ListViewItemType.EmptyItem); AutoIDControl(emptyItem); InstantiateEmptyItemTemplate(emptyItem); OnItemCreated(new ListViewItemEventArgs(emptyItem)); return emptyItem; } return null; } protected virtual ListViewItem CreateInsertItem() { if (InsertItemTemplate == null) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_InsertTemplateRequired, ID)); } ListViewItem item = CreateItem(ListViewItemType.InsertItem); AutoIDControl(item); InstantiateInsertItemTemplate(item); OnItemCreated(new ListViewItemEventArgs(item)); return item; } protected virtual ListViewItem CreateItem(ListViewItemType itemType) { ListViewItem item = new ListViewItem(itemType); if (itemType == ListViewItemType.InsertItem) { _insertItem = item; } return item; } protected virtual ListViewDataItem CreateDataItem(int dataItemIndex, int displayIndex) { return new ListViewDataItem(dataItemIndex, displayIndex); } protected virtual IListCreateItemsWithoutGroups(ListViewPagedDataSource dataSource, bool dataBinding, InsertItemPosition insertPosition, ArrayList keyArray) { // If this is the first time we're creating the control items, we need // to locate the itemPlaceholder container. // If this is a scenario where we are recreating control items, we already // have the cached itemPlaceholder container. if (_noGroupsOriginalIndexOfItemPlaceholderInContainer == -1) { _noGroupsItemPlaceholderContainer = GetPreparedContainerInfo(this, true, out _noGroupsOriginalIndexOfItemPlaceholderInContainer); } // We need to keep track of where we're inserting items and how many items we have // inserted so that if we need to remove them we know what to do. int itemInsertLocation = _noGroupsOriginalIndexOfItemPlaceholderInContainer; List items = new List (); int itemIndex = 0; int dataItemIndex = 0; if (insertPosition == InsertItemPosition.FirstItem) { ListViewItem insertItem = CreateInsertItem(); AddControlToContainer(insertItem, _noGroupsItemPlaceholderContainer, itemInsertLocation); insertItem.DataBind(); itemInsertLocation++; itemIndex++; } // Reset the selected index if we have a persisted datakey so we // can figure out what index to select based on the key ResetPersistedSelectedIndex(); foreach (object o in dataSource) { if (itemIndex != 0 && _itemSeparatorTemplate != null) { ListViewContainer itemSeparatorContainer = new ListViewContainer(); AutoIDControl(itemSeparatorContainer); InstantiateItemSeparatorTemplate(itemSeparatorContainer); AddControlToContainer(itemSeparatorContainer, _noGroupsItemPlaceholderContainer, itemInsertLocation); itemInsertLocation++; } ListViewDataItem item = CreateDataItem(dataItemIndex + dataSource.StartRowIndex, dataItemIndex); AutoIDControl(item); if (dataBinding) { item.DataItem = o; OrderedDictionary keyTable = new OrderedDictionary(DataKeyNamesInternal.Length); foreach (string keyName in DataKeyNamesInternal) { object keyValue = DataBinder.GetPropertyValue(o, keyName); keyTable.Add(keyName, keyValue); } if (keyArray.Count == dataItemIndex) { keyArray.Add(new DataKey(keyTable, DataKeyNamesInternal)); } else { keyArray[dataItemIndex] = new DataKey(keyTable, DataKeyNamesInternal); } } // If persisted selection is enabled and we have a data key then compare it to get the selected index if (EnablePersistedSelection) { if (dataItemIndex < keyArray.Count) { DataKey currentKey = (DataKey)keyArray[dataItemIndex]; SetPersistedDataKey(dataItemIndex, currentKey); } } InstantiateItemTemplate(item, dataItemIndex); OnItemCreated(new ListViewItemEventArgs(item)); AddControlToContainer(item, _noGroupsItemPlaceholderContainer, itemInsertLocation); itemInsertLocation++; items.Add(item); if (dataBinding) { item.DataBind(); OnItemDataBound(new ListViewItemEventArgs(item)); item.DataItem = null; } dataItemIndex++; itemIndex++; } if (insertPosition == InsertItemPosition.LastItem) { if (_itemSeparatorTemplate != null) { ListViewContainer itemSeparatorContainer = new ListViewContainer(); AutoIDControl(itemSeparatorContainer); InstantiateItemSeparatorTemplate(itemSeparatorContainer); AddControlToContainer(itemSeparatorContainer, _noGroupsItemPlaceholderContainer, itemInsertLocation); itemInsertLocation++; } ListViewItem insertItem = CreateInsertItem(); AddControlToContainer(insertItem, _noGroupsItemPlaceholderContainer, itemInsertLocation); insertItem.DataBind(); itemInsertLocation++; itemIndex++; } _noGroupsItemCreatedCount = itemInsertLocation - _noGroupsOriginalIndexOfItemPlaceholderInContainer; return items; } 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; } } protected virtual IList CreateItemsInGroups(ListViewPagedDataSource dataSource, bool dataBinding, InsertItemPosition insertPosition, ArrayList keyArray) { // If this is the first time we're creating the control items, we need // to locate the groupPlaceholder container. // If this is a scenario where we are recreating control items, we already // have the cached groupPlaceholder container. if (_groupsOriginalIndexOfGroupPlaceholderInContainer == -1) { _groupsGroupPlaceholderContainer = GetPreparedContainerInfo(this, false, out _groupsOriginalIndexOfGroupPlaceholderInContainer); } int groupInsertLocation = _groupsOriginalIndexOfGroupPlaceholderInContainer; _groupsItemCreatedCount = 0; int itemInsertLocation = 0; Control itemPlaceholderContainer = null; // Reset the selected index if we have a persisted datakey so we // can figure out what index to select based on the key ResetPersistedSelectedIndex(); List items = new List (); int itemIndex = 0; int dataItemIndex = 0; if (insertPosition == InsertItemPosition.FirstItem) { ListViewContainer groupContainer = new ListViewContainer(); AutoIDControl(groupContainer); InstantiateGroupTemplate(groupContainer); AddControlToContainer(groupContainer, _groupsGroupPlaceholderContainer, groupInsertLocation); groupInsertLocation++; itemPlaceholderContainer = GetPreparedContainerInfo(groupContainer, true, out itemInsertLocation); ListViewItem insertItem = CreateInsertItem(); AddControlToContainer(insertItem, itemPlaceholderContainer, itemInsertLocation); insertItem.DataBind(); itemInsertLocation++; itemIndex++; } foreach (object o in dataSource) { if (itemIndex % _groupItemCount == 0) { if (itemIndex != 0 && _groupSeparatorTemplate != null) { ListViewContainer groupSeparatorContainer = new ListViewContainer(); AutoIDControl(groupSeparatorContainer); InstantiateGroupSeparatorTemplate(groupSeparatorContainer); AddControlToContainer(groupSeparatorContainer, _groupsGroupPlaceholderContainer, groupInsertLocation); groupInsertLocation++; } ListViewContainer groupContainer = new ListViewContainer(); AutoIDControl(groupContainer); InstantiateGroupTemplate(groupContainer); AddControlToContainer(groupContainer, _groupsGroupPlaceholderContainer, groupInsertLocation); groupInsertLocation++; itemPlaceholderContainer = GetPreparedContainerInfo(groupContainer, true, out itemInsertLocation); } ListViewDataItem item = CreateDataItem(dataItemIndex + StartRowIndex, dataItemIndex); if (dataBinding) { item.DataItem = o; OrderedDictionary keyTable = new OrderedDictionary(DataKeyNamesInternal.Length); foreach (string keyName in DataKeyNamesInternal) { object keyValue = DataBinder.GetPropertyValue(o, keyName); keyTable.Add(keyName, keyValue); } if (keyArray.Count == dataItemIndex) { keyArray.Add(new DataKey(keyTable, DataKeyNamesInternal)); } else { keyArray[dataItemIndex] = new DataKey(keyTable, DataKeyNamesInternal); } } // If persisted selection is enabled and we have a data key then compare it to get the selected index if (EnablePersistedSelection) { if (dataItemIndex < keyArray.Count) { DataKey currentKey = (DataKey)keyArray[dataItemIndex]; SetPersistedDataKey(dataItemIndex, currentKey); } } InstantiateItemTemplate(item, dataItemIndex); OnItemCreated(new ListViewItemEventArgs(item)); if (itemIndex % _groupItemCount != 0 && _itemSeparatorTemplate != null) { ListViewContainer itemSeparatorContainer = new ListViewContainer(); InstantiateItemSeparatorTemplate(itemSeparatorContainer); AddControlToContainer(itemSeparatorContainer, itemPlaceholderContainer, itemInsertLocation); itemInsertLocation++; } AddControlToContainer(item, itemPlaceholderContainer, itemInsertLocation); itemInsertLocation++; items.Add(item); if (dataBinding) { item.DataBind(); OnItemDataBound(new ListViewItemEventArgs(item)); item.DataItem = null; } itemIndex++; dataItemIndex++; } if (insertPosition == InsertItemPosition.LastItem) { if (itemIndex % _groupItemCount == 0) { // start a new group if (itemIndex != 0 && _groupSeparatorTemplate != null) { ListViewContainer groupSeparatorContainer = new ListViewContainer(); AutoIDControl(groupSeparatorContainer); InstantiateGroupSeparatorTemplate(groupSeparatorContainer); AddControlToContainer(groupSeparatorContainer, _groupsGroupPlaceholderContainer, groupInsertLocation); groupInsertLocation++; } ListViewContainer groupContainer = new ListViewContainer(); AutoIDControl(groupContainer); InstantiateGroupTemplate(groupContainer); AddControlToContainer(groupContainer, _groupsGroupPlaceholderContainer, groupInsertLocation); groupInsertLocation++; itemPlaceholderContainer = GetPreparedContainerInfo(groupContainer, true, out itemInsertLocation); } // use the existing group if (itemIndex % _groupItemCount != 0 && _itemSeparatorTemplate != null) { ListViewContainer itemSeparatorContainer = new ListViewContainer(); InstantiateItemSeparatorTemplate(itemSeparatorContainer); AddControlToContainer(itemSeparatorContainer, itemPlaceholderContainer, itemInsertLocation); itemInsertLocation++; } ListViewItem insertItem = CreateInsertItem(); AddControlToContainer(insertItem, itemPlaceholderContainer, itemInsertLocation); insertItem.DataBind(); itemInsertLocation++; itemIndex++; } // fill in the rest of the items if there's an emptyItemTemplate if (_emptyItemTemplate != null) { while (itemIndex % _groupItemCount != 0) { if (_itemSeparatorTemplate != null) { ListViewContainer itemSeparatorContainer = new ListViewContainer(); InstantiateItemSeparatorTemplate(itemSeparatorContainer); AddControlToContainer(itemSeparatorContainer, itemPlaceholderContainer, itemInsertLocation); itemInsertLocation++; } ListViewItem emptyItem = CreateEmptyItem(); AddControlToContainer(emptyItem, itemPlaceholderContainer, itemInsertLocation); itemInsertLocation++; itemIndex++; } } _groupsItemCreatedCount = groupInsertLocation - _groupsOriginalIndexOfGroupPlaceholderInContainer; return items; } protected virtual void CreateSuffixArrayList(ListViewPagedDataSource dataSource, ArrayList suffixArray) { int dataItemIndex = 0; foreach (object o in dataSource) { OrderedDictionary suffixTable = new OrderedDictionary(ClientIDRowSuffixInternal.Length); foreach (string suffixName in ClientIDRowSuffixInternal) { object suffixValue = DataBinder.GetPropertyValue(o, suffixName); suffixTable.Add(suffixName, suffixValue); } if (suffixArray.Count == dataItemIndex) { suffixArray.Add(new DataKey(suffixTable, ClientIDRowSuffixInternal)); } else { suffixArray[dataItemIndex] = new DataKey(suffixTable, ClientIDRowSuffixInternal); } dataItemIndex++; } } protected virtual void CreateLayoutTemplate() { // Reset data concerning where things are in the layout template since we're about to recreate it _noGroupsOriginalIndexOfItemPlaceholderInContainer = -1; _noGroupsItemCreatedCount = 0; _noGroupsItemPlaceholderContainer = null; _groupsOriginalIndexOfGroupPlaceholderInContainer = -1; _groupsItemCreatedCount = 0; _groupsGroupPlaceholderContainer = null; Control containerControl = new Control(); if (_layoutTemplate != null) { _layoutTemplate.InstantiateIn(containerControl); Controls.Add(containerControl); } OnLayoutCreated(new EventArgs()); } private ListViewPagedDataSource CreatePagedDataSource() { ListViewPagedDataSource pagedDataSource = new ListViewPagedDataSource(); pagedDataSource.StartRowIndex = _startRowIndex; pagedDataSource.MaximumRows = _maximumRows; pagedDataSource.AllowServerPaging = false; pagedDataSource.TotalRowCount = 0; return pagedDataSource; } private ListViewPagedDataSource CreateServerPagedDataSource(int totalRowCount) { ListViewPagedDataSource pagedDataSource = new ListViewPagedDataSource(); pagedDataSource.StartRowIndex = _startRowIndex; pagedDataSource.MaximumRows = _maximumRows; pagedDataSource.AllowServerPaging = true; pagedDataSource.TotalRowCount = totalRowCount; return pagedDataSource; } public virtual void DeleteItem(int itemIndex) { // 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, itemIndex); } protected virtual void EnsureLayoutTemplate() { if (this.Controls.Count == 0 || _instantiatedEmptyDataTemplate) { Controls.Clear(); CreateLayoutTemplate(); } } public virtual void ExtractItemValues(IOrderedDictionary itemValues, ListViewItem item, bool includePrimaryKey) { if (itemValues == null) { throw new ArgumentNullException("itemValues"); } DataBoundControlHelper.ExtractValuesFromBindableControls(itemValues, item); IBindableTemplate bindableTemplate = null; if (item.ItemType == ListViewItemType.DataItem) { ListViewDataItem dataItem = item as ListViewDataItem; if (dataItem == null) { throw new InvalidOperationException(AtlasWeb.ListView_ItemsNotDataItems); } if (dataItem.DisplayIndex == EditIndex) { bindableTemplate = EditItemTemplate as IBindableTemplate; } else if (dataItem.DisplayIndex == SelectedIndex) { bindableTemplate = SelectedItemTemplate as IBindableTemplate; } else if (dataItem.DisplayIndex % 2 == 1 && AlternatingItemTemplate != null) { bindableTemplate = AlternatingItemTemplate as IBindableTemplate; } else { bindableTemplate = ItemTemplate as IBindableTemplate; } } else if (item.ItemType == ListViewItemType.InsertItem) { if (InsertItemTemplate != null) { bindableTemplate = InsertItemTemplate as IBindableTemplate; } } if (bindableTemplate != null) { OrderedDictionary newValues = new OrderedDictionary(); bool convertEmptyStringToNull = ConvertEmptyStringToNull; foreach (DictionaryEntry entry in bindableTemplate.ExtractValues(item)) { object value = entry.Value; if (convertEmptyStringToNull && value is string && ((string)value).Length == 0) { newValues[entry.Key] = null; } else { newValues[entry.Key] = value; } } foreach (DictionaryEntry entry in newValues) { if (includePrimaryKey || (Array.IndexOf(DataKeyNamesInternal, entry.Key) == -1)) { itemValues[entry.Key] = entry.Value; } } } } [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "ID")] protected virtual Control FindPlaceholder(string containerID, Control container) { return container.FindControl(containerID); } private DataPager FindDataPager(Control control) { foreach (Control c in control.Controls) { DataPager pager = c as DataPager; if (pager != null) { return pager; } } foreach (Control c in control.Controls) { if (c is IPageableItemContainer) { // Exit out if we've ventured into another ListView or pageable container, since that is the likely // target of any embedded pagers. return null; } DataPager pager = FindDataPager(c); if (pager != null) { return pager; } } return null; } private int GetItemIndex(ListViewItem item, string commandArgument) { if (item != null) { ListViewDataItem dataItem = item as ListViewDataItem; if (dataItem != null) { return dataItem.DisplayIndex; } return -1; } return Convert.ToInt32(commandArgument, CultureInfo.InvariantCulture); } private Control GetPreparedContainerInfo(Control outerContainer, bool isItem, out int placeholderIndex) { // This function locates the ItemPlaceholder for a given container and prepares // it for child controls. Strategy: // - Locate ItemPlaceholder // - If it's not found and the user defined a layout template throw // - If it's not found and the user didn't define a layout/group template, add a default placeholder with the placeholder ID // - Store the placeholder's container and the placeholder's location in the container // - Remove the ItemPlaceholder string placeholderID = isItem ? ItemPlaceholderID : GroupPlaceholderID; Control placeholder = FindPlaceholder(placeholderID, outerContainer); if (placeholder == null) { //add a default placeholder if (_layoutTemplate == null) { placeholder = new PlaceHolder(); placeholder.ID = placeholderID; } if (isItem) { //throw if the user defined a layout/group template and didn't specify an item placeholder if ((_layoutTemplate != null) || (_groupTemplate != null)) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_NoItemPlaceholder, ID, ItemPlaceholderID)); } } else { //throw if the user defined a layout template and didn't specify an group placeholder if (_layoutTemplate != null) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_NoGroupPlaceholder, ID, GroupPlaceholderID)); } } Controls.Add(placeholder); } // Save the information about where we found the itemPlaceholder because // in RemoveItems() we need to know where to delete whatever we create. // This only applies to certain usages of this function. Control placeholderContainer = placeholder.Parent; placeholderIndex = placeholderContainer.Controls.IndexOf(placeholder); // Remove the item placeholder since we're going to be // adding real items starting at the index where it used to be. placeholderContainer.Controls.Remove(placeholder); return placeholderContainer; } private void HandleCancel(int itemIndex) { ListViewCancelMode cancelMode = ListViewCancelMode.CancelingInsert; if (itemIndex == EditIndex && itemIndex >= 0) { cancelMode = ListViewCancelMode.CancelingEdit; } else if (itemIndex != -1) { throw new InvalidOperationException(AtlasWeb.ListView_InvalidCancel); } ListViewCancelEventArgs e = new ListViewCancelEventArgs(itemIndex, cancelMode); OnItemCanceling(e); if (e.Cancel) { return; } if (IsBoundUsingDataSourceID) { if (e.CancelMode == ListViewCancelMode.CancelingEdit) { EditIndex = -1; } else { // cancel on an insert is simply "redatabind to clear"? } } RequiresDataBinding = true; } private void HandleDelete(ListViewItem item, int itemIndex) { ListViewDataItem dataItem = item as ListViewDataItem; if (itemIndex < 0 && dataItem == null) { throw new InvalidOperationException(AtlasWeb.ListView_InvalidDelete); } DataSourceView view = null; bool isBoundToDataSourceControl = IsBoundUsingDataSourceID; if (isBoundToDataSourceControl) { view = GetData(); if (view == null) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_NullView, ID)); } } if (item == null && itemIndex < Items.Count) { item = Items[itemIndex]; } ListViewDeleteEventArgs e = new ListViewDeleteEventArgs(itemIndex); if (item != null) { ExtractItemValues(e.Values, item, false/*includePrimaryKey*/); } if (DataKeys.Count > itemIndex) { foreach (DictionaryEntry entry in DataKeys[itemIndex].Values) { e.Keys.Add(entry.Key, entry.Value); if (e.Values.Contains(entry.Key)) { e.Values.Remove(entry.Key); } } } OnItemDeleting(e); if (e.Cancel) { return; } _deletedItemIndex = itemIndex; if (isBoundToDataSourceControl) { _deleteKeys = e.Keys; _deleteValues = e.Values; view.Delete(e.Keys, e.Values, HandleDeleteCallback); } } private bool HandleDeleteCallback(int affectedRows, Exception ex) { ListViewDeletedEventArgs e = new ListViewDeletedEventArgs(affectedRows, ex); e.SetKeys(_deleteKeys); e.SetValues(_deleteValues); OnItemDeleted(e); _deleteKeys = null; _deleteValues = null; if (ex != null && !e.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 selected index if we deleted the last item on the last page. if ((_totalRowCount > 0) && (_deletedItemIndex == SelectedIndex) && (_deletedItemIndex + _startRowIndex == _totalRowCount)) { SelectedIndex--; } } _deletedItemIndex = -1; RequiresDataBinding = true; return true; } private void HandleEdit(int itemIndex) { if (itemIndex < 0) { throw new InvalidOperationException(AtlasWeb.ListView_InvalidEdit); } ListViewEditEventArgs e = new ListViewEditEventArgs(itemIndex); OnItemEditing(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); ListViewCommandEventArgs dce = e as ListViewCommandEventArgs; if (dce != null) { OnItemCommand(dce); handled = true; string command = dce.CommandName; if (String.Equals(command, DataControlCommands.SelectCommandName, StringComparison.OrdinalIgnoreCase)) { HandleSelect(GetItemIndex(dce.Item, (string)dce.CommandArgument)); } else if (String.Equals(command, DataControlCommands.SortCommandName, StringComparison.OrdinalIgnoreCase)) { HandleSort((string)dce.CommandArgument); } else if (String.Equals(command, DataControlCommands.EditCommandName, StringComparison.OrdinalIgnoreCase)) { HandleEdit(GetItemIndex(dce.Item, (string)dce.CommandArgument)); } else if (String.Equals(command, DataControlCommands.CancelCommandName, StringComparison.OrdinalIgnoreCase)) { HandleCancel(GetItemIndex(dce.Item, (string)dce.CommandArgument)); } else if (String.Equals(command, DataControlCommands.UpdateCommandName, StringComparison.OrdinalIgnoreCase)) { HandleUpdate(dce.Item, GetItemIndex(dce.Item, (string)dce.CommandArgument), causesValidation); } else if (String.Equals(command, DataControlCommands.DeleteCommandName, StringComparison.OrdinalIgnoreCase)) { HandleDelete(dce.Item, GetItemIndex(dce.Item, (string)dce.CommandArgument)); } else if (String.Equals(command, DataControlCommands.InsertCommandName, StringComparison.OrdinalIgnoreCase)) { HandleInsert(dce.Item, causesValidation); } else { handled = HandleCommand(dce.Item, GetItemIndex(dce.Item, (string)dce.CommandArgument), command); } } return handled; } private bool HandleCommand(ListViewItem item, int itemIndex, string commandName) { DataSourceView view = null; if (IsBoundUsingDataSourceID) { view = GetData(); if (view == null) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_NullView, ID)); } } else { return false; } if (!view.CanExecute(commandName)) { return false; } ListViewDataItem dataItem = item as ListViewDataItem; if (itemIndex < 0 && dataItem == null) { throw new InvalidOperationException(AtlasWeb.ListView_InvalidCommand); } OrderedDictionary values = new OrderedDictionary(); OrderedDictionary keys = new OrderedDictionary(); if (item != null) { ExtractItemValues(values, item, false /*includePrimaryKey*/); } if (DataKeys.Count > itemIndex) { foreach (DictionaryEntry entry in DataKeys[itemIndex].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 HandleInsert(ListViewItem item, bool causesValidation) { if (item != null && item.ItemType != ListViewItemType.InsertItem) { throw new InvalidOperationException(AtlasWeb.ListView_InvalidInsert); } if (causesValidation && Page != null && !Page.IsValid) { return; } if (item == null) { item = _insertItem; } if (item == null) { throw new InvalidOperationException(AtlasWeb.ListView_NoInsertItem); } DataSourceView view = null; bool isBoundToDataSourceControl = IsBoundUsingDataSourceID; if (isBoundToDataSourceControl) { view = GetData(); if (view == null) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_NullView, ID)); } } ListViewInsertEventArgs e = new ListViewInsertEventArgs(item); ExtractItemValues(e.Values, item, true/*includeKeys*/); OnItemInserting(e); if (e.Cancel) { return; } if (isBoundToDataSourceControl) { _insertValues = e.Values; view.Insert(e.Values, HandleInsertCallback); } } private bool HandleInsertCallback(int affectedRows, Exception ex) { ListViewInsertedEventArgs e = new ListViewInsertedEventArgs(affectedRows, ex); e.SetValues(_insertValues); OnItemInserted(e); _insertValues = null; if (ex != null && !e.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; } e.KeepInInsertMode = true; } if (!e.KeepInInsertMode) { RequiresDataBinding = true; } return true; } private void HandleSelect(int itemIndex) { if (itemIndex < 0) { throw new InvalidOperationException(AtlasWeb.ListView_InvalidSelect); } ListViewSelectEventArgs e = new ListViewSelectEventArgs(itemIndex); OnSelectedIndexChanging(e); if (e.Cancel) { return; } SelectedIndex = e.NewSelectedIndex; OnSelectedIndexChanged(EventArgs.Empty); RequiresDataBinding = true; } private void HandleSort(string sortExpression) { 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) { ListViewSortEventArgs e = new ListViewSortEventArgs(sortExpression, sortDirection); OnSorting(e); if (e.Cancel) { return; } if (IsBoundUsingDataSourceID) { ClearDataKeys(); DataSourceView view = GetData(); if (view == null) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_NullView, ID)); } EditIndex = -1; SortExpressionInternal = e.SortExpression; SortDirectionInternal = e.SortDirection; _startRowIndex = 0; } OnSorted(EventArgs.Empty); RequiresDataBinding = true; } private void HandleUpdate(ListViewItem item, int itemIndex, bool causesValidation) { ListViewDataItem dataItem = item as ListViewDataItem; if (itemIndex < 0 && dataItem == null) { throw new InvalidOperationException(AtlasWeb.ListView_InvalidUpdate); } if (causesValidation && Page != null && !Page.IsValid) { return; } DataSourceView view = null; bool isBoundToDataSourceControl = IsBoundUsingDataSourceID; if (isBoundToDataSourceControl) { view = GetData(); if (view == null) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_NullView, ID)); } } ListViewUpdateEventArgs e = new ListViewUpdateEventArgs(itemIndex); foreach (DictionaryEntry entry in BoundFieldValues) { e.OldValues.Add(entry.Key, entry.Value); } if (DataKeys.Count > itemIndex) { foreach (DictionaryEntry entry in DataKeys[itemIndex].Values) { e.Keys.Add(entry.Key, entry.Value); } } if (dataItem == null && Items.Count > itemIndex) { dataItem = Items[itemIndex]; } if (dataItem != null) { ExtractItemValues(e.NewValues, dataItem, true/*includePrimaryKey*/); } OnItemUpdating(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) { ListViewUpdatedEventArgs e = new ListViewUpdatedEventArgs(affectedRows, ex); e.SetKeys(_updateKeys); e.SetOldValues(_updateOldValues); e.SetNewValues(_updateNewValues); OnItemUpdated(e); _updateKeys = null; _updateOldValues = null; _updateNewValues = null; if (ex != null && !e.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; } e.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 (!e.KeepInEditMode) { EditIndex = -1; RequiresDataBinding = true; } return true; } public virtual void InsertNewItem(bool causesValidation) { ResetModelValidationGroup(causesValidation, String.Empty); HandleInsert(null, causesValidation); } protected virtual void InstantiateEmptyDataTemplate(Control container) { if (_emptyDataTemplate != null) { _emptyDataTemplate.InstantiateIn(container); } } protected virtual void InstantiateEmptyItemTemplate(Control container) { if (_emptyItemTemplate != null) { _emptyItemTemplate.InstantiateIn(container); } } protected virtual void InstantiateGroupTemplate(Control container) { if (_groupTemplate != null) { _groupTemplate.InstantiateIn(container); } } protected virtual void InstantiateGroupSeparatorTemplate(Control container) { if (_groupSeparatorTemplate != null) { _groupSeparatorTemplate.InstantiateIn(container); } } protected virtual void InstantiateInsertItemTemplate(Control container) { if (_insertItemTemplate != null) { _insertItemTemplate.InstantiateIn(container); } } protected virtual void InstantiateItemSeparatorTemplate(Control container) { if (_itemSeparatorTemplate != null) { _itemSeparatorTemplate.InstantiateIn(container); } } protected virtual void InstantiateItemTemplate(Control container, int displayIndex) { ITemplate contentTemplate = _itemTemplate; if (contentTemplate == null) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_ItemTemplateRequired, ID)); } if (displayIndex % 2 == 1 && _alternatingItemTemplate != null) { contentTemplate = _alternatingItemTemplate; } if (displayIndex == _selectedIndex && _selectedItemTemplate != null) { contentTemplate = _selectedItemTemplate; } if (displayIndex == _editIndex && _editItemTemplate != null) { contentTemplate = _editItemTemplate; } contentTemplate.InstantiateIn(container); } 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. _startRowIndex = 0; _maximumRows = -1; _editIndex = -1; _selectedIndex = -1; _groupItemCount = 1; _sortExpression = String.Empty; _sortDirection = SortDirection.Ascending; _dataKeyNames = new string[0]; object[] state = savedState as object[]; if (state != null) { base.LoadControlState(state[0]); if (state[1] != null) { _editIndex = (int)state[1]; } if (state[2] != null) { _selectedIndex = (int)state[2]; } if (state[3] != null) { _groupItemCount = (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) { _totalRowCount = (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]); } if (state[12] != null) { _startRowIndex = (int)state[12]; } if (state[13] != null) { _maximumRows = (int)state[13]; } } else { base.LoadControlState(null); } // DataPager handles the TotalRowCountAvailable event in order to create its pager fields. Normally this // is fired from CreateChildControls, but when ViewState is disabled this is not getting called until after // postback data has been handled. In this case the event will be fired using the control count from the // last request so that the pager fields can be initialized. if (!IsViewStateEnabled) { OnTotalRowCountAvailable(new PageEventArgs(_startRowIndex, _maximumRows, _totalRowCount)); } } 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]); } } } protected override void LoadViewState(object savedState) { if (savedState != null) { object[] state = (object[])savedState; base.LoadViewState(state[0]); if (state[1] != null) { OrderedDictionaryStateHelper.LoadViewState((OrderedDictionary)BoundFieldValues, (ArrayList)state[1]); } } else { base.LoadViewState(savedState); } } 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]); } } } [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "1#")] protected override bool OnBubbleEvent(object source, EventArgs e) { bool causesValidation = false; string validationGroup = String.Empty; ListViewCommandEventArgs commandEventArgs = e as ListViewCommandEventArgs; // todo: rethink this. Should everything in the layout template be bubbled // up as a ListViewCommand? if (commandEventArgs == null && e is CommandEventArgs) { // Use a new EmptyItem ListViewItem here so when HandleEvent tries to parse out the data item index, // the user gets a nice message about how this button should be in a data item. commandEventArgs = new ListViewCommandEventArgs(new ListViewItem(ListViewItemType.EmptyItem), source, (CommandEventArgs)e); } if (commandEventArgs != null) { IButtonControl button = commandEventArgs.CommandSource as IButtonControl; if (button != null) { causesValidation = button.CausesValidation; validationGroup = button.ValidationGroup; } } return HandleEvent(commandEventArgs, causesValidation, validationGroup); } [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] protected internal override void OnInit(EventArgs e) { base.OnInit(e); if (Page != null) { if (DataKeyNames.Length > 0) { Page.RegisterRequiresViewStateEncryption(); } Page.RegisterRequiresControlState(this); } } /// /// [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] protected virtual void OnItemCanceling(ListViewCancelEventArgs e) { EventHandlerRaises the ///event. handler = (EventHandler )Events[EventItemCanceling]; if (handler != null) { handler(this, e); } else { if (IsBoundUsingDataSourceID == false && e.Cancel == false) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_UnhandledEvent, ID, "ItemCanceling")); } } } /// /// [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] protected virtual void OnItemCommand(ListViewCommandEventArgs e) { EventHandlerRaises the ///event. handler = (EventHandler )Events[EventItemCommand]; if (handler != null) { handler(this, e); } } /// /// [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] protected virtual void OnItemCreated(ListViewItemEventArgs e) { EventHandlerRaises the ///event. handler = (EventHandler )Events[EventItemCreated]; if (handler != null) { handler(this, e); } } /// /// [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] protected virtual void OnItemDataBound(ListViewItemEventArgs e) { EventHandlerRaises the ///event. handler = (EventHandler )Events[EventItemDataBound]; if (handler != null) { handler(this, e); } // EventWizardListItemDataBound is a key for an internal event declared on IWizardSideBarListControl, which is // an interface that is meant to provide a facade to make ListView and DataList look the same. This handler // is meant to abstract away the differences between each controls ItemDataBound events. var wizardListHandler = (EventHandler )Events[EventWizardListItemDataBound]; if (wizardListHandler != null) { var item = e.Item; var wizardListEventArgs = new WizardSideBarListControlItemEventArgs(new WizardSideBarListControlItem(item.DataItem, ListItemType.Item, item.DataItemIndex, item)); wizardListHandler(this, wizardListEventArgs); } } /// /// [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] protected virtual void OnItemDeleted(ListViewDeletedEventArgs e) { EventHandlerRaises the ///event. handler = (EventHandler )Events[EventItemDeleted]; if (handler != null) { handler(this, e); } } /// /// [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] protected virtual void OnItemDeleting(ListViewDeleteEventArgs e) { EventHandlerRaises the ///event. handler = (EventHandler )Events[EventItemDeleting]; if (handler != null) { handler(this, e); } else { if (IsBoundUsingDataSourceID == false && e.Cancel == false) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_UnhandledEvent, ID, "ItemDeleting")); } } } /// /// [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] protected virtual void OnItemEditing(ListViewEditEventArgs e) { EventHandlerRaises the ///event. handler = (EventHandler )Events[EventItemEditing]; if (handler != null) { handler(this, e); } else { if (IsBoundUsingDataSourceID == false && e.Cancel == false) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_UnhandledEvent, ID, "ItemEditing")); } } } /// /// [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] protected virtual void OnItemInserted(ListViewInsertedEventArgs e) { EventHandlerRaises the ///event. handler = (EventHandler )Events[EventItemInserted]; if (handler != null) { handler(this, e); } } /// /// [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] protected virtual void OnItemInserting(ListViewInsertEventArgs e) { EventHandlerRaises the ///event. handler = (EventHandler )Events[EventItemInserting]; if (handler != null) { handler(this, e); } else { if (IsBoundUsingDataSourceID == false && e.Cancel == false) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_UnhandledEvent, ID, "ItemInserting")); } } } /// /// [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] protected virtual void OnItemUpdated(ListViewUpdatedEventArgs e) { EventHandlerRaises the ///event. handler = (EventHandler )Events[EventItemUpdated]; if (handler != null) handler(this, e); } /// /// [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] protected virtual void OnItemUpdating(ListViewUpdateEventArgs e) { EventHandlerRaises the ///event. handler = (EventHandler )Events[EventItemUpdating]; if (handler != null) { handler(this, e); } else { if (IsBoundUsingDataSourceID == false && e.Cancel == false) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_UnhandledEvent, ID, "ItemUpdating")); } } } /// /// [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] protected virtual void OnLayoutCreated(EventArgs e) { EventHandler handler = (EventHandler)Events[EventLayoutCreated]; if (handler != null) { handler(this, e); } } ///Raises the ///event. /// [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] protected virtual void OnPagePropertiesChanged(EventArgs e) { EventHandler handler = (EventHandler)Events[EventPagePropertiesChanged]; if (handler != null) { handler(this, e); } } ///Raises the ///event. /// [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] protected virtual void OnPagePropertiesChanging(PagePropertiesChangingEventArgs e) { EventHandlerRaises the ///event. handler = (EventHandler )Events[EventPagePropertiesChanging]; if (handler != null) { handler(this, e); } } /// /// [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] protected virtual void OnTotalRowCountAvailable(PageEventArgs e) { EventHandlerRaises the ///event of a . handler = (EventHandler )Events[EventTotalRowCountAvailable]; if (handler != null) { handler(this, e); } } /// /// [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] protected virtual void OnSelectedIndexChanged(EventArgs e) { EventHandler handler = (EventHandler)Events[EventSelectedIndexChanged]; if (handler != null) { handler(this, e); } } ///Raises the ///event of a . /// [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] protected virtual void OnSelectedIndexChanging(ListViewSelectEventArgs e) { EventHandlerRaises the ///event of a . handler = (EventHandler )Events[EventSelectedIndexChanging]; if (handler != null) { handler(this, e); } else { if (IsBoundUsingDataSourceID == false && e.Cancel == false) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_UnhandledEvent, ID, "SelectedIndexChanging")); } } } /// /// [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] protected virtual void OnSorted(EventArgs e) { EventHandler handler = (EventHandler)Events[EventSorted]; if (handler != null) { handler(this, e); } } ///Raises the ///event of a . /// [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] protected virtual void OnSorting(ListViewSortEventArgs e) { EventHandlerRaises the ///event. handler = (EventHandler )Events[EventSorting]; if (handler != null) { handler(this, e); } else { if (IsBoundUsingDataSourceID == false && e.Cancel == false) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_UnhandledEvent, ID, "Sorting")); } } } private bool PageIsValidAfterModelException() { if (_modelValidationGroup == null) { return true; } Page.Validate(_modelValidationGroup); return Page.IsValid; } /// /// Overriden by DataBoundControl to use its properties to determine the real /// data source that the control should bind to. It then clears the existing /// control hierarchy, and calls createChildControls to create a new control /// hierarchy based on the resolved data source. /// The implementation resolves various data source related properties to /// arrive at the appropriate IEnumerable implementation to use as the real /// data source. /// When resolving data sources, the DataSourceControlID takes highest precedence. /// In this mode, DataMember is used to access the appropriate list from the /// DataControl. /// If DataSourceControlID is not set, the value of the DataSource property is used. /// In this second alternative, DataMember is used to extract the appropriate /// list if the control has been handed an IListSource as a data source. /// protected internal override void PerformDataBinding(IEnumerable data) { base.PerformDataBinding(data); TrackViewState(); int controlCount = CreateChildControls(data, true); ChildControlsCreated = true; ViewState[ItemCountViewStateKey] = controlCount; int editIndex = EditIndex; if (IsBoundUsingDataSourceID && editIndex != -1 && editIndex < Items.Count && IsViewStateEnabled) { BoundFieldValues.Clear(); ExtractItemValues(BoundFieldValues, Items[editIndex], 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(AtlasWeb.ListView_PersistedSelectionRequiresDataKeysNames); } } } protected override void PerformSelect() { if (_performingSelect) { // Guard against databinding twice if we're currently databinding. // This happens when the ListView is nested within a databound control, and the call // To EnsureLayoutTemplate triggers a recursive DataBind. return; } try { _performingSelect = true; // If there is a DataPager in the layout template, we need the ListView's paging properties // to be set before we go to the datasource EnsureLayoutTemplate(); if (DesignMode) { // Try to find a pager that will control the paging on this control. // In design mode, an embedded pager will not have a designer but will // be the runtime control itself. We want the max rows so the ListView // renders with the right page size. DataPager pager = FindDataPager(this); if (pager != null) { _maximumRows = pager.PageSize; } } base.PerformSelect(); } finally { _performingSelect = false; } } protected virtual void RemoveItems() { if (_groupTemplate != null) { // If we're in grouped mode, delete all the items created in CreateItemsInGroups(). if (_groupsItemCreatedCount > 0) { for (int i = 0; i < _groupsItemCreatedCount; i++) { _groupsGroupPlaceholderContainer.Controls.RemoveAt(_groupsOriginalIndexOfGroupPlaceholderInContainer); } _groupsItemCreatedCount = 0; } } else { // If we're not in grouped mode, delete all the items // created in CreateItemsWithoutGroups(). if (_noGroupsItemCreatedCount > 0) { for (int i = 0; i < _noGroupsItemCreatedCount; i++) { _noGroupsItemPlaceholderContainer.Controls.RemoveAt(_noGroupsOriginalIndexOfItemPlaceholderInContainer); } _noGroupsItemCreatedCount = 0; } } _autoIDIndex = 0; } protected internal override void Render(HtmlTextWriter writer) { // Render only the contents. We don't want a rendered span tag around the control. RenderContents(writer); } private void ResetModelValidationGroup(bool causesValidation, string validationGroup) { _modelValidationGroup = null; if (causesValidation) { Page.Validate(validationGroup); if (EnableModelValidation) { _modelValidationGroup = validationGroup; } } } ////// protected internal override object SaveControlState() { object baseState = base.SaveControlState(); if (baseState != null || _startRowIndex > 0 || _maximumRows != -1 || _editIndex != -1 || _selectedIndex != -1 || _groupItemCount != 1 || (_sortExpression != null && _sortExpression.Length != 0) || _sortDirection != SortDirection.Ascending || _totalRowCount != -1 || (_dataKeyNames != null && _dataKeyNames.Length != 0) || (_dataKeysArrayList != null && _dataKeysArrayList.Count > 0)) { object[] state = new object[14]; state[0] = baseState; state[1] = (_editIndex == -1) ? null : (object)_editIndex; state[2] = (_selectedIndex == -1) ? null : (object)_selectedIndex; state[3] = (_groupItemCount == 1) ? null : (object)_groupItemCount; 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] = (_totalRowCount == -1) ? null : (object)_totalRowCount; state[9] = (_persistedDataKey == null) ? null : ((IStateManager)_persistedDataKey).SaveViewState(); state[10] = (_clientIDRowSuffix == null || _clientIDRowSuffix.Length == 0) ? null : (object)_clientIDRowSuffix; state[11] = SaveClientIDRowSuffixDataKeysState(); state[12] = _startRowIndex; state[13] = _maximumRows; 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; } protected override object SaveViewState() { object baseState = base.SaveViewState(); object boundFieldValuesState = (_boundFieldValues != null) ? OrderedDictionaryStateHelper.SaveViewState(_boundFieldValues) : null; object[] state = new object[2]; state[0] = baseState; state[1] = boundFieldValuesState; return state; } 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; } 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 InvalidOperationException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_DataSourceDoesntSupportPaging, DataSourceID)); } private void SetRequiresDataBindingIfInitialized() { if (Initialized) { RequiresDataBinding = true; } } public virtual void Sort(string sortExpression, SortDirection sortDirection) { HandleSort(sortExpression, sortDirection); } public virtual void UpdateItem(int itemIndex, bool causesValidation) { ResetModelValidationGroup(causesValidation, String.Empty); HandleUpdate(null, itemIndex, causesValidation); } #region IPageableItemContainer int IPageableItemContainer.StartRowIndex { get { return StartRowIndex; } } // Overridable version protected virtual int StartRowIndex { get { return _startRowIndex; } } int IPageableItemContainer.MaximumRows { get { return MaximumRows; } } // Overridable version protected virtual int MaximumRows { get { return _maximumRows; } } void IPageableItemContainer.SetPageProperties(int startRowIndex, int maximumRows, bool databind) { SetPageProperties(startRowIndex, maximumRows, databind); } [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "A property already exists. This method does additional work.")] public void SelectItem(int rowIndex) { HandleSelect(rowIndex); } [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "A property already exists. This method does additional work.")] public void SetEditItem(int rowIndex) { HandleEdit(rowIndex); } // Overridable version [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "databind", Justification = "Cannot change to 'dataBind' as would break binary compatibility with legacy code.")] protected virtual void SetPageProperties(int startRowIndex, int maximumRows, bool databind) { if (maximumRows < 1) { throw new ArgumentOutOfRangeException("maximumRows"); } if (startRowIndex < 0) { throw new ArgumentOutOfRangeException("startRowIndex"); } if (_startRowIndex != startRowIndex || _maximumRows != maximumRows) { PagePropertiesChangingEventArgs args = new PagePropertiesChangingEventArgs(startRowIndex, maximumRows); if (databind) { // This event is cancellable, and its properties aren't settable, because changing them would // create a strange disconnect between the pager and the ListView. You have to set // these properties on the pager if you want to change them. This is a notification event. OnPagePropertiesChanging(args); } _startRowIndex = args.StartRowIndex; _maximumRows = args.MaximumRows; if (databind) { OnPagePropertiesChanged(EventArgs.Empty); } } if (databind) { RequiresDataBinding = true; } } [SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Justification = "Unlikely that a derived type would re-implement this event.")] event EventHandlerSaves the control state for those properties that should persist across postbacks /// even when EnableViewState=false. ///IPageableItemContainer.TotalRowCountAvailable { add { Events.AddHandler(EventTotalRowCountAvailable, value); } remove { Events.RemoveHandler(EventTotalRowCountAvailable, value); } } #endregion IPageableItemContainer #region IPersistedSelector implementation 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; } } string IDataBoundControl.DataSourceID { get { return DataSourceID; } set { DataSourceID = value; } } IDataSource IDataBoundControl.DataSourceObject { get { return DataSourceObject; } } object IDataBoundControl.DataSource { get { return DataSource; } set { DataSource = value; } } string[] IDataBoundControl.DataKeyNames { get { return DataKeyNames; } set { DataKeyNames = value; } } string IDataBoundControl.DataMember { get { return DataMember; } set { DataMember = value; } } #endregion #region IWizardSideBarListControl implementation IEnumerable IWizardSideBarListControl.Items { get { return Items; } } event CommandEventHandler IWizardSideBarListControl.ItemCommand { add { ItemCommand += new EventHandler (value); } remove { ItemCommand -= new EventHandler (value); } } event EventHandler IWizardSideBarListControl.ItemDataBound { add { Events.AddHandler(EventWizardListItemDataBound, value); } remove { Events.RemoveHandler(EventWizardListItemDataBound, value); } } #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ // // Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Collections.Specialized; using System.ComponentModel; using System.Diagnostics.CodeAnalysis; using System.Drawing; using System.Drawing.Design; using System.Globalization; using System.Web; using System.Web.Resources; using System.Web.UI; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; namespace System.Web.UI.WebControls { [DefaultProperty("SelectedValue")] [Designer("System.Web.UI.Design.WebControls.ListViewDesigner, " + AssemblyRef.SystemWebExtensionsDesign)] [ControlValueProperty("SelectedValue")] [DefaultEvent("SelectedIndexChanged")] [SupportsEventValidation] [ToolboxBitmap(typeof(ListView), "ListView.bmp")] [DataKeyProperty("SelectedPersistedDataKey")] public class ListView : DataBoundControl, INamingContainer, IPageableItemContainer, IPersistedSelector, IDataKeysControl, IDataBoundListControl, IWizardSideBarListControl { internal const string ItemCountViewStateKey = "_!ItemCount"; private ITemplate _itemTemplate; private ITemplate _editItemTemplate; private ITemplate _insertItemTemplate; private ITemplate _layoutTemplate; private ITemplate _selectedItemTemplate; private ITemplate _groupTemplate; private ITemplate _itemSeparatorTemplate; private ITemplate _groupSeparatorTemplate; private ITemplate _emptyItemTemplate; private ITemplate _emptyDataTemplate; private ITemplate _alternatingItemTemplate; private static readonly object EventTotalRowCountAvailable = new object(); private static readonly object EventPagePropertiesChanged = new object(); private static readonly object EventPagePropertiesChanging = new object(); private static readonly object EventItemCanceling = new object(); private static readonly object EventItemCommand = new object(); private static readonly object EventItemCreated = new object(); private static readonly object EventItemDataBound = new object(); private static readonly object EventItemDeleted = new object(); private static readonly object EventItemDeleting = new object(); private static readonly object EventItemEditing = new object(); private static readonly object EventItemInserted = new object(); private static readonly object EventItemInserting = new object(); private static readonly object EventItemUpdated = new object(); private static readonly object EventItemUpdating = new object(); private static readonly object EventLayoutCreated = 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 static readonly object EventWizardListItemDataBound = new object(); private bool _performingSelect; private int _editIndex = -1; private int _selectedIndex = -1; private int _groupItemCount = 1; private string _modelValidationGroup; private string _sortExpression = String.Empty; private SortDirection _sortDirection = SortDirection.Ascending; private int _startRowIndex = 0; private int _maximumRows = -1; private int _totalRowCount = -1; private IList_itemList; private ListViewItem _insertItem; private string[] _dataKeyNames; private string[] _clientIDRowSuffix; private DataKeyArray _dataKeyArray; private ArrayList _dataKeysArrayList; private DataKeyArray _clientIDRowSuffixArray; private ArrayList _clientIDRowSuffixArrayList; private OrderedDictionary _boundFieldValues; private DataKey _persistedDataKey; private int _deletedItemIndex; private IOrderedDictionary _deleteKeys; private IOrderedDictionary _deleteValues; private IOrderedDictionary _insertValues; private IOrderedDictionary _updateKeys; private IOrderedDictionary _updateOldValues; private IOrderedDictionary _updateNewValues; private int _autoIDIndex = 0; private const string _automaticIDPrefix = "ctrl"; private bool _instantiatedEmptyDataTemplate = false; // Keep track of where we instantiated templates when we're not using grouping private int _noGroupsOriginalIndexOfItemPlaceholderInContainer = -1; private int _noGroupsItemCreatedCount; private Control _noGroupsItemPlaceholderContainer; // Keep track of where we instantiated templates when we're using grouping private int _groupsOriginalIndexOfGroupPlaceholderInContainer = -1; private int _groupsItemCreatedCount; private Control _groupsGroupPlaceholderContainer; public ListView() { } // Override style properties and throw from setter, and set Browsable(false). // Don't throw from getters because designer calls getters through reflection. [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never) ] public override string AccessKey { get { return base.AccessKey; } set { throw new NotSupportedException(AtlasWeb.ListView_StylePropertiesNotSupported); } } [ Browsable(false), DefaultValue(null), PersistenceMode(PersistenceMode.InnerProperty), TemplateContainer(typeof(ListViewDataItem), BindingDirection.TwoWay), ResourceDescription("ListView_AlternatingItemTemplate") ] public virtual ITemplate AlternatingItemTemplate { get { return _alternatingItemTemplate; } set { _alternatingItemTemplate = value; } } // Override style properties and throw from setter, and set Browsable(false). // Don't throw from getters because designer calls getters through reflection. [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never) ] public override Color BackColor { get { return base.BackColor; } set { throw new NotSupportedException(AtlasWeb.ListView_StylePropertiesNotSupported); } } // Override style properties and throw from setter, and set Browsable(false). // Don't throw from getters because designer calls getters through reflection. [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never) ] public override Color BorderColor { get { return base.BorderColor; } set { throw new NotSupportedException(AtlasWeb.ListView_StylePropertiesNotSupported); } } // Override style properties and throw from setter, and set Browsable(false). // Don't throw from getters because designer calls getters through reflection. [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never) ] public override Unit BorderWidth { get { return base.BorderWidth; } set { throw new NotSupportedException(AtlasWeb.ListView_StylePropertiesNotSupported); } } // Override style properties and throw from setter, and set Browsable(false). // Don't throw from getters because designer calls getters through reflection. [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never) ] public override BorderStyle BorderStyle { get { return base.BorderStyle; } set { throw new NotSupportedException(AtlasWeb.ListView_StylePropertiesNotSupported); } } private IOrderedDictionary BoundFieldValues { get { if (_boundFieldValues == null) { _boundFieldValues = new OrderedDictionary(); } return _boundFieldValues; } } public override ControlCollection Controls { get { EnsureChildControls(); return base.Controls; } } /// /// [ Category("Behavior"), DefaultValue(true), ResourceDescription("ListView_ConvertEmptyStringToNull"), ] public virtual bool ConvertEmptyStringToNull { get { object o = ViewState["ConvertEmptyStringToNull"]; if (o != null) { return (bool)o; } return true; } set { ViewState["ConvertEmptyStringToNull"] = value; } } // Override style properties and throw from setter, and set Browsable(false). // Don't throw from getters because designer calls getters through reflection. [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never), CssClassPropertyAttribute ] public override string CssClass { get { return base.CssClass; } set { throw new NotSupportedException(AtlasWeb.ListView_StylePropertiesNotSupported); } } ///Gets or sets the property that determines whether the control treats empty string as /// null when the item values are extracted. ////// An array of ordered dictionaries that represents each key /// private ArrayList DataKeysArrayList { get { if (_dataKeysArrayList == null) { _dataKeysArrayList = new ArrayList(); } return _dataKeysArrayList; } } private ArrayList ClientIDRowSuffixArrayList { get { if (_clientIDRowSuffixArrayList == null) { _clientIDRowSuffixArrayList = new ArrayList(); } return _clientIDRowSuffixArrayList; } } [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), ResourceDescription("ListView_DataKeys") ] public virtual DataKeyArray DataKeys { get { if (_dataKeyArray == null) { _dataKeyArray = new DataKeyArray(this.DataKeysArrayList); if (IsTrackingViewState) ((IStateManager)_dataKeyArray).TrackViewState(); } return _dataKeyArray; } } [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "ID"), ] 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)), Category("Data"), ResourceDescription("ListView_DataKeyNames"), SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Justification = "Required by ASP.NET parser."), TypeConverterAttribute(typeof(StringArrayConverter)), ] 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(); SetRequiresDataBindingIfInitialized(); } } } // This version doesn't clone the array private string[] DataKeyNamesInternal { get { object o = _dataKeyNames; if (o != null) { return (string[])o; } return new string[0]; } } [ Category("Default"), DefaultValue(-1), ResourceDescription("ListView_EditIndex") ] public virtual int EditIndex { get { return _editIndex; } set { if (value < -1) { throw new ArgumentOutOfRangeException("value"); } if (value != _editIndex) { if (value == -1) { BoundFieldValues.Clear(); } _editIndex = value; SetRequiresDataBindingIfInitialized(); } } } [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), ResourceDescription("ListView_EditItem") ] public virtual ListViewItem EditItem { get { if (_editIndex > -1 && _editIndex < Items.Count) { return Items[_editIndex]; } return null; } } [ Browsable(false), DefaultValue(null), PersistenceMode(PersistenceMode.InnerProperty), TemplateContainer(typeof(ListViewDataItem), BindingDirection.TwoWay), ResourceDescription("ListView_EditItemTemplate"), ] public virtual ITemplate EditItemTemplate { get { return _editItemTemplate; } set { _editItemTemplate = value; } } [ Browsable(false), DefaultValue(null), PersistenceMode(PersistenceMode.InnerProperty), TemplateContainer(typeof(ListView)), ResourceDescription("ListView_EmptyDataTemplate"), ] public virtual ITemplate EmptyDataTemplate { get { return _emptyDataTemplate; } set { _emptyDataTemplate = value; } } [ Browsable(false), DefaultValue(null), PersistenceMode(PersistenceMode.InnerProperty), TemplateContainer(typeof(ListViewItem)), ResourceDescription("ListView_EmptyItemTemplate"), ] public virtual ITemplate EmptyItemTemplate { get { return _emptyItemTemplate; } set { _emptyItemTemplate = value; } } [ WebCategory("Behavior"), DefaultValue(true), ResourceDescription("ListView_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), ResourceDescription("ListView_EnablePersistedSelection") ] public virtual bool EnablePersistedSelection { get { object o = ViewState["EnablePersistedSelection"]; if (o != null) { return (bool)o; } return false; } set { ViewState["EnablePersistedSelection"] = value; } } // Override style properties and throw from setter, and set Browsable(false). // Don't throw from getters because designer calls getters through reflection. [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never) ] public override FontInfo Font { get { return base.Font; } } // Override style properties and throw from setter, and set Browsable(false). // Don't throw from getters because designer calls getters through reflection. [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never) ] public override Color ForeColor { get { return base.ForeColor; } set { throw new NotSupportedException(AtlasWeb.ListView_StylePropertiesNotSupported); } } [ DefaultValue("groupPlaceholder"), Category("Behavior"), ResourceDescription("ListView_GroupPlaceholderID"), SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "ID") ] public virtual String GroupPlaceholderID { get { object o = ViewState["GroupPlaceholderID"]; if (o != null) { return (String)o; } return "groupPlaceholder"; } set { if (String.IsNullOrEmpty(value)) { throw new ArgumentOutOfRangeException("value", String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_ContainerNameMustNotBeEmpty, "GroupPlaceholderID")); } ViewState["GroupPlaceholderID"] = value; } } [ Category("Default"), DefaultValue(1), ResourceDescription("ListView_GroupItemCount"), ] public virtual int GroupItemCount { get { return _groupItemCount; } set { if (value < 1) { throw new ArgumentOutOfRangeException("value"); } _groupItemCount = value; SetRequiresDataBindingIfInitialized(); } } [ Browsable(false), DefaultValue(null), PersistenceMode(PersistenceMode.InnerProperty), TemplateContainer(typeof(ListViewItem)), ResourceDescription("ListView_GroupSeparatorTemplate"), ] public virtual ITemplate GroupSeparatorTemplate { get { return _groupSeparatorTemplate; } set { _groupSeparatorTemplate = value; } } [ Browsable(false), DefaultValue(null), PersistenceMode(PersistenceMode.InnerProperty), TemplateContainer(typeof(ListViewItem)), ResourceDescription("ListView_GroupTemplate"), ] public virtual ITemplate GroupTemplate { get { return _groupTemplate; } set { _groupTemplate = value; } } // Override style properties and throw from setter, and set Browsable(false). // Don't throw from getters because designer calls getters through reflection. [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never) ] public override Unit Height { get { return base.Height; } set { throw new NotSupportedException(AtlasWeb.ListView_StylePropertiesNotSupported); } } [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), ResourceDescription("ListView_InsertItem") ] public virtual ListViewItem InsertItem { get { return _insertItem; } } [ Category("Default"), DefaultValue(InsertItemPosition.None), ResourceDescription("ListView_InsertItemPosition") ] public virtual InsertItemPosition InsertItemPosition { get { object o = ViewState["InsertItemPosition"]; if (o != null) { return (InsertItemPosition)o; } return InsertItemPosition.None; } set { if (InsertItemPosition != value) { ViewState["InsertItemPosition"] = value; SetRequiresDataBindingIfInitialized(); } } } [ Browsable(false), DefaultValue(null), PersistenceMode(PersistenceMode.InnerProperty), TemplateContainer(typeof(ListViewItem), BindingDirection.TwoWay), ResourceDescription("ListView_InsertItemTemplate"), ] public virtual ITemplate InsertItemTemplate { get { return _insertItemTemplate; } set { _insertItemTemplate = value; } } [ DefaultValue("itemPlaceholder"), Category("Behavior"), ResourceDescription("ListView_ItemPlaceholderID"), SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "ID") ] public virtual String ItemPlaceholderID { get { object o = ViewState["ItemPlaceholderID"]; if (o != null) { return (String)o; } return "itemPlaceholder"; } set { if (String.IsNullOrEmpty(value)) { throw new ArgumentOutOfRangeException("value", String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_ContainerNameMustNotBeEmpty, "ItemPlaceholderID")); } ViewState["ItemPlaceholderID"] = value; } } [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), ResourceDescription("ListView_Items") ] public virtual IListItems { get { if (_itemList == null) { _itemList = new List (); } return _itemList; } } [ Browsable(false), DefaultValue(null), PersistenceMode(PersistenceMode.InnerProperty), TemplateContainer(typeof(ListViewItem)), ResourceDescription("ListView_ItemSeparatorTemplate"), ] public virtual ITemplate ItemSeparatorTemplate { get { return _itemSeparatorTemplate; } set { _itemSeparatorTemplate = value; } } [ Browsable(false), DefaultValue(null), PersistenceMode(PersistenceMode.InnerProperty), TemplateContainer(typeof(ListViewDataItem), BindingDirection.TwoWay), ResourceDescription("ListView_ItemTemplate"), SuppressMessage("Microsoft.Security", "CA2119:SealMethodsThatSatisfyPrivateInterfaces", Justification = "Interface denotes existence of property, not used for security.") ] public virtual ITemplate ItemTemplate { get { return _itemTemplate; } set { _itemTemplate = value; } } [ Browsable(false), DefaultValue(null), PersistenceMode(PersistenceMode.InnerProperty), TemplateContainer(typeof(ListView)), ResourceDescription("ListView_LayoutTemplate"), ] public virtual ITemplate LayoutTemplate { get { return _layoutTemplate; } set { _layoutTemplate = value; } } [ 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]; } } [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) ] public virtual DataKey SelectedDataKey { get { if (DataKeyNamesInternal == null || DataKeyNamesInternal.Length == 0) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_DataKeyNamesMustBeSpecified, ID)); } DataKeyArray keys = DataKeys; int selectedIndex = SelectedIndex; if (keys != null && selectedIndex < keys.Count && selectedIndex > -1) { return keys[selectedIndex]; } return null; } } [ Category("Default"), DefaultValue(-1), ResourceDescription("ListView_SelectedIndex"), SuppressMessage("Microsoft.Security", "CA2119:SealMethodsThatSatisfyPrivateInterfaces", Justification = "Interface denotes existence of property, not used for security.") ] public virtual int SelectedIndex { get { return _selectedIndex; } set { if (value < -1) { throw new ArgumentOutOfRangeException("value"); } if (value != _selectedIndex) { // update the virtual selection to use the new selection _selectedIndex = value; if (EnablePersistedSelection && (DataKeyNamesInternal.Length > 0)) { SelectedPersistedDataKey = SelectedDataKey; } // we're going to rebind here for a new template SetRequiresDataBindingIfInitialized(); } } } [ Browsable(false), DefaultValue(null), PersistenceMode(PersistenceMode.InnerProperty), TemplateContainer(typeof(ListViewDataItem), BindingDirection.TwoWay), ResourceDescription("ListView_SelectedItemTemplate"), ] public virtual ITemplate SelectedItemTemplate { get { return _selectedItemTemplate; } set { _selectedItemTemplate = value; } } [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) ] public object SelectedValue { get { DataKey selectedDataKey = SelectedDataKey; if (selectedDataKey != null) { return SelectedDataKey.Value; } return null; } } [ Browsable(false), DefaultValue(SortDirection.Ascending), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), PersistenceMode(PersistenceMode.InnerProperty), ResourceDescription("ListView_SortDirection"), ResourceCategory("Sorting"), ] public virtual SortDirection SortDirection { get { return SortDirectionInternal; } } /// /// Internal member for setting sort direction /// private SortDirection SortDirectionInternal { get { return _sortDirection; } set { if (value < SortDirection.Ascending || value > SortDirection.Descending) { throw new ArgumentOutOfRangeException("value"); } if (_sortDirection != value) { _sortDirection = value; SetRequiresDataBindingIfInitialized(); } } } ////// Gets a value that specifies the current column being sorted on in the /// [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), ResourceDescription("ListView_SortExpression"), ResourceCategory("Sorting"), ] public virtual string SortExpression { get { return SortExpressionInternal; } } ///. /// /// Internal member for setting sort expression /// private string SortExpressionInternal { get { return _sortExpression; } set { if (_sortExpression != value) { _sortExpression = value; SetRequiresDataBindingIfInitialized(); } } } // Override style properties and throw from setter, and set Browsable(false). // Don't throw from getters because designer calls getters through reflection. [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never) ] public override short TabIndex { get { return base.TabIndex; } set { throw new NotSupportedException(AtlasWeb.ListView_StylePropertiesNotSupported); } } // Override style properties and throw from setter, and set Browsable(false). // Don't throw from getters because designer calls getters through reflection. [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never) ] public override string ToolTip { get { return base.ToolTip; } set { throw new NotSupportedException(AtlasWeb.ListView_StylePropertiesNotSupported); } } [ Browsable(false) ] public virtual DataKey SelectedPersistedDataKey { get { return _persistedDataKey; } set { _persistedDataKey = value; if (IsTrackingViewState && (_persistedDataKey != null)) { ((IStateManager)_persistedDataKey).TrackViewState(); } } } // Override style properties and throw from setter, and set Browsable(false). // Don't throw from getters because designer calls getters through reflection. [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never) ] public override Unit Width { get { return base.Width; } set { throw new NotSupportedException(AtlasWeb.ListView_StylePropertiesNotSupported); } } ////// [ Category("Action"), ResourceDescription("ListView_OnItemDeleted") ] public event EventHandlerOccurs when a control bubbles an event to the ///with a /// . ItemDeleted { add { Events.AddHandler(EventItemDeleted, value); } remove { Events.RemoveHandler(EventItemDeleted, value); } } /// /// [ Category("Action"), ResourceDescription("ListView_OnItemInserted") ] public event EventHandlerOccurs when a control bubbles an event to the ///with a /// . ItemInserted { add { Events.AddHandler(EventItemInserted, value); } remove { Events.RemoveHandler(EventItemInserted, value); } } /// /// [ Category("Action"), ResourceDescription("ListView_OnItemUpdated") ] public event EventHandlerOccurs when a control bubbles an event to the ///with a /// . ItemUpdated { add { Events.AddHandler(EventItemUpdated, value); } remove { Events.RemoveHandler(EventItemUpdated, value); } } /// /// [ Category("Action"), ResourceDescription("ListView_OnItemCanceling") ] public event EventHandlerOccurs when a control bubbles an event to the ///with a /// property of /// . ItemCanceling { add { Events.AddHandler(EventItemCanceling, value); } remove { Events.RemoveHandler(EventItemCanceling, value); } } /// Occurs when a control bubbles an event to the /// [ Category("Action"), ResourceDescription("ListView_OnItemCommand") ] public event EventHandlernot covered by /// , , or /// . ItemCommand { add { Events.AddHandler(EventItemCommand, value); } remove { Events.RemoveHandler(EventItemCommand, value); } } /// /// [ Category("Behavior"), ResourceDescription("ListView_OnItemCreated") ] public event EventHandlerOccurs on the server when a control a created. ///ItemCreated { add { Events.AddHandler(EventItemCreated, value); } remove { Events.RemoveHandler(EventItemCreated, value); } } /// /// [ Category("Data"), ResourceDescription("ListView_OnItemDataBound") ] public event EventHandlerOccurs when an Item is data bound to the control. ///ItemDataBound { add { Events.AddHandler(EventItemDataBound, value); } remove { Events.RemoveHandler(EventItemDataBound, value); } } /// /// [ Category("Action"), ResourceDescription("ListView_OnItemDeleting") ] public event EventHandlerOccurs when a control bubbles an event to the ///with a /// . ItemDeleting { add { Events.AddHandler(EventItemDeleting, value); } remove { Events.RemoveHandler(EventItemDeleting, value); } } /// /// [ Category("Action"), ResourceDescription("ListView_OnItemEditing") ] public event EventHandlerOccurs when a control bubbles an event to the ///with a /// property of /// . ItemEditing { add { Events.AddHandler(EventItemEditing, value); } remove { Events.RemoveHandler(EventItemEditing, value); } } /// /// [ Category("Action"), ResourceDescription("ListView_OnItemInserting") ] public event EventHandlerOccurs when a control bubbles an event to the ///with a /// . ItemInserting { add { Events.AddHandler(EventItemInserting, value); } remove { Events.RemoveHandler(EventItemInserting, value); } } /// /// [ Category("Action"), ResourceDescription("ListView_OnItemUpdating") ] public event EventHandlerOccurs when a control bubbles an event to the ///with a /// . ItemUpdating { add { Events.AddHandler(EventItemUpdating, value); } remove { Events.RemoveHandler(EventItemUpdating, value); } } /// /// [ Category("Behavior"), ResourceDescription("ListView_OnLayoutCreated") ] public event EventHandler LayoutCreated { add { Events.AddHandler(EventLayoutCreated, value); } remove { Events.RemoveHandler(EventLayoutCreated, value); } } ///Occurs on the server when a control layout is created. ////// [ Category("Behavior"), ResourceDescription("ListView_OnPagePropertiesChanged") ] public event EventHandler PagePropertiesChanged { add { Events.AddHandler(EventPagePropertiesChanged, value); } remove { Events.RemoveHandler(EventPagePropertiesChanged, value); } } ///Occurs on the server when the page properties have changed. ////// [ Category("Behavior"), ResourceDescription("ListView_OnPagePropertiesChanging") ] public event EventHandlerOccurs on the server when the page properties are changing. ///PagePropertiesChanging { add { Events.AddHandler(EventPagePropertiesChanging, value); } remove { Events.RemoveHandler(EventPagePropertiesChanging, value); } } /// /// [ Category("Action"), ResourceDescription("ListView_OnSelectedIndexChanged") ] public event EventHandler SelectedIndexChanged { add { Events.AddHandler(EventSelectedIndexChanged, value); } remove { Events.RemoveHandler(EventSelectedIndexChanged, value); } } ///Occurs when an Item on the list is selected. ////// [ Category("Action"), ResourceDescription("ListView_OnSelectedIndexChanging") ] public event EventHandlerOccurs when an Item on the list is selected. ///SelectedIndexChanging { add { Events.AddHandler(EventSelectedIndexChanging, value); } remove { Events.RemoveHandler(EventSelectedIndexChanging, value); } } /// /// [ Category("Action"), ResourceDescription("ListView_OnSorted") ] public event EventHandler Sorted { add { Events.AddHandler(EventSorted, value); } remove { Events.RemoveHandler(EventSorted, value); } } ///Occurs when a field is sorted. ////// [ Category("Action"), ResourceDescription("ListView_OnSorting") ] public event EventHandlerOccurs when a field is sorting. ///Sorting { add { Events.AddHandler(EventSorting, value); } remove { Events.RemoveHandler(EventSorting, value); } } protected virtual void AddControlToContainer(Control control, Control container, int addLocation) { // The ListView packages up everything in the ItemTemplate in a ListViewDataItem or ListViewItem. // The ListViewItem is being added to the control tree. Since ListViewItems can't be children of HtmlTables or // HtmlTableRows, we put them in a derived HtmlTable or HtmlTableRow, which just renders out its children. // Since ListViewItems don't have any rendering, only the child HtmlTableRow or HtmlTableCell will be rendered. if (container is HtmlTable) { ListViewTableRow listViewTableRow = new ListViewTableRow(); container.Controls.AddAt(addLocation, listViewTableRow); listViewTableRow.Controls.Add(control); } else { if (container is HtmlTableRow) { ListViewTableCell listViewTableCell = new ListViewTableCell(); container.Controls.AddAt(addLocation, listViewTableCell); listViewTableCell.Controls.Add(control); } else { container.Controls.AddAt(addLocation, control); } } } private void AutoIDControl(Control control) { // We have to do our own auto-id'ing because we create the LayoutTemplate, add controls // to the item or group container, then clear those controls out when we bind again. // Because the item or group container isn't necessarily a naming container, clearing // out its controls collection doesn't reset the auto-id counter and you get new ids. // On postback, controls that have post data won't be found because their generated // ids won't match the prior ones. By creating our own auto-id'ing, we don't get // Control's auto-id, and we can reset the auto id index when we remove all items from // the item or group container. control.ID = _automaticIDPrefix + _autoIDIndex++.ToString(CultureInfo.InvariantCulture); } private void ClearDataKeys() { _dataKeysArrayList = null; } /// /// Overriden by DataBoundControl to determine if the control should /// recreate its control hierarchy based on values in view state. /// If the control hierarchy should be created, i.e. view state does /// exist, it calls CreateChildControls with a dummy (empty) data source /// which is usable for enumeration purposes only. /// protected internal override void CreateChildControls() { object controlCount = ViewState[ItemCountViewStateKey]; if (controlCount == null && RequiresDataBinding) { EnsureDataBound(); } if (controlCount != null && ((int)controlCount) != -1) { object[] dummyDataSource = new object[(int)controlCount]; CreateChildControls(dummyDataSource, false); ClearChildViewState(); } } ////// Performs the work of creating the control hierarchy based on a data source. /// When dataBinding is true, the specified data source contains real /// data, and the data is supposed to be pushed into the UI. /// When dataBinding is false, the specified data source is a dummy data /// source, that allows enumerating the right number of items, but the items /// themselves are null and do not contain data. In this case, the recreated /// control hierarchy reinitializes its state from view state. /// It enables a DataBoundControl to encapsulate the logic of creating its /// control hierarchy in both modes into a single code path. /// /// /// The data source to be used to enumerate items. /// /// /// Whether the method has been called from DataBind or not. /// ////// The number of items created based on the data source. Put another way, its /// the number of items enumerated from the data source. /// protected virtual int CreateChildControls(IEnumerable dataSource, bool dataBinding) { ListViewPagedDataSource pagedDataSource = null; // Create the LayoutTemplate so the pager control in it can set page properties. // We'll only create the layout template once. EnsureLayoutTemplate(); RemoveItems(); // if we should render the insert item, make a dummy empty datasource and go through // the regular code path. if (dataSource == null && InsertItemPosition != InsertItemPosition.None) { dataSource = new object[0]; } bool usePaging = (_startRowIndex > 0 || _maximumRows > 0); if (dataBinding) { DataSourceView view = GetData(); DataSourceSelectArguments arguments = SelectArguments; if (view == null) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_NullView, ID)); } bool useServerPaging = view.CanPage && usePaging; if (!view.CanPage && useServerPaging) { if (dataSource != null && !(dataSource is ICollection)) { arguments.StartRowIndex = _startRowIndex; arguments.MaximumRows = _maximumRows; // 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) { int totalRowCount; if (view.CanRetrieveTotalRowCount) { totalRowCount = arguments.TotalRowCount; } else { ICollection dataSourceCollection = dataSource as ICollection; if (dataSourceCollection == null) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_NeedICollectionOrTotalRowCount, GetType().Name)); } totalRowCount = checked(_startRowIndex + dataSourceCollection.Count); } pagedDataSource = CreateServerPagedDataSource(totalRowCount); } else { pagedDataSource = CreatePagedDataSource(); } } else { pagedDataSource = CreatePagedDataSource(); } ArrayList keyArray = DataKeysArrayList; ArrayList suffixArray = ClientIDRowSuffixArrayList; _dataKeyArray = null; _clientIDRowSuffixArray = null; ICollection collection = dataSource as ICollection; if (dataBinding) { keyArray.Clear(); suffixArray.Clear(); if ((dataSource != null) && (collection == null) && !pagedDataSource.IsServerPagingEnabled && usePaging) { // 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. throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_Missing_VirtualItemCount, ID)); } } else { if (collection == null) { throw new InvalidOperationException(AtlasWeb.ListView_DataSourceMustBeCollectionWhenNotDataBinding); } } if (dataSource != null) { pagedDataSource.DataSource = dataSource; if (dataBinding && usePaging) { keyArray.Capacity = pagedDataSource.DataSourceCount; suffixArray.Capacity = pagedDataSource.DataSourceCount; } if (_groupTemplate != null) { _itemList = CreateItemsInGroups(pagedDataSource, dataBinding, InsertItemPosition, keyArray); if (dataBinding && ClientIDRowSuffixInternal != null && ClientIDRowSuffixInternal.Length != 0) { CreateSuffixArrayList(pagedDataSource, suffixArray); } } else { if (GroupItemCount != 1) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_GroupItemCountNoGroupTemplate, ID, GroupPlaceholderID)); } _itemList = CreateItemsWithoutGroups(pagedDataSource, dataBinding, InsertItemPosition, keyArray); if(dataBinding && ClientIDRowSuffixInternal != null && ClientIDRowSuffixInternal.Length != 0) { CreateSuffixArrayList(pagedDataSource, suffixArray); } } _totalRowCount = usePaging ? pagedDataSource.DataSourceCount : _itemList.Count; OnTotalRowCountAvailable(new PageEventArgs(_startRowIndex, _maximumRows, _totalRowCount)); if (_itemList.Count == 0) { if (InsertItemPosition == InsertItemPosition.None) { // remove the layout template Controls.Clear(); CreateEmptyDataItem(); } } } else { // remove the layout template Controls.Clear(); CreateEmptyDataItem(); } return _totalRowCount; } // Style properties won't be honored on ListView, so throw if someone tries to set any style properties protected override Style CreateControlStyle() { // The designer reflects on properties at design time. Don't throw then. if (!DesignMode) { throw new NotSupportedException(AtlasWeb.ListView_StyleNotSupported); } return base.CreateControlStyle(); } protected override DataSourceSelectArguments CreateDataSourceSelectArguments() { DataSourceSelectArguments arguments = new DataSourceSelectArguments(); DataSourceView view = GetData(); bool useServerPaging = 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 = _maximumRows; } else { arguments.MaximumRows = -1; } arguments.StartRowIndex = _startRowIndex; } return arguments; } protected virtual void CreateEmptyDataItem() { if (_emptyDataTemplate != null) { _instantiatedEmptyDataTemplate = true; ListViewItem item = CreateItem(ListViewItemType.EmptyItem); AutoIDControl(item); InstantiateEmptyDataTemplate(item); OnItemCreated(new ListViewItemEventArgs(item)); AddControlToContainer(item, this, 0); } } protected virtual ListViewItem CreateEmptyItem() { if (_emptyItemTemplate != null) { ListViewItem emptyItem = CreateItem(ListViewItemType.EmptyItem); AutoIDControl(emptyItem); InstantiateEmptyItemTemplate(emptyItem); OnItemCreated(new ListViewItemEventArgs(emptyItem)); return emptyItem; } return null; } protected virtual ListViewItem CreateInsertItem() { if (InsertItemTemplate == null) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_InsertTemplateRequired, ID)); } ListViewItem item = CreateItem(ListViewItemType.InsertItem); AutoIDControl(item); InstantiateInsertItemTemplate(item); OnItemCreated(new ListViewItemEventArgs(item)); return item; } protected virtual ListViewItem CreateItem(ListViewItemType itemType) { ListViewItem item = new ListViewItem(itemType); if (itemType == ListViewItemType.InsertItem) { _insertItem = item; } return item; } protected virtual ListViewDataItem CreateDataItem(int dataItemIndex, int displayIndex) { return new ListViewDataItem(dataItemIndex, displayIndex); } protected virtual IListCreateItemsWithoutGroups(ListViewPagedDataSource dataSource, bool dataBinding, InsertItemPosition insertPosition, ArrayList keyArray) { // If this is the first time we're creating the control items, we need // to locate the itemPlaceholder container. // If this is a scenario where we are recreating control items, we already // have the cached itemPlaceholder container. if (_noGroupsOriginalIndexOfItemPlaceholderInContainer == -1) { _noGroupsItemPlaceholderContainer = GetPreparedContainerInfo(this, true, out _noGroupsOriginalIndexOfItemPlaceholderInContainer); } // We need to keep track of where we're inserting items and how many items we have // inserted so that if we need to remove them we know what to do. int itemInsertLocation = _noGroupsOriginalIndexOfItemPlaceholderInContainer; List items = new List (); int itemIndex = 0; int dataItemIndex = 0; if (insertPosition == InsertItemPosition.FirstItem) { ListViewItem insertItem = CreateInsertItem(); AddControlToContainer(insertItem, _noGroupsItemPlaceholderContainer, itemInsertLocation); insertItem.DataBind(); itemInsertLocation++; itemIndex++; } // Reset the selected index if we have a persisted datakey so we // can figure out what index to select based on the key ResetPersistedSelectedIndex(); foreach (object o in dataSource) { if (itemIndex != 0 && _itemSeparatorTemplate != null) { ListViewContainer itemSeparatorContainer = new ListViewContainer(); AutoIDControl(itemSeparatorContainer); InstantiateItemSeparatorTemplate(itemSeparatorContainer); AddControlToContainer(itemSeparatorContainer, _noGroupsItemPlaceholderContainer, itemInsertLocation); itemInsertLocation++; } ListViewDataItem item = CreateDataItem(dataItemIndex + dataSource.StartRowIndex, dataItemIndex); AutoIDControl(item); if (dataBinding) { item.DataItem = o; OrderedDictionary keyTable = new OrderedDictionary(DataKeyNamesInternal.Length); foreach (string keyName in DataKeyNamesInternal) { object keyValue = DataBinder.GetPropertyValue(o, keyName); keyTable.Add(keyName, keyValue); } if (keyArray.Count == dataItemIndex) { keyArray.Add(new DataKey(keyTable, DataKeyNamesInternal)); } else { keyArray[dataItemIndex] = new DataKey(keyTable, DataKeyNamesInternal); } } // If persisted selection is enabled and we have a data key then compare it to get the selected index if (EnablePersistedSelection) { if (dataItemIndex < keyArray.Count) { DataKey currentKey = (DataKey)keyArray[dataItemIndex]; SetPersistedDataKey(dataItemIndex, currentKey); } } InstantiateItemTemplate(item, dataItemIndex); OnItemCreated(new ListViewItemEventArgs(item)); AddControlToContainer(item, _noGroupsItemPlaceholderContainer, itemInsertLocation); itemInsertLocation++; items.Add(item); if (dataBinding) { item.DataBind(); OnItemDataBound(new ListViewItemEventArgs(item)); item.DataItem = null; } dataItemIndex++; itemIndex++; } if (insertPosition == InsertItemPosition.LastItem) { if (_itemSeparatorTemplate != null) { ListViewContainer itemSeparatorContainer = new ListViewContainer(); AutoIDControl(itemSeparatorContainer); InstantiateItemSeparatorTemplate(itemSeparatorContainer); AddControlToContainer(itemSeparatorContainer, _noGroupsItemPlaceholderContainer, itemInsertLocation); itemInsertLocation++; } ListViewItem insertItem = CreateInsertItem(); AddControlToContainer(insertItem, _noGroupsItemPlaceholderContainer, itemInsertLocation); insertItem.DataBind(); itemInsertLocation++; itemIndex++; } _noGroupsItemCreatedCount = itemInsertLocation - _noGroupsOriginalIndexOfItemPlaceholderInContainer; return items; } 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; } } protected virtual IList CreateItemsInGroups(ListViewPagedDataSource dataSource, bool dataBinding, InsertItemPosition insertPosition, ArrayList keyArray) { // If this is the first time we're creating the control items, we need // to locate the groupPlaceholder container. // If this is a scenario where we are recreating control items, we already // have the cached groupPlaceholder container. if (_groupsOriginalIndexOfGroupPlaceholderInContainer == -1) { _groupsGroupPlaceholderContainer = GetPreparedContainerInfo(this, false, out _groupsOriginalIndexOfGroupPlaceholderInContainer); } int groupInsertLocation = _groupsOriginalIndexOfGroupPlaceholderInContainer; _groupsItemCreatedCount = 0; int itemInsertLocation = 0; Control itemPlaceholderContainer = null; // Reset the selected index if we have a persisted datakey so we // can figure out what index to select based on the key ResetPersistedSelectedIndex(); List items = new List (); int itemIndex = 0; int dataItemIndex = 0; if (insertPosition == InsertItemPosition.FirstItem) { ListViewContainer groupContainer = new ListViewContainer(); AutoIDControl(groupContainer); InstantiateGroupTemplate(groupContainer); AddControlToContainer(groupContainer, _groupsGroupPlaceholderContainer, groupInsertLocation); groupInsertLocation++; itemPlaceholderContainer = GetPreparedContainerInfo(groupContainer, true, out itemInsertLocation); ListViewItem insertItem = CreateInsertItem(); AddControlToContainer(insertItem, itemPlaceholderContainer, itemInsertLocation); insertItem.DataBind(); itemInsertLocation++; itemIndex++; } foreach (object o in dataSource) { if (itemIndex % _groupItemCount == 0) { if (itemIndex != 0 && _groupSeparatorTemplate != null) { ListViewContainer groupSeparatorContainer = new ListViewContainer(); AutoIDControl(groupSeparatorContainer); InstantiateGroupSeparatorTemplate(groupSeparatorContainer); AddControlToContainer(groupSeparatorContainer, _groupsGroupPlaceholderContainer, groupInsertLocation); groupInsertLocation++; } ListViewContainer groupContainer = new ListViewContainer(); AutoIDControl(groupContainer); InstantiateGroupTemplate(groupContainer); AddControlToContainer(groupContainer, _groupsGroupPlaceholderContainer, groupInsertLocation); groupInsertLocation++; itemPlaceholderContainer = GetPreparedContainerInfo(groupContainer, true, out itemInsertLocation); } ListViewDataItem item = CreateDataItem(dataItemIndex + StartRowIndex, dataItemIndex); if (dataBinding) { item.DataItem = o; OrderedDictionary keyTable = new OrderedDictionary(DataKeyNamesInternal.Length); foreach (string keyName in DataKeyNamesInternal) { object keyValue = DataBinder.GetPropertyValue(o, keyName); keyTable.Add(keyName, keyValue); } if (keyArray.Count == dataItemIndex) { keyArray.Add(new DataKey(keyTable, DataKeyNamesInternal)); } else { keyArray[dataItemIndex] = new DataKey(keyTable, DataKeyNamesInternal); } } // If persisted selection is enabled and we have a data key then compare it to get the selected index if (EnablePersistedSelection) { if (dataItemIndex < keyArray.Count) { DataKey currentKey = (DataKey)keyArray[dataItemIndex]; SetPersistedDataKey(dataItemIndex, currentKey); } } InstantiateItemTemplate(item, dataItemIndex); OnItemCreated(new ListViewItemEventArgs(item)); if (itemIndex % _groupItemCount != 0 && _itemSeparatorTemplate != null) { ListViewContainer itemSeparatorContainer = new ListViewContainer(); InstantiateItemSeparatorTemplate(itemSeparatorContainer); AddControlToContainer(itemSeparatorContainer, itemPlaceholderContainer, itemInsertLocation); itemInsertLocation++; } AddControlToContainer(item, itemPlaceholderContainer, itemInsertLocation); itemInsertLocation++; items.Add(item); if (dataBinding) { item.DataBind(); OnItemDataBound(new ListViewItemEventArgs(item)); item.DataItem = null; } itemIndex++; dataItemIndex++; } if (insertPosition == InsertItemPosition.LastItem) { if (itemIndex % _groupItemCount == 0) { // start a new group if (itemIndex != 0 && _groupSeparatorTemplate != null) { ListViewContainer groupSeparatorContainer = new ListViewContainer(); AutoIDControl(groupSeparatorContainer); InstantiateGroupSeparatorTemplate(groupSeparatorContainer); AddControlToContainer(groupSeparatorContainer, _groupsGroupPlaceholderContainer, groupInsertLocation); groupInsertLocation++; } ListViewContainer groupContainer = new ListViewContainer(); AutoIDControl(groupContainer); InstantiateGroupTemplate(groupContainer); AddControlToContainer(groupContainer, _groupsGroupPlaceholderContainer, groupInsertLocation); groupInsertLocation++; itemPlaceholderContainer = GetPreparedContainerInfo(groupContainer, true, out itemInsertLocation); } // use the existing group if (itemIndex % _groupItemCount != 0 && _itemSeparatorTemplate != null) { ListViewContainer itemSeparatorContainer = new ListViewContainer(); InstantiateItemSeparatorTemplate(itemSeparatorContainer); AddControlToContainer(itemSeparatorContainer, itemPlaceholderContainer, itemInsertLocation); itemInsertLocation++; } ListViewItem insertItem = CreateInsertItem(); AddControlToContainer(insertItem, itemPlaceholderContainer, itemInsertLocation); insertItem.DataBind(); itemInsertLocation++; itemIndex++; } // fill in the rest of the items if there's an emptyItemTemplate if (_emptyItemTemplate != null) { while (itemIndex % _groupItemCount != 0) { if (_itemSeparatorTemplate != null) { ListViewContainer itemSeparatorContainer = new ListViewContainer(); InstantiateItemSeparatorTemplate(itemSeparatorContainer); AddControlToContainer(itemSeparatorContainer, itemPlaceholderContainer, itemInsertLocation); itemInsertLocation++; } ListViewItem emptyItem = CreateEmptyItem(); AddControlToContainer(emptyItem, itemPlaceholderContainer, itemInsertLocation); itemInsertLocation++; itemIndex++; } } _groupsItemCreatedCount = groupInsertLocation - _groupsOriginalIndexOfGroupPlaceholderInContainer; return items; } protected virtual void CreateSuffixArrayList(ListViewPagedDataSource dataSource, ArrayList suffixArray) { int dataItemIndex = 0; foreach (object o in dataSource) { OrderedDictionary suffixTable = new OrderedDictionary(ClientIDRowSuffixInternal.Length); foreach (string suffixName in ClientIDRowSuffixInternal) { object suffixValue = DataBinder.GetPropertyValue(o, suffixName); suffixTable.Add(suffixName, suffixValue); } if (suffixArray.Count == dataItemIndex) { suffixArray.Add(new DataKey(suffixTable, ClientIDRowSuffixInternal)); } else { suffixArray[dataItemIndex] = new DataKey(suffixTable, ClientIDRowSuffixInternal); } dataItemIndex++; } } protected virtual void CreateLayoutTemplate() { // Reset data concerning where things are in the layout template since we're about to recreate it _noGroupsOriginalIndexOfItemPlaceholderInContainer = -1; _noGroupsItemCreatedCount = 0; _noGroupsItemPlaceholderContainer = null; _groupsOriginalIndexOfGroupPlaceholderInContainer = -1; _groupsItemCreatedCount = 0; _groupsGroupPlaceholderContainer = null; Control containerControl = new Control(); if (_layoutTemplate != null) { _layoutTemplate.InstantiateIn(containerControl); Controls.Add(containerControl); } OnLayoutCreated(new EventArgs()); } private ListViewPagedDataSource CreatePagedDataSource() { ListViewPagedDataSource pagedDataSource = new ListViewPagedDataSource(); pagedDataSource.StartRowIndex = _startRowIndex; pagedDataSource.MaximumRows = _maximumRows; pagedDataSource.AllowServerPaging = false; pagedDataSource.TotalRowCount = 0; return pagedDataSource; } private ListViewPagedDataSource CreateServerPagedDataSource(int totalRowCount) { ListViewPagedDataSource pagedDataSource = new ListViewPagedDataSource(); pagedDataSource.StartRowIndex = _startRowIndex; pagedDataSource.MaximumRows = _maximumRows; pagedDataSource.AllowServerPaging = true; pagedDataSource.TotalRowCount = totalRowCount; return pagedDataSource; } public virtual void DeleteItem(int itemIndex) { // 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, itemIndex); } protected virtual void EnsureLayoutTemplate() { if (this.Controls.Count == 0 || _instantiatedEmptyDataTemplate) { Controls.Clear(); CreateLayoutTemplate(); } } public virtual void ExtractItemValues(IOrderedDictionary itemValues, ListViewItem item, bool includePrimaryKey) { if (itemValues == null) { throw new ArgumentNullException("itemValues"); } DataBoundControlHelper.ExtractValuesFromBindableControls(itemValues, item); IBindableTemplate bindableTemplate = null; if (item.ItemType == ListViewItemType.DataItem) { ListViewDataItem dataItem = item as ListViewDataItem; if (dataItem == null) { throw new InvalidOperationException(AtlasWeb.ListView_ItemsNotDataItems); } if (dataItem.DisplayIndex == EditIndex) { bindableTemplate = EditItemTemplate as IBindableTemplate; } else if (dataItem.DisplayIndex == SelectedIndex) { bindableTemplate = SelectedItemTemplate as IBindableTemplate; } else if (dataItem.DisplayIndex % 2 == 1 && AlternatingItemTemplate != null) { bindableTemplate = AlternatingItemTemplate as IBindableTemplate; } else { bindableTemplate = ItemTemplate as IBindableTemplate; } } else if (item.ItemType == ListViewItemType.InsertItem) { if (InsertItemTemplate != null) { bindableTemplate = InsertItemTemplate as IBindableTemplate; } } if (bindableTemplate != null) { OrderedDictionary newValues = new OrderedDictionary(); bool convertEmptyStringToNull = ConvertEmptyStringToNull; foreach (DictionaryEntry entry in bindableTemplate.ExtractValues(item)) { object value = entry.Value; if (convertEmptyStringToNull && value is string && ((string)value).Length == 0) { newValues[entry.Key] = null; } else { newValues[entry.Key] = value; } } foreach (DictionaryEntry entry in newValues) { if (includePrimaryKey || (Array.IndexOf(DataKeyNamesInternal, entry.Key) == -1)) { itemValues[entry.Key] = entry.Value; } } } } [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "ID")] protected virtual Control FindPlaceholder(string containerID, Control container) { return container.FindControl(containerID); } private DataPager FindDataPager(Control control) { foreach (Control c in control.Controls) { DataPager pager = c as DataPager; if (pager != null) { return pager; } } foreach (Control c in control.Controls) { if (c is IPageableItemContainer) { // Exit out if we've ventured into another ListView or pageable container, since that is the likely // target of any embedded pagers. return null; } DataPager pager = FindDataPager(c); if (pager != null) { return pager; } } return null; } private int GetItemIndex(ListViewItem item, string commandArgument) { if (item != null) { ListViewDataItem dataItem = item as ListViewDataItem; if (dataItem != null) { return dataItem.DisplayIndex; } return -1; } return Convert.ToInt32(commandArgument, CultureInfo.InvariantCulture); } private Control GetPreparedContainerInfo(Control outerContainer, bool isItem, out int placeholderIndex) { // This function locates the ItemPlaceholder for a given container and prepares // it for child controls. Strategy: // - Locate ItemPlaceholder // - If it's not found and the user defined a layout template throw // - If it's not found and the user didn't define a layout/group template, add a default placeholder with the placeholder ID // - Store the placeholder's container and the placeholder's location in the container // - Remove the ItemPlaceholder string placeholderID = isItem ? ItemPlaceholderID : GroupPlaceholderID; Control placeholder = FindPlaceholder(placeholderID, outerContainer); if (placeholder == null) { //add a default placeholder if (_layoutTemplate == null) { placeholder = new PlaceHolder(); placeholder.ID = placeholderID; } if (isItem) { //throw if the user defined a layout/group template and didn't specify an item placeholder if ((_layoutTemplate != null) || (_groupTemplate != null)) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_NoItemPlaceholder, ID, ItemPlaceholderID)); } } else { //throw if the user defined a layout template and didn't specify an group placeholder if (_layoutTemplate != null) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_NoGroupPlaceholder, ID, GroupPlaceholderID)); } } Controls.Add(placeholder); } // Save the information about where we found the itemPlaceholder because // in RemoveItems() we need to know where to delete whatever we create. // This only applies to certain usages of this function. Control placeholderContainer = placeholder.Parent; placeholderIndex = placeholderContainer.Controls.IndexOf(placeholder); // Remove the item placeholder since we're going to be // adding real items starting at the index where it used to be. placeholderContainer.Controls.Remove(placeholder); return placeholderContainer; } private void HandleCancel(int itemIndex) { ListViewCancelMode cancelMode = ListViewCancelMode.CancelingInsert; if (itemIndex == EditIndex && itemIndex >= 0) { cancelMode = ListViewCancelMode.CancelingEdit; } else if (itemIndex != -1) { throw new InvalidOperationException(AtlasWeb.ListView_InvalidCancel); } ListViewCancelEventArgs e = new ListViewCancelEventArgs(itemIndex, cancelMode); OnItemCanceling(e); if (e.Cancel) { return; } if (IsBoundUsingDataSourceID) { if (e.CancelMode == ListViewCancelMode.CancelingEdit) { EditIndex = -1; } else { // cancel on an insert is simply "redatabind to clear"? } } RequiresDataBinding = true; } private void HandleDelete(ListViewItem item, int itemIndex) { ListViewDataItem dataItem = item as ListViewDataItem; if (itemIndex < 0 && dataItem == null) { throw new InvalidOperationException(AtlasWeb.ListView_InvalidDelete); } DataSourceView view = null; bool isBoundToDataSourceControl = IsBoundUsingDataSourceID; if (isBoundToDataSourceControl) { view = GetData(); if (view == null) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_NullView, ID)); } } if (item == null && itemIndex < Items.Count) { item = Items[itemIndex]; } ListViewDeleteEventArgs e = new ListViewDeleteEventArgs(itemIndex); if (item != null) { ExtractItemValues(e.Values, item, false/*includePrimaryKey*/); } if (DataKeys.Count > itemIndex) { foreach (DictionaryEntry entry in DataKeys[itemIndex].Values) { e.Keys.Add(entry.Key, entry.Value); if (e.Values.Contains(entry.Key)) { e.Values.Remove(entry.Key); } } } OnItemDeleting(e); if (e.Cancel) { return; } _deletedItemIndex = itemIndex; if (isBoundToDataSourceControl) { _deleteKeys = e.Keys; _deleteValues = e.Values; view.Delete(e.Keys, e.Values, HandleDeleteCallback); } } private bool HandleDeleteCallback(int affectedRows, Exception ex) { ListViewDeletedEventArgs e = new ListViewDeletedEventArgs(affectedRows, ex); e.SetKeys(_deleteKeys); e.SetValues(_deleteValues); OnItemDeleted(e); _deleteKeys = null; _deleteValues = null; if (ex != null && !e.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 selected index if we deleted the last item on the last page. if ((_totalRowCount > 0) && (_deletedItemIndex == SelectedIndex) && (_deletedItemIndex + _startRowIndex == _totalRowCount)) { SelectedIndex--; } } _deletedItemIndex = -1; RequiresDataBinding = true; return true; } private void HandleEdit(int itemIndex) { if (itemIndex < 0) { throw new InvalidOperationException(AtlasWeb.ListView_InvalidEdit); } ListViewEditEventArgs e = new ListViewEditEventArgs(itemIndex); OnItemEditing(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); ListViewCommandEventArgs dce = e as ListViewCommandEventArgs; if (dce != null) { OnItemCommand(dce); handled = true; string command = dce.CommandName; if (String.Equals(command, DataControlCommands.SelectCommandName, StringComparison.OrdinalIgnoreCase)) { HandleSelect(GetItemIndex(dce.Item, (string)dce.CommandArgument)); } else if (String.Equals(command, DataControlCommands.SortCommandName, StringComparison.OrdinalIgnoreCase)) { HandleSort((string)dce.CommandArgument); } else if (String.Equals(command, DataControlCommands.EditCommandName, StringComparison.OrdinalIgnoreCase)) { HandleEdit(GetItemIndex(dce.Item, (string)dce.CommandArgument)); } else if (String.Equals(command, DataControlCommands.CancelCommandName, StringComparison.OrdinalIgnoreCase)) { HandleCancel(GetItemIndex(dce.Item, (string)dce.CommandArgument)); } else if (String.Equals(command, DataControlCommands.UpdateCommandName, StringComparison.OrdinalIgnoreCase)) { HandleUpdate(dce.Item, GetItemIndex(dce.Item, (string)dce.CommandArgument), causesValidation); } else if (String.Equals(command, DataControlCommands.DeleteCommandName, StringComparison.OrdinalIgnoreCase)) { HandleDelete(dce.Item, GetItemIndex(dce.Item, (string)dce.CommandArgument)); } else if (String.Equals(command, DataControlCommands.InsertCommandName, StringComparison.OrdinalIgnoreCase)) { HandleInsert(dce.Item, causesValidation); } else { handled = HandleCommand(dce.Item, GetItemIndex(dce.Item, (string)dce.CommandArgument), command); } } return handled; } private bool HandleCommand(ListViewItem item, int itemIndex, string commandName) { DataSourceView view = null; if (IsBoundUsingDataSourceID) { view = GetData(); if (view == null) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_NullView, ID)); } } else { return false; } if (!view.CanExecute(commandName)) { return false; } ListViewDataItem dataItem = item as ListViewDataItem; if (itemIndex < 0 && dataItem == null) { throw new InvalidOperationException(AtlasWeb.ListView_InvalidCommand); } OrderedDictionary values = new OrderedDictionary(); OrderedDictionary keys = new OrderedDictionary(); if (item != null) { ExtractItemValues(values, item, false /*includePrimaryKey*/); } if (DataKeys.Count > itemIndex) { foreach (DictionaryEntry entry in DataKeys[itemIndex].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 HandleInsert(ListViewItem item, bool causesValidation) { if (item != null && item.ItemType != ListViewItemType.InsertItem) { throw new InvalidOperationException(AtlasWeb.ListView_InvalidInsert); } if (causesValidation && Page != null && !Page.IsValid) { return; } if (item == null) { item = _insertItem; } if (item == null) { throw new InvalidOperationException(AtlasWeb.ListView_NoInsertItem); } DataSourceView view = null; bool isBoundToDataSourceControl = IsBoundUsingDataSourceID; if (isBoundToDataSourceControl) { view = GetData(); if (view == null) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_NullView, ID)); } } ListViewInsertEventArgs e = new ListViewInsertEventArgs(item); ExtractItemValues(e.Values, item, true/*includeKeys*/); OnItemInserting(e); if (e.Cancel) { return; } if (isBoundToDataSourceControl) { _insertValues = e.Values; view.Insert(e.Values, HandleInsertCallback); } } private bool HandleInsertCallback(int affectedRows, Exception ex) { ListViewInsertedEventArgs e = new ListViewInsertedEventArgs(affectedRows, ex); e.SetValues(_insertValues); OnItemInserted(e); _insertValues = null; if (ex != null && !e.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; } e.KeepInInsertMode = true; } if (!e.KeepInInsertMode) { RequiresDataBinding = true; } return true; } private void HandleSelect(int itemIndex) { if (itemIndex < 0) { throw new InvalidOperationException(AtlasWeb.ListView_InvalidSelect); } ListViewSelectEventArgs e = new ListViewSelectEventArgs(itemIndex); OnSelectedIndexChanging(e); if (e.Cancel) { return; } SelectedIndex = e.NewSelectedIndex; OnSelectedIndexChanged(EventArgs.Empty); RequiresDataBinding = true; } private void HandleSort(string sortExpression) { 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) { ListViewSortEventArgs e = new ListViewSortEventArgs(sortExpression, sortDirection); OnSorting(e); if (e.Cancel) { return; } if (IsBoundUsingDataSourceID) { ClearDataKeys(); DataSourceView view = GetData(); if (view == null) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_NullView, ID)); } EditIndex = -1; SortExpressionInternal = e.SortExpression; SortDirectionInternal = e.SortDirection; _startRowIndex = 0; } OnSorted(EventArgs.Empty); RequiresDataBinding = true; } private void HandleUpdate(ListViewItem item, int itemIndex, bool causesValidation) { ListViewDataItem dataItem = item as ListViewDataItem; if (itemIndex < 0 && dataItem == null) { throw new InvalidOperationException(AtlasWeb.ListView_InvalidUpdate); } if (causesValidation && Page != null && !Page.IsValid) { return; } DataSourceView view = null; bool isBoundToDataSourceControl = IsBoundUsingDataSourceID; if (isBoundToDataSourceControl) { view = GetData(); if (view == null) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_NullView, ID)); } } ListViewUpdateEventArgs e = new ListViewUpdateEventArgs(itemIndex); foreach (DictionaryEntry entry in BoundFieldValues) { e.OldValues.Add(entry.Key, entry.Value); } if (DataKeys.Count > itemIndex) { foreach (DictionaryEntry entry in DataKeys[itemIndex].Values) { e.Keys.Add(entry.Key, entry.Value); } } if (dataItem == null && Items.Count > itemIndex) { dataItem = Items[itemIndex]; } if (dataItem != null) { ExtractItemValues(e.NewValues, dataItem, true/*includePrimaryKey*/); } OnItemUpdating(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) { ListViewUpdatedEventArgs e = new ListViewUpdatedEventArgs(affectedRows, ex); e.SetKeys(_updateKeys); e.SetOldValues(_updateOldValues); e.SetNewValues(_updateNewValues); OnItemUpdated(e); _updateKeys = null; _updateOldValues = null; _updateNewValues = null; if (ex != null && !e.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; } e.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 (!e.KeepInEditMode) { EditIndex = -1; RequiresDataBinding = true; } return true; } public virtual void InsertNewItem(bool causesValidation) { ResetModelValidationGroup(causesValidation, String.Empty); HandleInsert(null, causesValidation); } protected virtual void InstantiateEmptyDataTemplate(Control container) { if (_emptyDataTemplate != null) { _emptyDataTemplate.InstantiateIn(container); } } protected virtual void InstantiateEmptyItemTemplate(Control container) { if (_emptyItemTemplate != null) { _emptyItemTemplate.InstantiateIn(container); } } protected virtual void InstantiateGroupTemplate(Control container) { if (_groupTemplate != null) { _groupTemplate.InstantiateIn(container); } } protected virtual void InstantiateGroupSeparatorTemplate(Control container) { if (_groupSeparatorTemplate != null) { _groupSeparatorTemplate.InstantiateIn(container); } } protected virtual void InstantiateInsertItemTemplate(Control container) { if (_insertItemTemplate != null) { _insertItemTemplate.InstantiateIn(container); } } protected virtual void InstantiateItemSeparatorTemplate(Control container) { if (_itemSeparatorTemplate != null) { _itemSeparatorTemplate.InstantiateIn(container); } } protected virtual void InstantiateItemTemplate(Control container, int displayIndex) { ITemplate contentTemplate = _itemTemplate; if (contentTemplate == null) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_ItemTemplateRequired, ID)); } if (displayIndex % 2 == 1 && _alternatingItemTemplate != null) { contentTemplate = _alternatingItemTemplate; } if (displayIndex == _selectedIndex && _selectedItemTemplate != null) { contentTemplate = _selectedItemTemplate; } if (displayIndex == _editIndex && _editItemTemplate != null) { contentTemplate = _editItemTemplate; } contentTemplate.InstantiateIn(container); } 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. _startRowIndex = 0; _maximumRows = -1; _editIndex = -1; _selectedIndex = -1; _groupItemCount = 1; _sortExpression = String.Empty; _sortDirection = SortDirection.Ascending; _dataKeyNames = new string[0]; object[] state = savedState as object[]; if (state != null) { base.LoadControlState(state[0]); if (state[1] != null) { _editIndex = (int)state[1]; } if (state[2] != null) { _selectedIndex = (int)state[2]; } if (state[3] != null) { _groupItemCount = (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) { _totalRowCount = (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]); } if (state[12] != null) { _startRowIndex = (int)state[12]; } if (state[13] != null) { _maximumRows = (int)state[13]; } } else { base.LoadControlState(null); } // DataPager handles the TotalRowCountAvailable event in order to create its pager fields. Normally this // is fired from CreateChildControls, but when ViewState is disabled this is not getting called until after // postback data has been handled. In this case the event will be fired using the control count from the // last request so that the pager fields can be initialized. if (!IsViewStateEnabled) { OnTotalRowCountAvailable(new PageEventArgs(_startRowIndex, _maximumRows, _totalRowCount)); } } 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]); } } } protected override void LoadViewState(object savedState) { if (savedState != null) { object[] state = (object[])savedState; base.LoadViewState(state[0]); if (state[1] != null) { OrderedDictionaryStateHelper.LoadViewState((OrderedDictionary)BoundFieldValues, (ArrayList)state[1]); } } else { base.LoadViewState(savedState); } } 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]); } } } [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "1#")] protected override bool OnBubbleEvent(object source, EventArgs e) { bool causesValidation = false; string validationGroup = String.Empty; ListViewCommandEventArgs commandEventArgs = e as ListViewCommandEventArgs; // todo: rethink this. Should everything in the layout template be bubbled // up as a ListViewCommand? if (commandEventArgs == null && e is CommandEventArgs) { // Use a new EmptyItem ListViewItem here so when HandleEvent tries to parse out the data item index, // the user gets a nice message about how this button should be in a data item. commandEventArgs = new ListViewCommandEventArgs(new ListViewItem(ListViewItemType.EmptyItem), source, (CommandEventArgs)e); } if (commandEventArgs != null) { IButtonControl button = commandEventArgs.CommandSource as IButtonControl; if (button != null) { causesValidation = button.CausesValidation; validationGroup = button.ValidationGroup; } } return HandleEvent(commandEventArgs, causesValidation, validationGroup); } [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] protected internal override void OnInit(EventArgs e) { base.OnInit(e); if (Page != null) { if (DataKeyNames.Length > 0) { Page.RegisterRequiresViewStateEncryption(); } Page.RegisterRequiresControlState(this); } } /// /// [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] protected virtual void OnItemCanceling(ListViewCancelEventArgs e) { EventHandlerRaises the ///event. handler = (EventHandler )Events[EventItemCanceling]; if (handler != null) { handler(this, e); } else { if (IsBoundUsingDataSourceID == false && e.Cancel == false) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_UnhandledEvent, ID, "ItemCanceling")); } } } /// /// [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] protected virtual void OnItemCommand(ListViewCommandEventArgs e) { EventHandlerRaises the ///event. handler = (EventHandler )Events[EventItemCommand]; if (handler != null) { handler(this, e); } } /// /// [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] protected virtual void OnItemCreated(ListViewItemEventArgs e) { EventHandlerRaises the ///event. handler = (EventHandler )Events[EventItemCreated]; if (handler != null) { handler(this, e); } } /// /// [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] protected virtual void OnItemDataBound(ListViewItemEventArgs e) { EventHandlerRaises the ///event. handler = (EventHandler )Events[EventItemDataBound]; if (handler != null) { handler(this, e); } // EventWizardListItemDataBound is a key for an internal event declared on IWizardSideBarListControl, which is // an interface that is meant to provide a facade to make ListView and DataList look the same. This handler // is meant to abstract away the differences between each controls ItemDataBound events. var wizardListHandler = (EventHandler )Events[EventWizardListItemDataBound]; if (wizardListHandler != null) { var item = e.Item; var wizardListEventArgs = new WizardSideBarListControlItemEventArgs(new WizardSideBarListControlItem(item.DataItem, ListItemType.Item, item.DataItemIndex, item)); wizardListHandler(this, wizardListEventArgs); } } /// /// [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] protected virtual void OnItemDeleted(ListViewDeletedEventArgs e) { EventHandlerRaises the ///event. handler = (EventHandler )Events[EventItemDeleted]; if (handler != null) { handler(this, e); } } /// /// [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] protected virtual void OnItemDeleting(ListViewDeleteEventArgs e) { EventHandlerRaises the ///event. handler = (EventHandler )Events[EventItemDeleting]; if (handler != null) { handler(this, e); } else { if (IsBoundUsingDataSourceID == false && e.Cancel == false) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_UnhandledEvent, ID, "ItemDeleting")); } } } /// /// [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] protected virtual void OnItemEditing(ListViewEditEventArgs e) { EventHandlerRaises the ///event. handler = (EventHandler )Events[EventItemEditing]; if (handler != null) { handler(this, e); } else { if (IsBoundUsingDataSourceID == false && e.Cancel == false) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_UnhandledEvent, ID, "ItemEditing")); } } } /// /// [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] protected virtual void OnItemInserted(ListViewInsertedEventArgs e) { EventHandlerRaises the ///event. handler = (EventHandler )Events[EventItemInserted]; if (handler != null) { handler(this, e); } } /// /// [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] protected virtual void OnItemInserting(ListViewInsertEventArgs e) { EventHandlerRaises the ///event. handler = (EventHandler )Events[EventItemInserting]; if (handler != null) { handler(this, e); } else { if (IsBoundUsingDataSourceID == false && e.Cancel == false) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_UnhandledEvent, ID, "ItemInserting")); } } } /// /// [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] protected virtual void OnItemUpdated(ListViewUpdatedEventArgs e) { EventHandlerRaises the ///event. handler = (EventHandler )Events[EventItemUpdated]; if (handler != null) handler(this, e); } /// /// [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] protected virtual void OnItemUpdating(ListViewUpdateEventArgs e) { EventHandlerRaises the ///event. handler = (EventHandler )Events[EventItemUpdating]; if (handler != null) { handler(this, e); } else { if (IsBoundUsingDataSourceID == false && e.Cancel == false) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_UnhandledEvent, ID, "ItemUpdating")); } } } /// /// [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] protected virtual void OnLayoutCreated(EventArgs e) { EventHandler handler = (EventHandler)Events[EventLayoutCreated]; if (handler != null) { handler(this, e); } } ///Raises the ///event. /// [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] protected virtual void OnPagePropertiesChanged(EventArgs e) { EventHandler handler = (EventHandler)Events[EventPagePropertiesChanged]; if (handler != null) { handler(this, e); } } ///Raises the ///event. /// [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] protected virtual void OnPagePropertiesChanging(PagePropertiesChangingEventArgs e) { EventHandlerRaises the ///event. handler = (EventHandler )Events[EventPagePropertiesChanging]; if (handler != null) { handler(this, e); } } /// /// [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] protected virtual void OnTotalRowCountAvailable(PageEventArgs e) { EventHandlerRaises the ///event of a . handler = (EventHandler )Events[EventTotalRowCountAvailable]; if (handler != null) { handler(this, e); } } /// /// [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] protected virtual void OnSelectedIndexChanged(EventArgs e) { EventHandler handler = (EventHandler)Events[EventSelectedIndexChanged]; if (handler != null) { handler(this, e); } } ///Raises the ///event of a . /// [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] protected virtual void OnSelectedIndexChanging(ListViewSelectEventArgs e) { EventHandlerRaises the ///event of a . handler = (EventHandler )Events[EventSelectedIndexChanging]; if (handler != null) { handler(this, e); } else { if (IsBoundUsingDataSourceID == false && e.Cancel == false) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_UnhandledEvent, ID, "SelectedIndexChanging")); } } } /// /// [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] protected virtual void OnSorted(EventArgs e) { EventHandler handler = (EventHandler)Events[EventSorted]; if (handler != null) { handler(this, e); } } ///Raises the ///event of a . /// [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] protected virtual void OnSorting(ListViewSortEventArgs e) { EventHandlerRaises the ///event. handler = (EventHandler )Events[EventSorting]; if (handler != null) { handler(this, e); } else { if (IsBoundUsingDataSourceID == false && e.Cancel == false) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_UnhandledEvent, ID, "Sorting")); } } } private bool PageIsValidAfterModelException() { if (_modelValidationGroup == null) { return true; } Page.Validate(_modelValidationGroup); return Page.IsValid; } /// /// Overriden by DataBoundControl to use its properties to determine the real /// data source that the control should bind to. It then clears the existing /// control hierarchy, and calls createChildControls to create a new control /// hierarchy based on the resolved data source. /// The implementation resolves various data source related properties to /// arrive at the appropriate IEnumerable implementation to use as the real /// data source. /// When resolving data sources, the DataSourceControlID takes highest precedence. /// In this mode, DataMember is used to access the appropriate list from the /// DataControl. /// If DataSourceControlID is not set, the value of the DataSource property is used. /// In this second alternative, DataMember is used to extract the appropriate /// list if the control has been handed an IListSource as a data source. /// protected internal override void PerformDataBinding(IEnumerable data) { base.PerformDataBinding(data); TrackViewState(); int controlCount = CreateChildControls(data, true); ChildControlsCreated = true; ViewState[ItemCountViewStateKey] = controlCount; int editIndex = EditIndex; if (IsBoundUsingDataSourceID && editIndex != -1 && editIndex < Items.Count && IsViewStateEnabled) { BoundFieldValues.Clear(); ExtractItemValues(BoundFieldValues, Items[editIndex], 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(AtlasWeb.ListView_PersistedSelectionRequiresDataKeysNames); } } } protected override void PerformSelect() { if (_performingSelect) { // Guard against databinding twice if we're currently databinding. // This happens when the ListView is nested within a databound control, and the call // To EnsureLayoutTemplate triggers a recursive DataBind. return; } try { _performingSelect = true; // If there is a DataPager in the layout template, we need the ListView's paging properties // to be set before we go to the datasource EnsureLayoutTemplate(); if (DesignMode) { // Try to find a pager that will control the paging on this control. // In design mode, an embedded pager will not have a designer but will // be the runtime control itself. We want the max rows so the ListView // renders with the right page size. DataPager pager = FindDataPager(this); if (pager != null) { _maximumRows = pager.PageSize; } } base.PerformSelect(); } finally { _performingSelect = false; } } protected virtual void RemoveItems() { if (_groupTemplate != null) { // If we're in grouped mode, delete all the items created in CreateItemsInGroups(). if (_groupsItemCreatedCount > 0) { for (int i = 0; i < _groupsItemCreatedCount; i++) { _groupsGroupPlaceholderContainer.Controls.RemoveAt(_groupsOriginalIndexOfGroupPlaceholderInContainer); } _groupsItemCreatedCount = 0; } } else { // If we're not in grouped mode, delete all the items // created in CreateItemsWithoutGroups(). if (_noGroupsItemCreatedCount > 0) { for (int i = 0; i < _noGroupsItemCreatedCount; i++) { _noGroupsItemPlaceholderContainer.Controls.RemoveAt(_noGroupsOriginalIndexOfItemPlaceholderInContainer); } _noGroupsItemCreatedCount = 0; } } _autoIDIndex = 0; } protected internal override void Render(HtmlTextWriter writer) { // Render only the contents. We don't want a rendered span tag around the control. RenderContents(writer); } private void ResetModelValidationGroup(bool causesValidation, string validationGroup) { _modelValidationGroup = null; if (causesValidation) { Page.Validate(validationGroup); if (EnableModelValidation) { _modelValidationGroup = validationGroup; } } } ////// protected internal override object SaveControlState() { object baseState = base.SaveControlState(); if (baseState != null || _startRowIndex > 0 || _maximumRows != -1 || _editIndex != -1 || _selectedIndex != -1 || _groupItemCount != 1 || (_sortExpression != null && _sortExpression.Length != 0) || _sortDirection != SortDirection.Ascending || _totalRowCount != -1 || (_dataKeyNames != null && _dataKeyNames.Length != 0) || (_dataKeysArrayList != null && _dataKeysArrayList.Count > 0)) { object[] state = new object[14]; state[0] = baseState; state[1] = (_editIndex == -1) ? null : (object)_editIndex; state[2] = (_selectedIndex == -1) ? null : (object)_selectedIndex; state[3] = (_groupItemCount == 1) ? null : (object)_groupItemCount; 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] = (_totalRowCount == -1) ? null : (object)_totalRowCount; state[9] = (_persistedDataKey == null) ? null : ((IStateManager)_persistedDataKey).SaveViewState(); state[10] = (_clientIDRowSuffix == null || _clientIDRowSuffix.Length == 0) ? null : (object)_clientIDRowSuffix; state[11] = SaveClientIDRowSuffixDataKeysState(); state[12] = _startRowIndex; state[13] = _maximumRows; 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; } protected override object SaveViewState() { object baseState = base.SaveViewState(); object boundFieldValuesState = (_boundFieldValues != null) ? OrderedDictionaryStateHelper.SaveViewState(_boundFieldValues) : null; object[] state = new object[2]; state[0] = baseState; state[1] = boundFieldValuesState; return state; } 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; } 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 InvalidOperationException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_DataSourceDoesntSupportPaging, DataSourceID)); } private void SetRequiresDataBindingIfInitialized() { if (Initialized) { RequiresDataBinding = true; } } public virtual void Sort(string sortExpression, SortDirection sortDirection) { HandleSort(sortExpression, sortDirection); } public virtual void UpdateItem(int itemIndex, bool causesValidation) { ResetModelValidationGroup(causesValidation, String.Empty); HandleUpdate(null, itemIndex, causesValidation); } #region IPageableItemContainer int IPageableItemContainer.StartRowIndex { get { return StartRowIndex; } } // Overridable version protected virtual int StartRowIndex { get { return _startRowIndex; } } int IPageableItemContainer.MaximumRows { get { return MaximumRows; } } // Overridable version protected virtual int MaximumRows { get { return _maximumRows; } } void IPageableItemContainer.SetPageProperties(int startRowIndex, int maximumRows, bool databind) { SetPageProperties(startRowIndex, maximumRows, databind); } [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "A property already exists. This method does additional work.")] public void SelectItem(int rowIndex) { HandleSelect(rowIndex); } [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "A property already exists. This method does additional work.")] public void SetEditItem(int rowIndex) { HandleEdit(rowIndex); } // Overridable version [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "databind", Justification = "Cannot change to 'dataBind' as would break binary compatibility with legacy code.")] protected virtual void SetPageProperties(int startRowIndex, int maximumRows, bool databind) { if (maximumRows < 1) { throw new ArgumentOutOfRangeException("maximumRows"); } if (startRowIndex < 0) { throw new ArgumentOutOfRangeException("startRowIndex"); } if (_startRowIndex != startRowIndex || _maximumRows != maximumRows) { PagePropertiesChangingEventArgs args = new PagePropertiesChangingEventArgs(startRowIndex, maximumRows); if (databind) { // This event is cancellable, and its properties aren't settable, because changing them would // create a strange disconnect between the pager and the ListView. You have to set // these properties on the pager if you want to change them. This is a notification event. OnPagePropertiesChanging(args); } _startRowIndex = args.StartRowIndex; _maximumRows = args.MaximumRows; if (databind) { OnPagePropertiesChanged(EventArgs.Empty); } } if (databind) { RequiresDataBinding = true; } } [SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Justification = "Unlikely that a derived type would re-implement this event.")] event EventHandlerSaves the control state for those properties that should persist across postbacks /// even when EnableViewState=false. ///IPageableItemContainer.TotalRowCountAvailable { add { Events.AddHandler(EventTotalRowCountAvailable, value); } remove { Events.RemoveHandler(EventTotalRowCountAvailable, value); } } #endregion IPageableItemContainer #region IPersistedSelector implementation 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; } } string IDataBoundControl.DataSourceID { get { return DataSourceID; } set { DataSourceID = value; } } IDataSource IDataBoundControl.DataSourceObject { get { return DataSourceObject; } } object IDataBoundControl.DataSource { get { return DataSource; } set { DataSource = value; } } string[] IDataBoundControl.DataKeyNames { get { return DataKeyNames; } set { DataKeyNames = value; } } string IDataBoundControl.DataMember { get { return DataMember; } set { DataMember = value; } } #endregion #region IWizardSideBarListControl implementation IEnumerable IWizardSideBarListControl.Items { get { return Items; } } event CommandEventHandler IWizardSideBarListControl.ItemCommand { add { ItemCommand += new EventHandler (value); } remove { ItemCommand -= new EventHandler (value); } } event EventHandler IWizardSideBarListControl.ItemDataBound { add { Events.AddHandler(EventWizardListItemDataBound, value); } remove { Events.RemoveHandler(EventWizardListItemDataBound, value); } } #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ExistsInCollection.cs
- DirectoryNotFoundException.cs
- EventLogger.cs
- CLSCompliantAttribute.cs
- Stack.cs
- CharKeyFrameCollection.cs
- InputBuffer.cs
- TextDecoration.cs
- CompilerCollection.cs
- Configuration.cs
- ListViewSortEventArgs.cs
- EndpointInstanceProvider.cs
- QueryStringConverter.cs
- KeySpline.cs
- CompressStream.cs
- ListItemsPage.cs
- FileDataSourceCache.cs
- CookieProtection.cs
- DirtyTextRange.cs
- DoubleLink.cs
- IgnoreSectionHandler.cs
- AttachedPropertyBrowsableForChildrenAttribute.cs
- CultureSpecificStringDictionary.cs
- DbConnectionStringBuilder.cs
- KnownBoxes.cs
- EntityDataSourceDataSelection.cs
- OutputCacheSettingsSection.cs
- SQLInt32Storage.cs
- Helper.cs
- EmbeddedMailObjectsCollection.cs
- SerializerProvider.cs
- SequentialWorkflowRootDesigner.cs
- ValidateNames.cs
- TextServicesDisplayAttribute.cs
- TreeView.cs
- SpecularMaterial.cs
- RepeatBehavior.cs
- EncryptedKey.cs
- StateDesigner.CommentLayoutGlyph.cs
- MailWriter.cs
- Int64Animation.cs
- Span.cs
- FontSizeConverter.cs
- Thread.cs
- ForeignConstraint.cs
- ValidationEventArgs.cs
- CodeArrayIndexerExpression.cs
- LogicalChannelCollection.cs
- TextAnchor.cs
- EditorPart.cs
- ObjectMemberMapping.cs
- OdbcUtils.cs
- Utils.cs
- ApplicationContext.cs
- ClientRolePrincipal.cs
- Profiler.cs
- ValueConversionAttribute.cs
- CatchBlock.cs
- FontSizeConverter.cs
- DateTimeUtil.cs
- LineBreakRecord.cs
- Random.cs
- ValidationEventArgs.cs
- MimeTextImporter.cs
- OuterGlowBitmapEffect.cs
- DiscriminatorMap.cs
- SqlTriggerContext.cs
- COAUTHIDENTITY.cs
- EditableRegion.cs
- FamilyCollection.cs
- TaiwanLunisolarCalendar.cs
- FlatButtonAppearance.cs
- EntityDataSourceEntityTypeFilterConverter.cs
- SmiGettersStream.cs
- LongValidator.cs
- SoapTypeAttribute.cs
- Html32TextWriter.cs
- WrappedIUnknown.cs
- DataSvcMapFileSerializer.cs
- basecomparevalidator.cs
- CompositeControl.cs
- DataBindingsDialog.cs
- BamlCollectionHolder.cs
- AttachedPropertyBrowsableForChildrenAttribute.cs
- DataError.cs
- MaterialGroup.cs
- ControlAdapter.cs
- LineSegment.cs
- PartitionerStatic.cs
- BitmapCodecInfo.cs
- SEHException.cs
- EdmSchemaError.cs
- TypefaceCollection.cs
- MimeBasePart.cs
- SqlTypeConverter.cs
- TypedDataSetSchemaImporterExtension.cs
- TextRunCache.cs
- CallSiteOps.cs
- CapabilitiesAssignment.cs
- TextDecorationCollection.cs