You've already forked linux-packaging-mono
3526 lines
138 KiB
C#
3526 lines
138 KiB
C#
![]() |
//------------------------------------------------------------------------------
|
||
|
// <copyright file="ListView.cs" company="Microsoft">
|
||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||
|
// </copyright>
|
||
|
//------------------------------------------------------------------------------
|
||
|
|
||
|
using System.Collections;
|
||
|
using System.Collections.Generic;
|
||
|
using System.Collections.Specialized;
|
||
|
using System.ComponentModel;
|
||
|
using System.Diagnostics.CodeAnalysis;
|
||
|
using System.Drawing;
|
||
|
using System.Drawing.Design;
|
||
|
using System.Globalization;
|
||
|
using System.Web.Resources;
|
||
|
using System.Web.UI.HtmlControls;
|
||
|
using System.Web.Util;
|
||
|
|
||
|
|
||
|
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<ListViewDataItem> _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;
|
||
|
|
||
|
private string _updateMethod;
|
||
|
private string _insertMethod;
|
||
|
private string _deleteMethod;
|
||
|
|
||
|
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;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <devdoc>
|
||
|
/// <para>Gets or sets the property that determines whether the control treats empty string as
|
||
|
/// null when the item values are extracted.</para>
|
||
|
/// </devdoc>
|
||
|
[
|
||
|
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);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <devdoc>
|
||
|
/// An array of ordered dictionaries that represents each key
|
||
|
/// </devdoc>
|
||
|
private ArrayList DataKeysArrayList {
|
||
|
get {
|
||
|
if (_dataKeysArrayList == null) {
|
||
|
_dataKeysArrayList = new ArrayList();
|
||
|
}
|
||
|
return _dataKeysArrayList;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private ArrayList ClientIDRowSuffixArrayList {
|
||
|
get {
|
||
|
if (_clientIDRowSuffixArrayList == null) {
|
||
|
_clientIDRowSuffixArrayList = new ArrayList();
|
||
|
}
|
||
|
return _clientIDRowSuffixArrayList;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[
|
||
|
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<ListViewDataItem> Items {
|
||
|
get {
|
||
|
if (_itemList == null) {
|
||
|
_itemList = new List<ListViewDataItem>();
|
||
|
}
|
||
|
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;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Internal member for setting sort direction
|
||
|
/// </summary>
|
||
|
private SortDirection SortDirectionInternal {
|
||
|
get {
|
||
|
return _sortDirection;
|
||
|
}
|
||
|
set {
|
||
|
if (value < SortDirection.Ascending || value > SortDirection.Descending) {
|
||
|
throw new ArgumentOutOfRangeException("value");
|
||
|
}
|
||
|
if (_sortDirection != value) {
|
||
|
_sortDirection = value;
|
||
|
SetRequiresDataBindingIfInitialized();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Gets a value that specifies the current column being sorted on in the
|
||
|
/// <see cref='System.Web.UI.WebControls.GridView'/>.
|
||
|
/// </summary>
|
||
|
[
|
||
|
Browsable(false),
|
||
|
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
|
||
|
ResourceDescription("ListView_SortExpression"),
|
||
|
ResourceCategory("Sorting"),
|
||
|
]
|
||
|
public virtual string SortExpression {
|
||
|
get {
|
||
|
return SortExpressionInternal;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Internal member for setting sort expression
|
||
|
/// </summary>
|
||
|
private string SortExpressionInternal {
|
||
|
get {
|
||
|
return _sortExpression;
|
||
|
}
|
||
|
set {
|
||
|
if (_sortExpression != value) {
|
||
|
_sortExpression = value;
|
||
|
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);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <devdoc>
|
||
|
/// <para>Occurs when a control bubbles an event to the <see cref='System.Web.UI.WebControls.ListView'/> with a
|
||
|
/// <see langword='delete'/>.</para>
|
||
|
/// </devdoc>
|
||
|
[
|
||
|
Category("Action"),
|
||
|
ResourceDescription("ListView_OnItemDeleted")
|
||
|
]
|
||
|
public event EventHandler<ListViewDeletedEventArgs> ItemDeleted {
|
||
|
add {
|
||
|
Events.AddHandler(EventItemDeleted, value);
|
||
|
}
|
||
|
remove {
|
||
|
Events.RemoveHandler(EventItemDeleted, value);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <devdoc>
|
||
|
/// <para>Occurs when a control bubbles an event to the <see cref='System.Web.UI.WebControls.ListView'/> with a
|
||
|
/// <see langword='insert'/>.</para>
|
||
|
/// </devdoc>
|
||
|
[
|
||
|
Category("Action"),
|
||
|
ResourceDescription("ListView_OnItemInserted")
|
||
|
]
|
||
|
public event EventHandler<ListViewInsertedEventArgs> ItemInserted {
|
||
|
add {
|
||
|
Events.AddHandler(EventItemInserted, value);
|
||
|
}
|
||
|
remove {
|
||
|
Events.RemoveHandler(EventItemInserted, value);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <devdoc>
|
||
|
/// <para>Occurs when a control bubbles an event to the <see cref='System.Web.UI.WebControls.ListView'/> with a
|
||
|
/// <see langword='update'/>.</para>
|
||
|
/// </devdoc>
|
||
|
[
|
||
|
Category("Action"),
|
||
|
ResourceDescription("ListView_OnItemUpdated")
|
||
|
]
|
||
|
public event EventHandler<ListViewUpdatedEventArgs> ItemUpdated {
|
||
|
add {
|
||
|
Events.AddHandler(EventItemUpdated, value);
|
||
|
}
|
||
|
remove {
|
||
|
Events.RemoveHandler(EventItemUpdated, value);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <devdoc>
|
||
|
/// <para>Occurs when a control bubbles an event to the <see cref='System.Web.UI.WebControls.ListView'/> with a
|
||
|
/// <see langword='Command'/> property of
|
||
|
/// <see langword='cancel'/>.</para>
|
||
|
/// </devdoc>
|
||
|
[
|
||
|
Category("Action"),
|
||
|
ResourceDescription("ListView_OnItemCanceling")
|
||
|
]
|
||
|
public event EventHandler<ListViewCancelEventArgs> ItemCanceling {
|
||
|
add {
|
||
|
Events.AddHandler(EventItemCanceling, value);
|
||
|
}
|
||
|
remove {
|
||
|
Events.RemoveHandler(EventItemCanceling, value);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <para>Occurs when a control bubbles an event to the <see cref='System.Web.UI.WebControls.ListView'/> not covered by
|
||
|
/// <see langword='edit'/>, <see langword='cancel'/>, <see langword='delete'/> or
|
||
|
/// <see langword='update'/>.</para>
|
||
|
/// </devdoc>
|
||
|
[
|
||
|
Category("Action"),
|
||
|
ResourceDescription("ListView_OnItemCommand")
|
||
|
]
|
||
|
public event EventHandler<ListViewCommandEventArgs> ItemCommand {
|
||
|
add {
|
||
|
Events.AddHandler(EventItemCommand, value);
|
||
|
}
|
||
|
remove {
|
||
|
Events.RemoveHandler(EventItemCommand, value);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <devdoc>
|
||
|
/// <para>Occurs on the server when a control a created.</para>
|
||
|
/// </devdoc>
|
||
|
[
|
||
|
Category("Behavior"),
|
||
|
ResourceDescription("ListView_OnItemCreated")
|
||
|
]
|
||
|
public event EventHandler<ListViewItemEventArgs> ItemCreated {
|
||
|
add {
|
||
|
Events.AddHandler(EventItemCreated, value);
|
||
|
}
|
||
|
remove {
|
||
|
Events.RemoveHandler(EventItemCreated, value);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <devdoc>
|
||
|
/// <para>Occurs when an Item is data bound to the control.</para>
|
||
|
/// </devdoc>
|
||
|
[
|
||
|
Category("Data"),
|
||
|
ResourceDescription("ListView_OnItemDataBound")
|
||
|
]
|
||
|
public event EventHandler<ListViewItemEventArgs> ItemDataBound {
|
||
|
add {
|
||
|
Events.AddHandler(EventItemDataBound, value);
|
||
|
}
|
||
|
remove {
|
||
|
Events.RemoveHandler(EventItemDataBound, value);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <devdoc>
|
||
|
/// <para>Occurs when a control bubbles an event to the <see cref='System.Web.UI.WebControls.ListView'/> with a
|
||
|
/// <see langword='delete'/>.</para>
|
||
|
/// </devdoc>
|
||
|
[
|
||
|
Category("Action"),
|
||
|
ResourceDescription("ListView_OnItemDeleting")
|
||
|
]
|
||
|
public event EventHandler<ListViewDeleteEventArgs> ItemDeleting {
|
||
|
add {
|
||
|
Events.AddHandler(EventItemDeleting, value);
|
||
|
}
|
||
|
remove {
|
||
|
Events.RemoveHandler(EventItemDeleting, value);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <devdoc>
|
||
|
/// <para>Occurs when a control bubbles an event to the <see cref='System.Web.UI.WebControls.ListView'/> with a
|
||
|
/// <see langword='Command'/> property of
|
||
|
/// <see langword='edit'/>.</para>
|
||
|
/// </devdoc>
|
||
|
[
|
||
|
Category("Action"),
|
||
|
ResourceDescription("ListView_OnItemEditing")
|
||
|
]
|
||
|
public event EventHandler<ListViewEditEventArgs> ItemEditing {
|
||
|
add {
|
||
|
Events.AddHandler(EventItemEditing, value);
|
||
|
}
|
||
|
remove {
|
||
|
Events.RemoveHandler(EventItemEditing, value);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <devdoc>
|
||
|
/// <para>Occurs when a control bubbles an event to the <see cref='System.Web.UI.WebControls.ListView'/> with a
|
||
|
/// <see langword='insert'/>.</para>
|
||
|
/// </devdoc>
|
||
|
[
|
||
|
Category("Action"),
|
||
|
ResourceDescription("ListView_OnItemInserting")
|
||
|
]
|
||
|
public event EventHandler<ListViewInsertEventArgs> ItemInserting {
|
||
|
add {
|
||
|
Events.AddHandler(EventItemInserting, value);
|
||
|
}
|
||
|
remove {
|
||
|
Events.RemoveHandler(EventItemInserting, value);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <devdoc>
|
||
|
/// <para>Occurs when a control bubbles an event to the <see cref='System.Web.UI.WebControls.ListView'/> with a
|
||
|
/// <see langword='update'/>.</para>
|
||
|
/// </devdoc>
|
||
|
[
|
||
|
Category("Action"),
|
||
|
ResourceDescription("ListView_OnItemUpdating")
|
||
|
]
|
||
|
public event EventHandler<ListViewUpdateEventArgs> ItemUpdating {
|
||
|
add {
|
||
|
Events.AddHandler(EventItemUpdating, value);
|
||
|
}
|
||
|
remove {
|
||
|
Events.RemoveHandler(EventItemUpdating, value);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <devdoc>
|
||
|
/// <para>Occurs on the server when a control layout is created.</para>
|
||
|
/// </devdoc>
|
||
|
[
|
||
|
Category("Behavior"),
|
||
|
ResourceDescription("ListView_OnLayoutCreated")
|
||
|
]
|
||
|
public event EventHandler LayoutCreated {
|
||
|
add {
|
||
|
Events.AddHandler(EventLayoutCreated, value);
|
||
|
}
|
||
|
remove {
|
||
|
Events.RemoveHandler(EventLayoutCreated, value);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <devdoc>
|
||
|
/// <para>Occurs on the server when the page properties have changed.</para>
|
||
|
/// </devdoc>
|
||
|
[
|
||
|
Category("Behavior"),
|
||
|
ResourceDescription("ListView_OnPagePropertiesChanged")
|
||
|
]
|
||
|
public event EventHandler PagePropertiesChanged {
|
||
|
add {
|
||
|
Events.AddHandler(EventPagePropertiesChanged, value);
|
||
|
}
|
||
|
remove {
|
||
|
Events.RemoveHandler(EventPagePropertiesChanged, value);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <devdoc>
|
||
|
/// <para>Occurs on the server when the page properties are changing.</para>
|
||
|
/// </devdoc>
|
||
|
[
|
||
|
Category("Behavior"),
|
||
|
ResourceDescription("ListView_OnPagePropertiesChanging")
|
||
|
]
|
||
|
public event EventHandler<PagePropertiesChangingEventArgs> PagePropertiesChanging {
|
||
|
add {
|
||
|
Events.AddHandler(EventPagePropertiesChanging, value);
|
||
|
}
|
||
|
remove {
|
||
|
Events.RemoveHandler(EventPagePropertiesChanging, value);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <devdoc>
|
||
|
/// <para>Occurs when an Item on the list is selected.</para>
|
||
|
/// </devdoc>
|
||
|
[
|
||
|
Category("Action"),
|
||
|
ResourceDescription("ListView_OnSelectedIndexChanged")
|
||
|
]
|
||
|
public event EventHandler SelectedIndexChanged {
|
||
|
add {
|
||
|
Events.AddHandler(EventSelectedIndexChanged, value);
|
||
|
}
|
||
|
remove {
|
||
|
Events.RemoveHandler(EventSelectedIndexChanged, value);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <devdoc>
|
||
|
/// <para>Occurs when an Item on the list is selected.</para>
|
||
|
/// </devdoc>
|
||
|
[
|
||
|
Category("Action"),
|
||
|
ResourceDescription("ListView_OnSelectedIndexChanging")
|
||
|
]
|
||
|
public event EventHandler<ListViewSelectEventArgs> SelectedIndexChanging {
|
||
|
add {
|
||
|
Events.AddHandler(EventSelectedIndexChanging, value);
|
||
|
}
|
||
|
remove {
|
||
|
Events.RemoveHandler(EventSelectedIndexChanging, value);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <devdoc>
|
||
|
/// <para>Occurs when a field is sorted.</para>
|
||
|
/// </devdoc>
|
||
|
[
|
||
|
Category("Action"),
|
||
|
ResourceDescription("ListView_OnSorted")
|
||
|
]
|
||
|
public event EventHandler Sorted {
|
||
|
add {
|
||
|
Events.AddHandler(EventSorted, value);
|
||
|
}
|
||
|
remove {
|
||
|
Events.RemoveHandler(EventSorted, value);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <devdoc>
|
||
|
/// <para>Occurs when a field is sorting.</para>
|
||
|
/// </devdoc>
|
||
|
[
|
||
|
Category("Action"),
|
||
|
ResourceDescription("ListView_OnSorting")
|
||
|
]
|
||
|
public event EventHandler<ListViewSortEventArgs> Sorting {
|
||
|
add {
|
||
|
Events.AddHandler(EventSorting, value);
|
||
|
}
|
||
|
remove {
|
||
|
Events.RemoveHandler(EventSorting, value);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
protected override bool IsUsingModelBinders {
|
||
|
get {
|
||
|
return !String.IsNullOrEmpty(SelectMethod) ||
|
||
|
!String.IsNullOrEmpty(UpdateMethod) ||
|
||
|
!String.IsNullOrEmpty(DeleteMethod) ||
|
||
|
!String.IsNullOrEmpty(InsertMethod);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// The name of the method on the page which is called when this Control does an update operation.
|
||
|
/// </summary>
|
||
|
[
|
||
|
DefaultValue(""),
|
||
|
Themeable(false),
|
||
|
WebCategory("Data"),
|
||
|
WebSysDescription(SR.DataBoundControl_UpdateMethod)
|
||
|
]
|
||
|
public virtual string UpdateMethod {
|
||
|
get {
|
||
|
return _updateMethod ?? String.Empty;
|
||
|
}
|
||
|
set {
|
||
|
if (!String.Equals(_updateMethod, value, StringComparison.OrdinalIgnoreCase)) {
|
||
|
_updateMethod = value;
|
||
|
OnDataPropertyChanged();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// The name of the method on the page which is called when this Control does a delete operation.
|
||
|
/// </summary>
|
||
|
[
|
||
|
DefaultValue(""),
|
||
|
Themeable(false),
|
||
|
WebCategory("Data"),
|
||
|
WebSysDescription(SR.DataBoundControl_DeleteMethod)
|
||
|
]
|
||
|
public virtual string DeleteMethod {
|
||
|
get {
|
||
|
return _deleteMethod ?? String.Empty;
|
||
|
}
|
||
|
set {
|
||
|
if (!String.Equals(_deleteMethod, value, StringComparison.OrdinalIgnoreCase)) {
|
||
|
_deleteMethod = value;
|
||
|
OnDataPropertyChanged();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// The name of the method on the page which is called when this Control does an insert operation.
|
||
|
/// </summary>
|
||
|
[
|
||
|
DefaultValue(""),
|
||
|
Themeable(false),
|
||
|
WebCategory("Data"),
|
||
|
WebSysDescription(SR.DataBoundControl_InsertMethod)
|
||
|
]
|
||
|
public virtual string InsertMethod {
|
||
|
get {
|
||
|
return _insertMethod ?? String.Empty;
|
||
|
}
|
||
|
set {
|
||
|
if (!String.Equals(_insertMethod, value, StringComparison.OrdinalIgnoreCase)) {
|
||
|
_insertMethod = value;
|
||
|
OnDataPropertyChanged();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
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;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// 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.
|
||
|
/// </summary>
|
||
|
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();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// 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.
|
||
|
/// </summary>
|
||
|
/// <param name="dataSource">
|
||
|
/// The data source to be used to enumerate items.
|
||
|
/// </param>
|
||
|
/// <param name="dataBinding">
|
||
|
/// Whether the method has been called from DataBind or not.
|
||
|
/// </param>
|
||
|
/// <returns>
|
||
|
/// The number of items created based on the data source. Put another way, its
|
||
|
/// the number of items enumerated from the data source.
|
||
|
/// </returns>
|
||
|
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<ListViewDataItem> 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<ListViewDataItem> items = new List<ListViewDataItem>();
|
||
|
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<ListViewDataItem> 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<ListViewDataItem> items = new List<ListViewDataItem>();
|
||
|
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 bool TryGetItemIndex(ListViewItem item, string commandArgument, out int itemIndex) {
|
||
|
if (item != null) {
|
||
|
ListViewDataItem dataItem = item as ListViewDataItem;
|
||
|
itemIndex = (dataItem != null) ? dataItem.DisplayIndex : -1;
|
||
|
// HandleCommand will throw detailed exception when item is not data item
|
||
|
return true;
|
||
|
}
|
||
|
return Int32.TryParse(commandArgument, NumberStyles.Integer, CultureInfo.InvariantCulture, out itemIndex);
|
||
|
}
|
||
|
|
||
|
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 (IsDataBindingAutomatic) {
|
||
|
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 = IsDataBindingAutomatic;
|
||
|
|
||
|
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);
|
||
|
if (dce.Handled) {
|
||
|
return true;
|
||
|
}
|
||
|
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 {
|
||
|
int itemIndex;
|
||
|
if (TryGetItemIndex(dce.Item, (string)dce.CommandArgument, out itemIndex)) {
|
||
|
handled = HandleCommand(dce.Item, itemIndex, command);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return handled;
|
||
|
}
|
||
|
|
||
|
private bool HandleCommand(ListViewItem item, int itemIndex, string commandName) {
|
||
|
DataSourceView view = null;
|
||
|
|
||
|
if (IsDataBindingAutomatic) {
|
||
|
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 = IsDataBindingAutomatic;
|
||
|
|
||
|
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 (IsUsingModelBinders && !Page.ModelState.IsValid) {
|
||
|
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 (IsDataBindingAutomatic) {
|
||
|
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 = IsDataBindingAutomatic;
|
||
|
|
||
|
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;
|
||
|
}
|
||
|
|
||
|
if (IsUsingModelBinders && !Page.ModelState.IsValid) {
|
||
|
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);
|
||
|
}
|
||
|
|
||
|
if (!DesignMode && !String.IsNullOrEmpty(ItemType)) {
|
||
|
DataBoundControlHelper.EnableDynamicData(this, ItemType);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <devdoc>
|
||
|
/// <para>Raises the <see langword='CancelCommand '/>event.</para>
|
||
|
/// </devdoc>
|
||
|
[SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")]
|
||
|
protected virtual void OnItemCanceling(ListViewCancelEventArgs e) {
|
||
|
EventHandler<ListViewCancelEventArgs> handler = (EventHandler<ListViewCancelEventArgs>)Events[EventItemCanceling];
|
||
|
if (handler != null) {
|
||
|
handler(this, e);
|
||
|
}
|
||
|
else {
|
||
|
if (IsDataBindingAutomatic == false && e.Cancel == false) {
|
||
|
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_UnhandledEvent, ID, "ItemCanceling"));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <devdoc>
|
||
|
/// <para>Raises the <see langword='ItemCommand'/> event.</para>
|
||
|
/// </devdoc>
|
||
|
[SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")]
|
||
|
protected virtual void OnItemCommand(ListViewCommandEventArgs e) {
|
||
|
EventHandler<ListViewCommandEventArgs> handler = (EventHandler<ListViewCommandEventArgs>)Events[EventItemCommand];
|
||
|
if (handler != null) {
|
||
|
handler(this, e);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <devdoc>
|
||
|
/// <para>Raises the <see langword='ItemCreated'/> event.</para>
|
||
|
/// </devdoc>
|
||
|
[SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")]
|
||
|
protected virtual void OnItemCreated(ListViewItemEventArgs e) {
|
||
|
EventHandler<ListViewItemEventArgs> handler = (EventHandler<ListViewItemEventArgs>)Events[EventItemCreated];
|
||
|
if (handler != null) {
|
||
|
handler(this, e);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <devdoc>
|
||
|
/// <para>Raises the <see langword='ItemDataBound'/> event.</para>
|
||
|
/// </devdoc>
|
||
|
[SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")]
|
||
|
protected virtual void OnItemDataBound(ListViewItemEventArgs e) {
|
||
|
EventHandler<ListViewItemEventArgs> handler = (EventHandler<ListViewItemEventArgs>)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<WizardSideBarListControlItemEventArgs>)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);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <devdoc>
|
||
|
/// <para>Raises the <see langword='ItemDeleted '/>event.</para>
|
||
|
/// </devdoc>
|
||
|
[SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")]
|
||
|
protected virtual void OnItemDeleted(ListViewDeletedEventArgs e) {
|
||
|
EventHandler<ListViewDeletedEventArgs> handler = (EventHandler<ListViewDeletedEventArgs>)Events[EventItemDeleted];
|
||
|
if (handler != null) {
|
||
|
handler(this, e);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <devdoc>
|
||
|
/// <para>Raises the <see langword='Delete'/> event.</para>
|
||
|
/// </devdoc>
|
||
|
[SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")]
|
||
|
protected virtual void OnItemDeleting(ListViewDeleteEventArgs e) {
|
||
|
EventHandler<ListViewDeleteEventArgs> handler = (EventHandler<ListViewDeleteEventArgs>)Events[EventItemDeleting];
|
||
|
if (handler != null) {
|
||
|
handler(this, e);
|
||
|
}
|
||
|
else {
|
||
|
if (IsDataBindingAutomatic == false && e.Cancel == false) {
|
||
|
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_UnhandledEvent, ID, "ItemDeleting"));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <devdoc>
|
||
|
/// <para>Raises the <see langword='EditCommand'/> event.</para>
|
||
|
/// </devdoc>
|
||
|
[SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")]
|
||
|
protected virtual void OnItemEditing(ListViewEditEventArgs e) {
|
||
|
EventHandler<ListViewEditEventArgs> handler = (EventHandler<ListViewEditEventArgs>)Events[EventItemEditing];
|
||
|
if (handler != null) {
|
||
|
handler(this, e);
|
||
|
}
|
||
|
else {
|
||
|
if (IsDataBindingAutomatic == false && e.Cancel == false) {
|
||
|
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_UnhandledEvent, ID, "ItemEditing"));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <devdoc>
|
||
|
/// <para>Raises the <see langword='ItemInserted '/>event.</para>
|
||
|
/// </devdoc>
|
||
|
[SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")]
|
||
|
protected virtual void OnItemInserted(ListViewInsertedEventArgs e) {
|
||
|
EventHandler<ListViewInsertedEventArgs> handler = (EventHandler<ListViewInsertedEventArgs>)Events[EventItemInserted];
|
||
|
if (handler != null) {
|
||
|
handler(this, e);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <devdoc>
|
||
|
/// <para>Raises the <see langword='Delete'/> event.</para>
|
||
|
/// </devdoc>
|
||
|
[SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")]
|
||
|
protected virtual void OnItemInserting(ListViewInsertEventArgs e) {
|
||
|
EventHandler<ListViewInsertEventArgs> handler = (EventHandler<ListViewInsertEventArgs>)Events[EventItemInserting];
|
||
|
if (handler != null) {
|
||
|
handler(this, e);
|
||
|
}
|
||
|
else {
|
||
|
if (IsDataBindingAutomatic == false && e.Cancel == false) {
|
||
|
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_UnhandledEvent, ID, "ItemInserting"));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <devdoc>
|
||
|
/// <para>Raises the <see langword='ItemUpdated '/>event.</para>
|
||
|
/// </devdoc>
|
||
|
[SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")]
|
||
|
protected virtual void OnItemUpdated(ListViewUpdatedEventArgs e) {
|
||
|
EventHandler<ListViewUpdatedEventArgs> handler = (EventHandler<ListViewUpdatedEventArgs>)Events[EventItemUpdated];
|
||
|
if (handler != null) handler(this, e);
|
||
|
}
|
||
|
|
||
|
/// <devdoc>
|
||
|
/// <para>Raises the <see langword='UpdateCommand'/> event.</para>
|
||
|
/// </devdoc>
|
||
|
[SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")]
|
||
|
protected virtual void OnItemUpdating(ListViewUpdateEventArgs e) {
|
||
|
EventHandler<ListViewUpdateEventArgs> handler = (EventHandler<ListViewUpdateEventArgs>)Events[EventItemUpdating];
|
||
|
if (handler != null) {
|
||
|
handler(this, e);
|
||
|
}
|
||
|
else {
|
||
|
if (IsDataBindingAutomatic == false && e.Cancel == false) {
|
||
|
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_UnhandledEvent, ID, "ItemUpdating"));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <devdoc>
|
||
|
/// <para>Raises the <see langword='LayoutCreated'/> event.</para>
|
||
|
/// </devdoc>
|
||
|
[SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")]
|
||
|
protected virtual void OnLayoutCreated(EventArgs e) {
|
||
|
EventHandler handler = (EventHandler)Events[EventLayoutCreated];
|
||
|
if (handler != null) {
|
||
|
handler(this, e);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <devdoc>
|
||
|
/// <para>Raises the <see langword='PagePropertiesChanged'/> event.</para>
|
||
|
/// </devdoc>
|
||
|
[SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")]
|
||
|
protected virtual void OnPagePropertiesChanged(EventArgs e) {
|
||
|
EventHandler handler = (EventHandler)Events[EventPagePropertiesChanged];
|
||
|
if (handler != null) {
|
||
|
handler(this, e);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <devdoc>
|
||
|
/// <para>Raises the <see langword='PagePropertiesChanging'/> event.</para>
|
||
|
/// </devdoc>
|
||
|
[SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")]
|
||
|
protected virtual void OnPagePropertiesChanging(PagePropertiesChangingEventArgs e) {
|
||
|
EventHandler<PagePropertiesChangingEventArgs> handler = (EventHandler<PagePropertiesChangingEventArgs>)Events[EventPagePropertiesChanging];
|
||
|
if (handler != null) {
|
||
|
handler(this, e);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <devdoc>
|
||
|
/// <para>Raises the <see cref='System.Web.UI.WebControls.ListView.TotalRowCountAvailable'/>event of a <see cref='System.Web.UI.WebControls.ListView'/>.</para>
|
||
|
/// </devdoc>
|
||
|
[SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")]
|
||
|
protected virtual void OnTotalRowCountAvailable(PageEventArgs e) {
|
||
|
EventHandler<PageEventArgs> handler = (EventHandler<PageEventArgs>)Events[EventTotalRowCountAvailable];
|
||
|
if (handler != null) {
|
||
|
handler(this, e);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <devdoc>
|
||
|
/// <para>Raises the <see cref='System.Web.UI.WebControls.ListView.SelectedIndexChanged'/>event of a <see cref='System.Web.UI.WebControls.ListView'/>.</para>
|
||
|
/// </devdoc>
|
||
|
[SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")]
|
||
|
protected virtual void OnSelectedIndexChanged(EventArgs e) {
|
||
|
EventHandler handler = (EventHandler)Events[EventSelectedIndexChanged];
|
||
|
if (handler != null) {
|
||
|
handler(this, e);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <devdoc>
|
||
|
/// <para>Raises the <see cref='System.Web.UI.WebControls.ListView.SelectedIndexChanging'/>event of a <see cref='System.Web.UI.WebControls.ListView'/>.</para>
|
||
|
/// </devdoc>
|
||
|
[SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")]
|
||
|
protected virtual void OnSelectedIndexChanging(ListViewSelectEventArgs e) {
|
||
|
EventHandler<ListViewSelectEventArgs> handler = (EventHandler<ListViewSelectEventArgs>)Events[EventSelectedIndexChanging];
|
||
|
if (handler != null) {
|
||
|
handler(this, e);
|
||
|
}
|
||
|
else {
|
||
|
if (IsDataBindingAutomatic == false && e.Cancel == false) {
|
||
|
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ListView_UnhandledEvent, ID, "SelectedIndexChanging"));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <devdoc>
|
||
|
/// <para>Raises the <see cref='System.Web.UI.WebControls.ListView.Sorted'/>event of a <see cref='System.Web.UI.WebControls.ListView'/>.</para>
|
||
|
/// </devdoc>
|
||
|
[SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")]
|
||
|
protected virtual void OnSorted(EventArgs e) {
|
||
|
EventHandler handler = (EventHandler)Events[EventSorted];
|
||
|
if (handler != null) {
|
||
|
handler(this, e);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <devdoc>
|
||
|
/// <para>Raises the <see langword='SortCommand'/> event.</para>
|
||
|
/// </devdoc>
|
||
|
[SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")]
|
||
|
protected virtual void OnSorting(ListViewSortEventArgs e) {
|
||
|
EventHandler<ListViewSortEventArgs> handler = (EventHandler<ListViewSortEventArgs>)Events[EventSorting];
|
||
|
if (handler != null) {
|
||
|
handler(this, e);
|
||
|
}
|
||
|
else {
|
||
|
if (IsDataBindingAutomatic == 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;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// 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.
|
||
|
/// </summary>
|
||
|
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 (IsDataBindingAutomatic && 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;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <devdoc>
|
||
|
/// <para>Saves the control state for those properties that should persist across postbacks
|
||
|
/// even when EnableViewState=false.</para>
|
||
|
/// </devdoc>
|
||
|
protected internal override object SaveControlState() {
|
||
|
object baseState = base.SaveControlState();
|
||
|
if (baseState != null ||
|
||
|
_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);
|
||
|
}
|
||
|
|
||
|
internal override void UpdateModelDataSourceProperties(ModelDataSource modelDataSource) {
|
||
|
Debug.Assert(modelDataSource != null, "A non-null ModelDataSource should be passed in");
|
||
|
string dataKeyName = DataKeyNamesInternal.Length > 0 ? DataKeyNamesInternal[0] : "";
|
||
|
modelDataSource.UpdateProperties(ItemType, SelectMethod, UpdateMethod, InsertMethod, DeleteMethod, dataKeyName);
|
||
|
}
|
||
|
|
||
|
#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<PageEventArgs> 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<ListViewCommandEventArgs>(value);
|
||
|
}
|
||
|
remove {
|
||
|
ItemCommand -= new EventHandler<ListViewCommandEventArgs>(value);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
event EventHandler<WizardSideBarListControlItemEventArgs> IWizardSideBarListControl.ItemDataBound {
|
||
|
add {
|
||
|
Events.AddHandler(EventWizardListItemDataBound, value);
|
||
|
}
|
||
|
remove {
|
||
|
Events.RemoveHandler(EventWizardListItemDataBound, value);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
}
|
||
|
}
|