|
//------------------------------------------------------------------------------
// <copyright file="DataList.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
namespace System.Web.UI.WebControls {
using System;
using System.Collections;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Web;
using System.Web.UI;
using System.Web.Util;
/// <devdoc>
/// <para>
/// Creates
/// a control to display a data-bound list.
/// </para>
/// </devdoc>
[
ControlValueProperty("SelectedValue"),
Editor("System.Web.UI.Design.WebControls.DataListComponentEditor, " + AssemblyRef.SystemDesign, typeof(ComponentEditor)),
Designer("System.Web.UI.Design.WebControls.DataListDesigner, " + AssemblyRef.SystemDesign)
]
public class DataList : BaseDataList, INamingContainer, IRepeatInfoUser, IWizardSideBarListControl {
private static readonly object EventItemCreated = new object();
private static readonly object EventItemDataBound = new object();
private static readonly object EventItemCommand = new object();
private static readonly object EventEditCommand = new object();
private static readonly object EventUpdateCommand = new object();
private static readonly object EventCancelCommand = new object();
private static readonly object EventDeleteCommand = new object();
private static readonly object EventWizardListItemDataBound = new object();
/// <devdoc>
/// <para>Specifies the <see langword='Select'/> command. This field is constant.</para>
/// </devdoc>
public const string SelectCommandName = "Select";
/// <devdoc>
/// <para>Specifies the <see langword='Edit'/> command. This field is constant</para>
/// </devdoc>
public const string EditCommandName = "Edit";
/// <devdoc>
/// <para>Specifies the <see langword='Update'/> command. This field is constant</para>
/// </devdoc>
public const string UpdateCommandName = "Update";
/// <devdoc>
/// <para>Specifies the <see langword='Cancel'/> command. This field is constant</para>
/// </devdoc>
public const string CancelCommandName = "Cancel";
/// <devdoc>
/// <para>Specifies the <see langword='Delete'/> command. This field is constant</para>
/// </devdoc>
public const string DeleteCommandName = "Delete";
private TableItemStyle itemStyle;
private TableItemStyle alternatingItemStyle;
private TableItemStyle selectedItemStyle;
private TableItemStyle editItemStyle;
private TableItemStyle separatorStyle;
private TableItemStyle headerStyle;
private TableItemStyle footerStyle;
private ITemplate itemTemplate;
private ITemplate alternatingItemTemplate;
private ITemplate selectedItemTemplate;
private ITemplate editItemTemplate;
private ITemplate separatorTemplate;
private ITemplate headerTemplate;
private ITemplate footerTemplate;
private bool extractTemplateRows;
private ArrayList itemsArray;
private DataListItemCollection itemsCollection;
private int offset;
private int visibleItemCount = -1;
/// <devdoc>
/// <para>
/// Initializes a new instance of the <see cref='System.Web.UI.WebControls.DataList'/> class.
/// </para>
/// </devdoc>
public DataList() {
offset = 0;
visibleItemCount = -1;
}
/// <devdoc>
/// <para>Gets the style properties for alternating items in the <see cref='System.Web.UI.WebControls.DataList'/>. This
/// property is read-only. </para>
/// </devdoc>
[
WebCategory("Styles"),
DefaultValue(null),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
NotifyParentProperty(true),
PersistenceMode(PersistenceMode.InnerProperty),
WebSysDescription(SR.DataList_AlternatingItemStyle)
]
public virtual TableItemStyle AlternatingItemStyle {
get {
if (alternatingItemStyle == null) {
alternatingItemStyle = new TableItemStyle();
if (IsTrackingViewState)
((IStateManager)alternatingItemStyle).TrackViewState();
}
return alternatingItemStyle;
}
}
/// <devdoc>
/// <para>Indicates the template to use for alternating items in the <see cref='System.Web.UI.WebControls.DataList'/>.</para>
/// </devdoc>
[
Browsable(false),
DefaultValue(null),
PersistenceMode(PersistenceMode.InnerProperty),
TemplateContainer(typeof(DataListItem)),
WebSysDescription(SR.DataList_AlternatingItemTemplate)
]
public virtual ITemplate AlternatingItemTemplate {
get {
return alternatingItemTemplate;
}
set {
alternatingItemTemplate = value;
}
}
/// <devdoc>
/// <para>Indicates the ordinal index of the item to be edited.</para>
/// </devdoc>
[
WebCategory("Default"),
DefaultValue(-1),
WebSysDescription(SR.DataList_EditItemIndex)
]
public virtual int EditItemIndex {
get {
object o = ViewState["EditItemIndex"];
if (o != null) {
return (int)o;
}
return -1;
}
set {
if (value < -1) {
throw new ArgumentOutOfRangeException("value");
}
ViewState["EditItemIndex"] = value;
}
}
/// <devdoc>
/// <para>Indicates the style properties of the item to be edited.</para>
/// </devdoc>
[
WebCategory("Styles"),
DefaultValue(null),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
NotifyParentProperty(true),
PersistenceMode(PersistenceMode.InnerProperty),
WebSysDescription(SR.DataList_EditItemStyle)
]
public virtual TableItemStyle EditItemStyle {
get {
if (editItemStyle == null) {
editItemStyle = new TableItemStyle();
if (IsTrackingViewState)
((IStateManager)editItemStyle).TrackViewState();
}
return editItemStyle;
}
}
/// <devdoc>
/// <para>Indicates the template to use for an item set in edit mode within the <see cref='System.Web.UI.WebControls.DataList'/>.</para>
/// </devdoc>
[
Browsable(false),
DefaultValue(null),
PersistenceMode(PersistenceMode.InnerProperty),
TemplateContainer(typeof(DataListItem)),
WebSysDescription(SR.DataList_EditItemTemplate)
]
public virtual ITemplate EditItemTemplate {
get {
return editItemTemplate;
}
set {
editItemTemplate = value;
}
}
/// <devdoc>
/// <para>Indicates whether to extract template rows.</para>
/// </devdoc>
[
WebCategory("Layout"),
DefaultValue(false),
WebSysDescription(SR.DataList_ExtractTemplateRows)
]
public virtual bool ExtractTemplateRows {
get {
object o = ViewState["ExtractTemplateRows"];
if (o != null)
return(bool)o;
return false;
}
set {
ViewState["ExtractTemplateRows"] = value;
}
}
/// <devdoc>
/// <para>Gets the style properties of the footer item.</para>
/// </devdoc>
[
WebCategory("Styles"),
DefaultValue(null),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
NotifyParentProperty(true),
PersistenceMode(PersistenceMode.InnerProperty),
WebSysDescription(SR.DataControls_FooterStyle)
]
public virtual TableItemStyle FooterStyle {
get {
if (footerStyle == null) {
footerStyle = new TableItemStyle();
if (IsTrackingViewState)
((IStateManager)footerStyle).TrackViewState();
}
return footerStyle;
}
}
/// <devdoc>
/// <para> Indicates the template to use for the footer in the <see cref='System.Web.UI.WebControls.DataList'/>.</para>
/// </devdoc>
[
Browsable(false),
DefaultValue(null),
PersistenceMode(PersistenceMode.InnerProperty),
TemplateContainer(typeof(DataListItem)),
WebSysDescription(SR.DataList_FooterTemplate)
]
public virtual ITemplate FooterTemplate {
get {
return footerTemplate;
}
set {
footerTemplate = value;
}
}
/// <devdoc>
/// <para>Indicates a value that specifies the grid line style.</para>
/// </devdoc>
[
DefaultValue(GridLines.None)
]
public override GridLines GridLines {
get {
if (ControlStyleCreated == false) {
return GridLines.None;
}
return ((TableStyle)ControlStyle).GridLines;
}
set {
base.GridLines = value;
}
}
/// <devdoc>
/// <para>Gets the style properties of the header item.</para>
/// </devdoc>
[
WebCategory("Styles"),
DefaultValue(null),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
NotifyParentProperty(true),
PersistenceMode(PersistenceMode.InnerProperty),
WebSysDescription(SR.DataControls_HeaderStyle)
]
public virtual TableItemStyle HeaderStyle {
get {
if (headerStyle == null) {
headerStyle = new TableItemStyle();
if (IsTrackingViewState)
((IStateManager)headerStyle).TrackViewState();
}
return headerStyle;
}
}
/// <devdoc>
/// <para>Indicates the template to use for the header in the <see cref='System.Web.UI.WebControls.DataList'/>.</para>
/// </devdoc>
[
Browsable(false),
DefaultValue(null),
PersistenceMode(PersistenceMode.InnerProperty),
TemplateContainer(typeof(DataListItem)),
WebSysDescription(SR.DataList_HeaderTemplate)
]
public virtual ITemplate HeaderTemplate {
get {
return headerTemplate;
}
set {
headerTemplate = value;
}
}
/// <devdoc>
/// <para>Gets a collection of <see cref='System.Web.UI.WebControls.DataListItem'/> objects representing the individual
/// items within the control.</para>
/// </devdoc>
[
Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
WebSysDescription(SR.DataList_Items)
]
public virtual DataListItemCollection Items {
get {
if (itemsCollection == null) {
if (itemsArray == null) {
EnsureChildControls();
}
if (itemsArray == null) {
itemsArray = new ArrayList();
}
itemsCollection = new DataListItemCollection(itemsArray);
}
return itemsCollection;
}
}
/// <devdoc>
/// <para>Indicates the style properties of the individual items.</para>
/// </devdoc>
[
WebCategory("Styles"),
DefaultValue(null),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
NotifyParentProperty(true),
PersistenceMode(PersistenceMode.InnerProperty),
WebSysDescription(SR.DataList_ItemStyle)
]
public virtual TableItemStyle ItemStyle {
get {
if (itemStyle == null) {
itemStyle = new TableItemStyle();
if (IsTrackingViewState)
((IStateManager)itemStyle).TrackViewState();
}
return itemStyle;
}
}
/// <devdoc>
/// <para>Indicates the template to use for an item in the <see cref='System.Web.UI.WebControls.DataList'/>.</para>
/// </devdoc>
[
Browsable(false),
DefaultValue(null),
PersistenceMode(PersistenceMode.InnerProperty),
TemplateContainer(typeof(DataListItem)),
WebSysDescription(SR.DataList_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;
}
}
/// <devdoc>
/// <para>Indicates the number of columns to repeat.</para>
/// </devdoc>
[
WebCategory("Layout"),
DefaultValue(0),
WebSysDescription(SR.DataList_RepeatColumns)
]
public virtual int RepeatColumns {
get {
object o = ViewState["RepeatColumns"];
if (o != null)
return(int)o;
return 0;
}
set {
if (value < 0) {
throw new ArgumentOutOfRangeException("value");
}
ViewState["RepeatColumns"] = value;
}
}
/// <devdoc>
/// <para>Indicates whether the control is displayed vertically or horizontally.</para>
/// </devdoc>
[
WebCategory("Layout"),
DefaultValue(RepeatDirection.Vertical),
WebSysDescription(SR.Item_RepeatDirection)
]
public virtual RepeatDirection RepeatDirection {
get {
object o = ViewState["RepeatDirection"];
if (o != null)
return(RepeatDirection)o;
return RepeatDirection.Vertical;
}
set {
if (value < RepeatDirection.Horizontal || value > RepeatDirection.Vertical) {
throw new ArgumentOutOfRangeException("value");
}
ViewState["RepeatDirection"] = value;
}
}
/// <devdoc>
/// <para>Gets or sets a value that indicates whether the control is displayed in table
/// or flow layout.</para>
/// </devdoc>
[
WebCategory("Layout"),
DefaultValue(RepeatLayout.Table),
WebSysDescription(SR.WebControl_RepeatLayout)
]
public virtual RepeatLayout RepeatLayout {
get {
object o = ViewState["RepeatLayout"];
if (o != null)
return(RepeatLayout)o;
return RepeatLayout.Table;
}
set {
if ((value == RepeatLayout.UnorderedList) ||
(value == RepeatLayout.OrderedList)) {
throw new ArgumentOutOfRangeException("value", SR.GetString(SR.DataList_LayoutNotSupported, value));
}
EnumerationRangeValidationUtil.ValidateRepeatLayout(value);
ViewState["RepeatLayout"] = value;
}
}
/// <devdoc>
/// <para> Indicates the index of
/// the currently selected item.</para>
/// </devdoc>
[
Bindable(true),
DefaultValue(-1),
WebSysDescription(SR.WebControl_SelectedIndex),
SuppressMessage("Microsoft.Security", "CA2119:SealMethodsThatSatisfyPrivateInterfaces",
Justification = "Interface denotes existence of property, not used for security.")
]
public virtual int SelectedIndex {
get {
object o = ViewState["SelectedIndex"];
if (o != null) {
return (int)o;
}
return -1;
}
set {
if (value < -1) {
throw new ArgumentOutOfRangeException("value");
}
int oldSelectedIndex = SelectedIndex;
ViewState["SelectedIndex"] = value;
if (itemsArray != null) {
DataListItem item;
if ((oldSelectedIndex != -1) && (itemsArray.Count > oldSelectedIndex)) {
item = (DataListItem)itemsArray[oldSelectedIndex];
if (item.ItemType != ListItemType.EditItem) {
ListItemType itemType = ListItemType.Item;
if (oldSelectedIndex % 2 != 0)
itemType = ListItemType.AlternatingItem;
item.SetItemType(itemType);
}
}
if ((value != -1) && (itemsArray.Count > value)) {
item = (DataListItem)itemsArray[value];
if (item.ItemType != ListItemType.EditItem)
item.SetItemType(ListItemType.SelectedItem);
}
}
}
}
/// <devdoc>
/// <para>Gets the selected item in the <see cref='System.Web.UI.WebControls.DataGrid'/>.</para>
/// </devdoc>
[
Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
WebSysDescription(SR.DataList_SelectedItem)
]
public virtual DataListItem SelectedItem {
get {
int index = SelectedIndex;
DataListItem item = null;
if (index != -1) {
item = Items[index];
}
return item;
}
}
/// <devdoc>
/// <para>Indicates the style properties of the currently
/// selected item.</para>
/// </devdoc>
[
WebCategory("Styles"),
DefaultValue(null),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
NotifyParentProperty(true),
PersistenceMode(PersistenceMode.InnerProperty),
WebSysDescription(SR.DataList_SelectedItemStyle)
]
public virtual TableItemStyle SelectedItemStyle {
get {
if (selectedItemStyle == null) {
selectedItemStyle = new TableItemStyle();
if (IsTrackingViewState)
((IStateManager)selectedItemStyle).TrackViewState();
}
return selectedItemStyle;
}
}
/// <devdoc>
/// <para>Indicates the template to use for the currently selected item in the <see cref='System.Web.UI.WebControls.DataList'/>.</para>
/// </devdoc>
[
Browsable(false),
DefaultValue(null),
PersistenceMode(PersistenceMode.InnerProperty),
TemplateContainer(typeof(DataListItem)),
WebSysDescription(SR.DataList_SelectedItemTemplate)
]
public virtual ITemplate SelectedItemTemplate {
get {
return selectedItemTemplate;
}
set {
selectedItemTemplate = value;
}
}
[
Browsable(false)
]
public object SelectedValue {
get {
if (DataKeyField.Length == 0) {
throw new InvalidOperationException(SR.GetString(SR.DataList_DataKeyFieldMustBeSpecified, ID));
}
DataKeyCollection keys = DataKeys;
int selectedIndex = SelectedIndex;
if (keys != null && selectedIndex < keys.Count && selectedIndex > -1) {
return keys[selectedIndex];
}
return null;
}
}
/// <devdoc>
/// <para>Indicates the style properties of the separator between each item in the
/// <see cref='System.Web.UI.WebControls.DataList'/>.</para>
/// </devdoc>
[
WebCategory("Styles"),
DefaultValue(null),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
NotifyParentProperty(true),
PersistenceMode(PersistenceMode.InnerProperty),
WebSysDescription(SR.DataList_SeparatorStyle)
]
public virtual TableItemStyle SeparatorStyle {
get {
if (separatorStyle == null) {
separatorStyle = new TableItemStyle();
if (IsTrackingViewState)
((IStateManager)separatorStyle).TrackViewState();
}
return separatorStyle;
}
}
/// <devdoc>
/// <para>Indicates the template to use for the separator in the <see cref='System.Web.UI.WebControls.DataList'/>.</para>
/// </devdoc>
[
Browsable(false),
DefaultValue(null),
PersistenceMode(PersistenceMode.InnerProperty),
TemplateContainer(typeof(DataListItem)),
WebSysDescription(SR.DataList_SeparatorTemplate)
]
public virtual ITemplate SeparatorTemplate {
get {
return separatorTemplate;
}
set {
separatorTemplate = value;
}
}
/// <devdoc>
/// <para>Gets or sets a value that specifies whether the footer is displayed in the
/// <see cref='System.Web.UI.WebControls.DataList'/>.</para>
/// </devdoc>
[
WebCategory("Appearance"),
DefaultValue(true),
WebSysDescription(SR.DataControls_ShowFooter)
]
public virtual bool ShowFooter {
get {
object o = ViewState["ShowFooter"];
if (o != null)
return(bool)o;
return true;
}
set {
ViewState["ShowFooter"] = value;
}
}
/// <devdoc>
/// <para>Gets or sets a value that specifies whether the header is displayed in the<see cref='System.Web.UI.WebControls.DataGrid'/>.</para>
/// </devdoc>
[
WebCategory("Appearance"),
DefaultValue(true),
WebSysDescription(SR.DataControls_ShowHeader)
]
public virtual bool ShowHeader {
get {
object o = ViewState["ShowHeader"];
if (o != null)
return(bool)o;
return true;
}
set {
ViewState["ShowHeader"] = value;
}
}
protected override HtmlTextWriterTag TagKey {
get {
return RepeatLayout == RepeatLayout.Table?
HtmlTextWriterTag.Table : HtmlTextWriterTag.Span;
}
}
/// <devdoc>
/// <para>Occurs when a control bubbles an event to the <see cref='System.Web.UI.WebControls.DataList'/> with a
/// <see langword='Command'/> property of <see langword='cancel'/>.</para>
/// </devdoc>
[
WebCategory("Action"),
WebSysDescription(SR.DataList_OnCancelCommand)
]
public event DataListCommandEventHandler CancelCommand {
add {
Events.AddHandler(EventCancelCommand, value);
}
remove {
Events.RemoveHandler(EventCancelCommand, value);
}
}
/// <devdoc>
/// <para>Occurs when a control bubbles an event to the <see cref='System.Web.UI.WebControls.DataList'/> with a
/// <see langword='Command'/> property of <see langword='delete'/>.</para>
/// </devdoc>
[
WebCategory("Action"),
WebSysDescription(SR.DataList_OnDeleteCommand)
]
public event DataListCommandEventHandler DeleteCommand {
add {
Events.AddHandler(EventDeleteCommand, value);
}
remove {
Events.RemoveHandler(EventDeleteCommand, value);
}
}
/// <devdoc>
/// <para>Occurs when a control bubbles an event to the <see cref='System.Web.UI.WebControls.DataList'/> with a
/// <see langword='Command'/> property of <see langword='edit'/>.</para>
/// </devdoc>
[
WebCategory("Action"),
WebSysDescription(SR.DataList_OnEditCommand)
]
public event DataListCommandEventHandler EditCommand {
add {
Events.AddHandler(EventEditCommand, value);
}
remove {
Events.RemoveHandler(EventEditCommand, value);
}
}
/// <devdoc>
/// <para>Occurs when a control bubbles an event to the <see cref='System.Web.UI.WebControls.DataList'/> not covered by
/// <see langword='edit'/>, <see langword='cancel'/>, <see langword='delete'/> or
/// <see langword='update'/>.</para>
/// </devdoc>
[
WebCategory("Action"),
WebSysDescription(SR.DataList_OnItemCommand)
]
public event DataListCommandEventHandler ItemCommand {
add {
Events.AddHandler(EventItemCommand, value);
}
remove {
Events.RemoveHandler(EventItemCommand, value);
}
}
/// <devdoc>
/// <para>Occurs on the server when a control a created.</para>
/// </devdoc>
[
WebCategory("Behavior"),
WebSysDescription(SR.DataControls_OnItemCreated)
]
public event DataListItemEventHandler 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>
[
WebCategory("Behavior"),
WebSysDescription(SR.DataControls_OnItemDataBound)
]
public event DataListItemEventHandler 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.DataList'/> with a
/// <see langword='Command'/> property of <see langword='update'/>.</para>
/// </devdoc>
[
WebCategory("Action"),
WebSysDescription(SR.DataList_OnUpdateCommand)
]
public event DataListCommandEventHandler UpdateCommand {
add {
Events.AddHandler(EventUpdateCommand, value);
}
remove {
Events.RemoveHandler(EventUpdateCommand, value);
}
}
/// <internalonly/>
/// <devdoc>
/// </devdoc>
protected override void CreateControlHierarchy(bool useDataSource) {
IEnumerable dataSource = null;
int count = -1;
ArrayList keysArray = DataKeysArray;
// cache this, so we don't need to go to the statebag each time
extractTemplateRows = this.ExtractTemplateRows;
if (itemsArray != null) {
itemsArray.Clear();
}
else {
itemsArray = new ArrayList();
}
if (useDataSource == false) {
// ViewState must have a non-null value for ItemCount because we check for
// this in CreateChildControls
count = (int)ViewState[BaseDataList.ItemCountViewStateKey];
if (count != -1) {
dataSource = new DummyDataSource(count);
itemsArray.Capacity = count;
}
}
else {
keysArray.Clear();
dataSource = GetData();
ICollection collection = dataSource as ICollection;
if (collection != null) {
keysArray.Capacity = collection.Count;
itemsArray.Capacity = collection.Count;
}
}
if (dataSource != null) {
ControlCollection controls = Controls;
DataListItem item;
ListItemType itemType;
int index = 0;
bool hasSeparators = (separatorTemplate != null);
int editItemIndex = EditItemIndex;
int selectedItemIndex = SelectedIndex;
string keyField = DataKeyField;
bool storeKeys = (useDataSource && (keyField.Length != 0));
count = 0;
if (headerTemplate != null) {
CreateItem(-1, ListItemType.Header, useDataSource, null);
}
foreach (object dataItem in dataSource) {
if (storeKeys) {
object keyValue = DataBinder.GetPropertyValue(dataItem, keyField);
keysArray.Add(keyValue);
}
itemType = ListItemType.Item;
if (index == editItemIndex) {
itemType = ListItemType.EditItem;
}
else if (index == selectedItemIndex) {
itemType = ListItemType.SelectedItem;
}
else if (index % 2 != 0) {
itemType = ListItemType.AlternatingItem;
}
item = CreateItem(index, itemType, useDataSource, dataItem);
itemsArray.Add(item);
if (hasSeparators) {
CreateItem(index, ListItemType.Separator, useDataSource, null);
}
count++;
index++;
}
if (footerTemplate != null) {
CreateItem(-1, ListItemType.Footer, useDataSource, null);
}
}
if (useDataSource) {
// save the number of items contained in the DataList for use in round-trips
ViewState[BaseDataList.ItemCountViewStateKey] = ((dataSource != null) ? count : -1);
}
}
/// <internalonly/>
/// <devdoc>
/// </devdoc>
protected override Style CreateControlStyle() {
TableStyle controlStyle = new TableStyle();
// initialize defaults that are different from TableStyle
controlStyle.CellSpacing = 0;
return controlStyle;
}
/// <devdoc>
/// </devdoc>
private DataListItem CreateItem(int itemIndex, ListItemType itemType, bool dataBind, object dataItem) {
DataListItem item = CreateItem(itemIndex, itemType);
DataListItemEventArgs e = new DataListItemEventArgs(item);
InitializeItem(item);
if (dataBind) {
item.DataItem = dataItem;
}
OnItemCreated(e);
Controls.Add(item);
if (dataBind) {
item.DataBind();
OnItemDataBound(e);
item.DataItem = null;
}
return item;
}
/// <devdoc>
/// </devdoc>
protected virtual DataListItem CreateItem(int itemIndex, ListItemType itemType) {
return new DataListItem(itemIndex, itemType);
}
private DataListItem GetItem(ListItemType itemType, int repeatIndex) {
DataListItem item = null;
switch (itemType) {
case ListItemType.Header:
Debug.Assert(((IRepeatInfoUser)this).HasHeader);
item = (DataListItem)Controls[0];
break;
case ListItemType.Footer:
Debug.Assert(((IRepeatInfoUser)this).HasFooter);
item = (DataListItem)Controls[Controls.Count - 1];
break;
case ListItemType.Separator:
Debug.Assert(((IRepeatInfoUser)this).HasSeparators);
{
int controlIndex = repeatIndex * 2 + 1;
if (headerTemplate != null) {
controlIndex++;
}
item = (DataListItem)Controls[controlIndex];
}
break;
case ListItemType.Item:
case ListItemType.AlternatingItem:
case ListItemType.SelectedItem:
case ListItemType.EditItem:
item = (DataListItem)itemsArray[repeatIndex];
break;
}
return item;
}
/// <devdoc>
/// </devdoc>
protected virtual void InitializeItem(DataListItem item) {
ITemplate contentTemplate = itemTemplate;
switch (item.ItemType) {
case ListItemType.Header:
contentTemplate = headerTemplate;
break;
case ListItemType.Footer:
contentTemplate = footerTemplate;
break;
case ListItemType.AlternatingItem:
if (alternatingItemTemplate != null) {
contentTemplate = alternatingItemTemplate;
}
break;
case ListItemType.SelectedItem:
if (selectedItemTemplate != null) {
contentTemplate = selectedItemTemplate;
}
else {
if (item.ItemIndex % 2 != 0)
goto case ListItemType.AlternatingItem;
}
break;
case ListItemType.EditItem:
if (editItemTemplate != null) {
contentTemplate = editItemTemplate;
}
else {
if (item.ItemIndex == SelectedIndex)
goto case ListItemType.SelectedItem;
else if (item.ItemIndex % 2 != 0)
goto case ListItemType.AlternatingItem;
}
break;
case ListItemType.Separator:
contentTemplate = separatorTemplate;
break;
}
if (contentTemplate != null)
contentTemplate.InstantiateIn(item);
}
/// <internalonly/>
/// <devdoc>
/// </devdoc>
protected override void LoadViewState(object savedState) {
if (savedState != null) {
object[] myState = (object[])savedState;
if (myState[0] != null)
base.LoadViewState(myState[0]);
if (myState[1] != null)
((IStateManager)ItemStyle).LoadViewState(myState[1]);
if (myState[2] != null)
((IStateManager)SelectedItemStyle).LoadViewState(myState[2]);
if (myState[3] != null)
((IStateManager)AlternatingItemStyle).LoadViewState(myState[3]);
if (myState[4] != null)
((IStateManager)EditItemStyle).LoadViewState(myState[4]);
if (myState[5] != null)
((IStateManager)SeparatorStyle).LoadViewState(myState[5]);
if (myState[6] != null)
((IStateManager)HeaderStyle).LoadViewState(myState[6]);
if (myState[7] != null)
((IStateManager)FooterStyle).LoadViewState(myState[7]);
if (myState[8] != null)
((IStateManager)ControlStyle).LoadViewState(myState[8]);
}
}
/// <internalonly/>
/// <devdoc>
/// </devdoc>
protected override bool OnBubbleEvent(object source, EventArgs e) {
bool handled = false;
if (e is DataListCommandEventArgs) {
DataListCommandEventArgs dce = (DataListCommandEventArgs)e;
OnItemCommand(dce);
handled = true;
string command = dce.CommandName;
if (StringUtil.EqualsIgnoreCase(command, DataList.SelectCommandName)) {
SelectedIndex = dce.Item.ItemIndex;
OnSelectedIndexChanged(EventArgs.Empty);
}
else if (StringUtil.EqualsIgnoreCase(command, DataList.EditCommandName)) {
OnEditCommand(dce);
}
else if (StringUtil.EqualsIgnoreCase(command, DataList.DeleteCommandName)) {
OnDeleteCommand(dce);
}
else if (StringUtil.EqualsIgnoreCase(command, DataList.UpdateCommandName)) {
OnUpdateCommand(dce);
}
else if (StringUtil.EqualsIgnoreCase(command, DataList.CancelCommandName)) {
OnCancelCommand(dce);
}
}
return handled;
}
/// <devdoc>
/// <para>Raises the <see langword='CancelCommand '/>event.</para>
/// </devdoc>
protected virtual void OnCancelCommand(DataListCommandEventArgs e) {
DataListCommandEventHandler onCancelCommandHandler = (DataListCommandEventHandler)Events[EventCancelCommand];
if (onCancelCommandHandler != null) onCancelCommandHandler(this, e);
}
/// <devdoc>
/// <para>Raises the <see langword='DeleteCommand '/>event.</para>
/// </devdoc>
protected virtual void OnDeleteCommand(DataListCommandEventArgs e) {
DataListCommandEventHandler onDeleteCommandHandler = (DataListCommandEventHandler)Events[EventDeleteCommand];
if (onDeleteCommandHandler != null) onDeleteCommandHandler(this, e);
}
/// <devdoc>
/// <para>Raises the <see langword='EditCommand '/>event.</para>
/// </devdoc>
protected virtual void OnEditCommand(DataListCommandEventArgs e) {
DataListCommandEventHandler onEditCommandHandler = (DataListCommandEventHandler)Events[EventEditCommand];
if (onEditCommandHandler != null) onEditCommandHandler(this, e);
}
/// <devdoc>
/// DataList initialization.
/// </devdoc>
protected internal override void OnInit(EventArgs e) {
base.OnInit(e);
if (Page != null && DataKeyField.Length > 0) {
Page.RegisterRequiresViewStateEncryption();
}
}
/// <devdoc>
/// <para>Raises the <see langword='ItemCommand '/>event.</para>
/// </devdoc>
protected virtual void OnItemCommand(DataListCommandEventArgs e) {
DataListCommandEventHandler onItemCommandHandler = (DataListCommandEventHandler)Events[EventItemCommand];
if (onItemCommandHandler != null) onItemCommandHandler(this, e);
}
/// <devdoc>
/// <para>Raises the <see langword='ItemCreated '/>event.</para>
/// </devdoc>
protected virtual void OnItemCreated(DataListItemEventArgs e) {
DataListItemEventHandler onItemCreatedHandler = (DataListItemEventHandler)Events[EventItemCreated];
if (onItemCreatedHandler != null) onItemCreatedHandler(this, e);
}
/// <devdoc>
/// <para>Raises the <see langword='ItemDataBound '/>event.</para>
/// </devdoc>
protected virtual void OnItemDataBound(DataListItemEventArgs e) {
DataListItemEventHandler onItemDataBoundHandler = (DataListItemEventHandler)Events[EventItemDataBound];
if (onItemDataBoundHandler != null) onItemDataBoundHandler(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 onWizardListItemDataBoundHandler = (EventHandler<WizardSideBarListControlItemEventArgs>)Events[EventWizardListItemDataBound];
if (onWizardListItemDataBoundHandler != null) {
var item = e.Item;
var wizardListEventArgs = new WizardSideBarListControlItemEventArgs(new WizardSideBarListControlItem(item.DataItem, item.ItemType, item.ItemIndex, item));
onWizardListItemDataBoundHandler(this, wizardListEventArgs);
}
}
/// <devdoc>
/// <para>Raises the <see langword='UpdateCommand '/>event.</para>
/// </devdoc>
protected virtual void OnUpdateCommand(DataListCommandEventArgs e) {
DataListCommandEventHandler onUpdateCommandHandler = (DataListCommandEventHandler)Events[EventUpdateCommand];
if (onUpdateCommandHandler != null) onUpdateCommandHandler(this, e);
}
/// <internalonly/>
/// <devdoc>
/// </devdoc>
protected internal override void PrepareControlHierarchy() {
ControlCollection controls = Controls;
int controlCount = controls.Count;
if (controlCount == 0)
return;
// the composite alternating item style, so we need to do just one
// merge style on the actual item
Style altItemStyle = null;
if (alternatingItemStyle != null) {
altItemStyle = new TableItemStyle();
altItemStyle.CopyFrom(itemStyle);
altItemStyle.CopyFrom(alternatingItemStyle);
}
else {
altItemStyle = itemStyle;
}
Style compositeStyle;
for (int i = 0; i < controlCount; i++) {
DataListItem item = (DataListItem)controls[i];
compositeStyle = null;
switch (item.ItemType) {
case ListItemType.Header:
if (ShowHeader)
compositeStyle = headerStyle;
break;
case ListItemType.Footer:
if (ShowFooter)
compositeStyle = footerStyle;
break;
case ListItemType.Separator:
compositeStyle = separatorStyle;
break;
case ListItemType.Item:
compositeStyle = itemStyle;
break;
case ListItemType.AlternatingItem:
compositeStyle = altItemStyle;
break;
case ListItemType.SelectedItem:
// When creating the control hierarchy we first check if the
// item is in edit mode, so we know this item cannot be in edit
// mode. The only special characteristic of this item is that
// it is selected.
{
compositeStyle = new TableItemStyle();
if (item.ItemIndex % 2 != 0)
compositeStyle.CopyFrom(altItemStyle);
else
compositeStyle.CopyFrom(itemStyle);
compositeStyle.CopyFrom(selectedItemStyle);
}
break;
case ListItemType.EditItem:
// When creating the control hierarchy, we first check if the
// item is in edit mode. So an item may be selected too, and
// so both editItemStyle (more specific) and selectedItemStyle
// are applied.
{
compositeStyle = new TableItemStyle();
if (item.ItemIndex % 2 != 0)
compositeStyle.CopyFrom(altItemStyle);
else
compositeStyle.CopyFrom(itemStyle);
if (item.ItemIndex == SelectedIndex)
compositeStyle.CopyFrom(selectedItemStyle);
compositeStyle.CopyFrom(editItemStyle);
}
break;
}
if (compositeStyle != null) {
// use the cached value of ExtractTemplateRows as it was at the time of
// control creation, so we don't do the wrong thing even if the
// user happened to change the property
if (extractTemplateRows == false) {
item.MergeStyle(compositeStyle);
}
else {
// apply the style on the TRs
IEnumerator controlEnum = item.Controls.GetEnumerator();
while (controlEnum.MoveNext()) {
Control c = (Control)controlEnum.Current;
if (c is Table) {
IEnumerator rowEnum = ((Table)c).Rows.GetEnumerator();
while (rowEnum.MoveNext()) {
//
((TableRow)rowEnum.Current).MergeStyle(compositeStyle);
}
break;
}
}
}
}
}
}
/// <internalonly/>
/// <devdoc>
/// </devdoc>
protected internal override void RenderContents(HtmlTextWriter writer) {
if (Controls.Count == 0)
return;
RepeatInfo repeatInfo = new RepeatInfo();
Table outerTable = null;
// NOTE: This will end up creating the ControlStyle... Ideally we would
// not create the style just for rendering, but turns out our default
// style isn't empty, and does have an effect on rendering, and must
// therefore always be created
Style style = ControlStyle;
if (extractTemplateRows) {
// The table tags in the templates are stripped out and only the
// <tr>'s and <td>'s are assumed to come from the template itself.
// This is equivalent to a flow layout of <tr>'s in a single
// vertical column.
repeatInfo.RepeatDirection = RepeatDirection.Vertical;
repeatInfo.RepeatLayout = RepeatLayout.Flow;
repeatInfo.RepeatColumns = 1;
repeatInfo.OuterTableImplied = true;
outerTable = new Table();
// use ClientID (and not ID) since we want to render the fully qualified
// ID even though the control will not be parented to the control hierarchy
outerTable.ID = ClientID;
outerTable.CopyBaseAttributes(this);
outerTable.Caption = Caption;
outerTable.CaptionAlign = CaptionAlign;
outerTable.ApplyStyle(style);
outerTable.RenderBeginTag(writer);
}
else {
repeatInfo.RepeatDirection = RepeatDirection;
repeatInfo.RepeatLayout = RepeatLayout;
repeatInfo.RepeatColumns = RepeatColumns;
if (repeatInfo.RepeatLayout == RepeatLayout.Table) {
repeatInfo.Caption = Caption;
repeatInfo.CaptionAlign = CaptionAlign;
repeatInfo.UseAccessibleHeader = UseAccessibleHeader;
}
else {
repeatInfo.EnableLegacyRendering = EnableLegacyRendering;
}
}
repeatInfo.RenderRepeater(writer, (IRepeatInfoUser)this, style, this);
if (outerTable != null)
outerTable.RenderEndTag(writer);
}
/// <internalonly/>
/// <devdoc>
/// </devdoc>
protected override object SaveViewState() {
object baseState = base.SaveViewState();
object itemStyleState = (itemStyle != null) ? ((IStateManager)itemStyle).SaveViewState() : null;
object selectedItemStyleState = (selectedItemStyle != null) ? ((IStateManager)selectedItemStyle).SaveViewState() : null;
object alternatingItemStyleState = (alternatingItemStyle != null) ? ((IStateManager)alternatingItemStyle).SaveViewState() : null;
object editItemStyleState = (editItemStyle != null) ? ((IStateManager)editItemStyle).SaveViewState() : null;
object separatorStyleState = (separatorStyle != null) ? ((IStateManager)separatorStyle).SaveViewState() : null;
object headerStyleState = (headerStyle != null) ? ((IStateManager)headerStyle).SaveViewState() : null;
object footerStyleState = (footerStyle != null) ? ((IStateManager)footerStyle).SaveViewState() : null;
object controlState = ControlStyleCreated ? ((IStateManager)ControlStyle).SaveViewState() : null;
object[] myState = new object[9];
myState[0] = baseState;
myState[1] = itemStyleState;
myState[2] = selectedItemStyleState;
myState[3] = alternatingItemStyleState;
myState[4] = editItemStyleState;
myState[5] = separatorStyleState;
myState[6] = headerStyleState;
myState[7] = footerStyleState;
myState[8] = controlState;
// note that we always have some state, atleast the ItemCount
return myState;
}
/// <internalonly/>
/// <devdoc>
/// <para>Marks the starting point to begin tracking and saving changes to the
/// control as part of the control viewstate.</para>
/// </devdoc>
protected override void TrackViewState() {
base.TrackViewState();
if (itemStyle != null)
((IStateManager)itemStyle).TrackViewState();
if (selectedItemStyle != null)
((IStateManager)selectedItemStyle).TrackViewState();
if (alternatingItemStyle != null)
((IStateManager)alternatingItemStyle).TrackViewState();
if (editItemStyle != null)
((IStateManager)editItemStyle).TrackViewState();
if (separatorStyle != null)
((IStateManager)separatorStyle).TrackViewState();
if (headerStyle != null)
((IStateManager)headerStyle).TrackViewState();
if (footerStyle != null)
((IStateManager)footerStyle).TrackViewState();
if (ControlStyleCreated)
((IStateManager)ControlStyle).TrackViewState();
}
/// <internalonly/>
/// <devdoc>
/// </devdoc>
bool IRepeatInfoUser.HasFooter {
get {
return ShowFooter && (footerTemplate != null);
}
}
/// <internalonly/>
/// <devdoc>
/// </devdoc>
bool IRepeatInfoUser.HasHeader {
get {
return ShowHeader && (headerTemplate != null);
}
}
/// <internalonly/>
/// <devdoc>
/// </devdoc>
bool IRepeatInfoUser.HasSeparators {
get {
return (separatorTemplate != null);
}
}
/// <internalonly/>
/// <devdoc>
/// </devdoc>
int IRepeatInfoUser.RepeatedItemCount {
get {
if (visibleItemCount == -1) {
return itemsArray != null ? itemsArray.Count : 0;
}
return visibleItemCount;
}
}
/// <internalonly/>
/// <devdoc>
/// </devdoc>
Style IRepeatInfoUser.GetItemStyle(ListItemType itemType, int repeatIndex) {
DataListItem item = GetItem(itemType, repeatIndex);
if ((item != null) && item.ControlStyleCreated) {
return item.ControlStyle;
}
return null;
}
/// <internalonly/>
/// <devdoc>
/// </devdoc>
void IRepeatInfoUser.RenderItem(ListItemType itemType, int repeatIndex, RepeatInfo repeatInfo, HtmlTextWriter writer) {
DataListItem item = GetItem(itemType, repeatIndex + offset);
if (item != null) {
item.RenderItem(writer, extractTemplateRows, repeatInfo.RepeatLayout == RepeatLayout.Table);
}
}
#region IWizardSideBarListControl implementation
IEnumerable IWizardSideBarListControl.Items {
get { return Items; }
}
event CommandEventHandler IWizardSideBarListControl.ItemCommand {
add {
ItemCommand += new DataListCommandEventHandler(value);
}
remove {
ItemCommand -= new DataListCommandEventHandler(value);
}
}
event EventHandler<WizardSideBarListControlItemEventArgs> IWizardSideBarListControl.ItemDataBound {
add {
Events.AddHandler(EventWizardListItemDataBound , value);
}
remove {
Events.RemoveHandler(EventWizardListItemDataBound, value);
}
}
#endregion
}
}
|