ListView.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / 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; 
            }
        } 
 
        /// 
        ///    Gets or sets the property that determines whether the control treats empty string as 
        ///    null when the item values are extracted.
        /// 
        [
        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); 
            }
        } 

        /// 
        /// 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 IList Items {
            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); 
            } 
        }
 
        /// 
        /// Occurs when a control bubbles an event to the  with a
        /// .
        ///  
        [
        Category("Action"), 
        ResourceDescription("ListView_OnItemDeleted") 
        ]
        public event EventHandler ItemDeleted { 
            add {
                Events.AddHandler(EventItemDeleted, value);
            }
            remove { 
                Events.RemoveHandler(EventItemDeleted, value);
            } 
        } 

        ///  
        /// Occurs when a control bubbles an event to the  with a
        /// .
        /// 
        [ 
        Category("Action"),
        ResourceDescription("ListView_OnItemInserted") 
        ] 
        public event EventHandler ItemInserted {
            add { 
                Events.AddHandler(EventItemInserted, value);
            }
            remove {
                Events.RemoveHandler(EventItemInserted, value); 
            }
        } 
 
        /// 
        /// Occurs when a control bubbles an event to the  with a 
        /// .
        /// 
        [
        Category("Action"), 
        ResourceDescription("ListView_OnItemUpdated")
        ] 
        public event EventHandler ItemUpdated { 
            add {
                Events.AddHandler(EventItemUpdated, value); 
            }
            remove {
                Events.RemoveHandler(EventItemUpdated, value);
            } 
        }
 
        ///  
        /// Occurs when a control bubbles an event to the  with a
        ///  property of 
        /// .
        /// 
        [
        Category("Action"), 
        ResourceDescription("ListView_OnItemCanceling")
        ] 
        public event EventHandler ItemCanceling { 
            add {
                Events.AddHandler(EventItemCanceling, value); 
            }
            remove {
                Events.RemoveHandler(EventItemCanceling, value);
            } 
        }
 
        /// Occurs when a control bubbles an event to the  not covered by 
        /// , ,  or
        /// . 
        /// 
        [
        Category("Action"),
        ResourceDescription("ListView_OnItemCommand") 
        ]
        public event EventHandler ItemCommand { 
            add { 
                Events.AddHandler(EventItemCommand, value);
            } 
            remove {
                Events.RemoveHandler(EventItemCommand, value);
            }
        } 

        ///  
        ///    Occurs on the server when a control a created. 
        /// 
        [ 
        Category("Behavior"),
        ResourceDescription("ListView_OnItemCreated")
        ]
        public event EventHandler ItemCreated { 
            add {
                Events.AddHandler(EventItemCreated, value); 
            } 
            remove {
                Events.RemoveHandler(EventItemCreated, value); 
            }
        }

        ///  
        ///    Occurs when an Item is data bound to the control.
        ///  
        [ 
        Category("Data"),
        ResourceDescription("ListView_OnItemDataBound") 
        ]
        public event EventHandler ItemDataBound {
            add {
                Events.AddHandler(EventItemDataBound, value); 
            }
            remove { 
                Events.RemoveHandler(EventItemDataBound, value); 
            }
        } 

        /// 
        /// Occurs when a control bubbles an event to the  with a
        /// . 
        /// 
        [ 
        Category("Action"), 
        ResourceDescription("ListView_OnItemDeleting")
        ] 
        public event EventHandler ItemDeleting {
            add {
                Events.AddHandler(EventItemDeleting, value);
            } 
            remove {
                Events.RemoveHandler(EventItemDeleting, value); 
            } 
        }
 
        /// 
        /// Occurs when a control bubbles an event to the  with a
        ///  property of
        /// . 
        /// 
        [ 
        Category("Action"), 
        ResourceDescription("ListView_OnItemEditing")
        ] 
        public event EventHandler ItemEditing {
            add {
                Events.AddHandler(EventItemEditing, value);
            } 
            remove {
                Events.RemoveHandler(EventItemEditing, value); 
            } 
        }
 
        /// 
        /// Occurs when a control bubbles an event to the  with a
        /// .
        ///  
        [
        Category("Action"), 
        ResourceDescription("ListView_OnItemInserting") 
        ]
        public event EventHandler ItemInserting { 
            add {
                Events.AddHandler(EventItemInserting, value);
            }
            remove { 
                Events.RemoveHandler(EventItemInserting, value);
            } 
        } 

        ///  
        /// Occurs when a control bubbles an event to the  with a
        /// .
        /// 
        [ 
        Category("Action"),
        ResourceDescription("ListView_OnItemUpdating") 
        ] 
        public event EventHandler ItemUpdating {
            add { 
                Events.AddHandler(EventItemUpdating, value);
            }
            remove {
                Events.RemoveHandler(EventItemUpdating, value); 
            }
        } 
 
        /// 
        /// Occurs on the server when a control layout is created. 
        /// 
        [
        Category("Behavior"),
        ResourceDescription("ListView_OnLayoutCreated") 
        ]
        public event EventHandler LayoutCreated { 
            add { 
                Events.AddHandler(EventLayoutCreated, value);
            } 
            remove {
                Events.RemoveHandler(EventLayoutCreated, value);
            }
        } 

        ///  
        /// Occurs on the server when the page properties have changed. 
        /// 
        [ 
        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 are changing.
        ///  
        [ 
        Category("Behavior"),
        ResourceDescription("ListView_OnPagePropertiesChanging") 
        ]
        public event EventHandler PagePropertiesChanging {
            add {
                Events.AddHandler(EventPagePropertiesChanging, value); 
            }
            remove { 
                Events.RemoveHandler(EventPagePropertiesChanging, value); 
            }
        } 

        /// 
        ///    Occurs when an Item on the list is selected.
        ///  
        [
        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 EventHandler SelectedIndexChanging { 
            add {
                Events.AddHandler(EventSelectedIndexChanging, value); 
            }
            remove {
                Events.RemoveHandler(EventSelectedIndexChanging, value);
            } 
        }
 
        ///  
        ///    Occurs when a field is sorted.
        ///  
        [
        Category("Action"),
        ResourceDescription("ListView_OnSorted")
        ] 
        public event EventHandler Sorted {
            add { 
                Events.AddHandler(EventSorted, value); 
            }
            remove { 
                Events.RemoveHandler(EventSorted, value);
            }
        }
 
        /// 
        ///    Occurs when a field is sorting. 
        ///  
        [
        Category("Action"), 
        ResourceDescription("ListView_OnSorting")
        ]
        public event EventHandler 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 IList CreateItemsWithoutGroups(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); 
            } 
        }
 
        /// 
        /// Raises the event.
        /// 
        [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] 
        protected virtual void OnItemCanceling(ListViewCancelEventArgs e) {
            EventHandler 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"));
                } 
            }
        } 
 
        /// 
        /// Raises the  event. 
        /// 
        [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")]
        protected virtual void OnItemCommand(ListViewCommandEventArgs e) {
            EventHandler handler = (EventHandler)Events[EventItemCommand]; 
            if (handler != null) {
                handler(this, e); 
            } 
        }
 
        /// 
        /// Raises the  event.
        /// 
        [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] 
        protected virtual void OnItemCreated(ListViewItemEventArgs e) {
            EventHandler handler = (EventHandler)Events[EventItemCreated]; 
            if (handler != null) { 
                handler(this, e);
            } 
        }

        /// 
        /// Raises the  event. 
        /// 
        [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] 
        protected virtual void OnItemDataBound(ListViewItemEventArgs e) { 
            EventHandler 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);
            }
        } 

        ///  
        /// Raises the event. 
        /// 
        [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] 
        protected virtual void OnItemDeleted(ListViewDeletedEventArgs e) {
            EventHandler handler = (EventHandler)Events[EventItemDeleted];
            if (handler != null) {
                handler(this, e); 
            }
        } 
 
        /// 
        /// Raises the  event. 
        /// 
        [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")]
        protected virtual void OnItemDeleting(ListViewDeleteEventArgs e) {
            EventHandler 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"));
                }
            }
        } 

        ///  
        /// Raises the  event. 
        /// 
        [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] 
        protected virtual void OnItemEditing(ListViewEditEventArgs e) {
            EventHandler 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"));
                } 
            }
        }

        ///  
        /// Raises the event.
        ///  
        [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] 
        protected virtual void OnItemInserted(ListViewInsertedEventArgs e) {
            EventHandler handler = (EventHandler)Events[EventItemInserted]; 
            if (handler != null) {
                handler(this, e);
            }
        } 

        ///  
        /// Raises the  event. 
        /// 
        [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] 
        protected virtual void OnItemInserting(ListViewInsertEventArgs e) {
            EventHandler 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"));
                } 
            }
        }

        ///  
        /// Raises the event.
        ///  
        [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] 
        protected virtual void OnItemUpdated(ListViewUpdatedEventArgs e) {
            EventHandler handler = (EventHandler)Events[EventItemUpdated]; 
            if (handler != null) handler(this, e);
        }

        ///  
        /// Raises the  event.
        ///  
        [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] 
        protected virtual void OnItemUpdating(ListViewUpdateEventArgs e) {
            EventHandler 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")); 
                } 
            }
        } 

        /// 
        /// Raises the  event.
        ///  
        [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) {
            EventHandler handler = (EventHandler)Events[EventPagePropertiesChanging];
            if (handler != null) {
                handler(this, e); 
            }
        } 
 
        /// 
        /// Raises the event of a . 
        /// 
        [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")]
        protected virtual void OnTotalRowCountAvailable(PageEventArgs e) {
            EventHandler handler = (EventHandler)Events[EventTotalRowCountAvailable]; 
            if (handler != null) {
                handler(this, e); 
            } 
        }
 
        /// 
        /// Raises the event of a .
        /// 
        [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) { 
            EventHandler 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"));
                } 
            } 
        }
 
        /// 
        /// Raises the event of a .
        /// 
        [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. 
        /// 
        [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] 
        protected virtual void OnSorting(ListViewSortEventArgs e) { 
            EventHandler 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; 
                } 
            }
        } 

        /// 
        /// Saves the control state for those properties that should persist across postbacks
        ///   even when EnableViewState=false. 
        /// 
        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 EventHandler 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

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK