|
//------------------------------------------------------------------------------
// <copyright file="ObjectList.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing.Design;
using System.Globalization;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Security.Permissions;
namespace System.Web.UI.MobileControls
{
/*
* Object List class.
*
* Copyright (c) 2000 Microsoft Corporation
*/
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList"]/*' />
[
ControlBuilderAttribute(typeof(ObjectListControlBuilder)),
DefaultEvent("ItemCommand"),
DefaultProperty("DataSource"),
Designer(typeof(System.Web.UI.Design.MobileControls.ObjectListDesigner)),
DesignerAdapter(typeof(System.Web.UI.Design.MobileControls.Adapters.DesignerObjectListAdapter)),
Editor(typeof(System.Web.UI.Design.MobileControls.ObjectListComponentEditor), typeof(ComponentEditor)),
ToolboxData("<{0}:ObjectList runat=\"server\" LabelStyle-StyleReference=\"title\" CommandStyle-StyleReference=\"subcommand\"></{0}:ObjectList>"),
ToolboxItem("System.Web.UI.Design.WebControlToolboxItem, " + AssemblyRef.SystemDesign)
]
[AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)]
[AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)]
[Obsolete("The System.Web.Mobile.dll assembly has been deprecated and should no longer be used. For information about how to develop ASP.NET mobile applications, see http://go.microsoft.com/fwlink/?LinkId=157231.")]
public class ObjectList : PagedControl, INamingContainer, ITemplateable, IPostBackEventHandler
{
private static readonly Object EventItemDataBind = new Object();
private static readonly Object EventItemCommand = new Object();
private static readonly Object EventItemSelect = new Object();
private static readonly Object EventShowItemCommands = new Object();
private Object _dataSource;
private IEnumerable _resolvedDataSource;
private ObjectListFieldCollection _fields;
private ObjectListFieldCollection _autoGeneratedFields;
private ObjectListFieldCollection _allFields;
private ObjectListItemCollection _items;
private ObjectListCommandCollection _commands;
private ObjectListCommandCollection _globalCommands;
private int _labelFieldIndex = -1;
private int[] _tableFieldIndices = null;
private IEnumerator _storedEnumerator = null;
private Object _firstDataItem = null;
private bool _storedDataValid = false;
private ObjectListViewMode _viewMode = ObjectListViewMode.List;
private bool _ignoreFieldsItemsViewModeViewState = false;
private Style _commandStyle = null;
private Style _labelStyle = null;
private const string _itemCountViewStateKey = "_!ItemCount";
private int _selectedIndex = -1;
private bool _selectedIndexDirty = false;
private bool _loadingItems = false;
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.SelectMoreCommand"]/*' />
public static String SelectMoreCommand
{
get
{
return "More";
}
}
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.DataSource"]/*' />
[
Bindable(true),
DefaultValue(null),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
MobileCategory(SR.Category_Data),
MobileSysDescription(SR.ObjectList_DataSource)
]
public virtual Object DataSource
{
get
{
return _dataSource;
}
set
{
_dataSource = value;
// _allFields and _resolvedDataSource need to be recalculated.
_allFields = null;
_resolvedDataSource = null;
}
}
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.DataMember"]/*' />
[
Bindable(false),
DefaultValue(""),
MobileCategory(SR.Category_Data),
MobileSysDescription(SR.List_DataMember),
TypeConverter(typeof(System.Web.UI.Design.MobileControls.Converters.DataMemberConverter))
]
public virtual String DataMember
{
get
{
String s = (String)ViewState["DataMember"];
return s == null ? String.Empty : s;
}
set
{
ViewState["DataMember"] = value;
}
}
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.Fields"]/*' />
[
Bindable(false),
DefaultValue(null),
Editor(typeof(System.Web.UI.Design.MobileControls.FieldCollectionEditor), typeof(UITypeEditor)),
MergableProperty(false),
MobileCategory(SR.Category_Data),
MobileSysDescription(SR.ObjectList_Fields),
PersistenceMode(PersistenceMode.InnerDefaultProperty)
]
public virtual ObjectListFieldCollection Fields
{
get
{
if (_fields == null)
{
_fields = new ObjectListFieldCollection(this);
if (IsTrackingViewState)
{
((IStateManager)_fields).TrackViewState();
}
}
return _fields;
}
}
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.Items"]/*' />
[
Bindable(true),
Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
]
public virtual ObjectListItemCollection Items
{
get
{
if (_items == null)
{
_items = new ObjectListItemCollection(this);
if (IsTrackingViewState)
{
((IStateManager)_items).TrackViewState();
}
}
return _items;
}
}
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.Commands"]/*' />
[
Bindable(false),
Editor(typeof(System.Web.UI.Design.MobileControls.CommandCollectionEditor), typeof(UITypeEditor)),
MergableProperty(false),
MobileCategory(SR.Category_Data),
MobileSysDescription(SR.ObjectList_Commands),
PersistenceMode(PersistenceMode.InnerDefaultProperty)
]
public virtual ObjectListCommandCollection Commands
{
get
{
if (_commands == null)
{
_commands = new ObjectListCommandCollection();
if (IsTrackingViewState)
{
((IStateManager)_commands).TrackViewState();
}
}
return _commands;
}
}
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.LabelField"]/*' />
[
DefaultValue(""),
MobileCategory(SR.Category_Data),
MobileSysDescription(SR.ObjectList_LabelField),
TypeConverter(typeof(System.Web.UI.Design.MobileControls.Converters.DataFieldConverter))
]
public String LabelField
{
get
{
String s = (String)ViewState["LabelField"];
return (s != null) ? s : String.Empty;
}
set
{
ViewState["LabelField"] = value;
InvalidateDisplayFieldIndices();
}
}
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.DefaultCommand"]/*' />
[
Bindable(true),
DefaultValue(""),
MobileCategory(SR.Category_Data),
MobileSysDescription(SR.ObjectList_DefaultCommand),
TypeConverter(typeof(System.Web.UI.Design.MobileControls.Converters.DefaultCommandConverter))
]
public String DefaultCommand
{
get
{
String s = (String)ViewState["DefaultCommand"];
return (s != null) ? s : String.Empty;
}
set
{
ViewState["DefaultCommand"] = value;
}
}
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.TableFields"]/*' />
[
Bindable(true),
DefaultValue(""),
Editor(typeof(System.Web.UI.Design.MobileControls.TableFieldsEditor),
typeof(UITypeEditor)),
MobileCategory(SR.Category_Data),
MobileSysDescription(SR.ObjectList_TableFields)
]
public String TableFields
{
get
{
String s = (String)ViewState["TableFields"];
return (s != null) ? s : String.Empty;
}
set
{
ViewState["TableFields"] = value;
InvalidateDisplayFieldIndices();
}
}
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.SelectedIndex"]/*' />
[
Bindable(false),
Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
]
public int SelectedIndex
{
get
{
return _selectedIndex;
}
set
{
if (value == -1 && ViewMode != ObjectListViewMode.List)
{
throw new Exception(
SR.GetString(SR.ObjectList_MustBeInListModeToClearSelectedIndex));
}
int itemCount = ItemCount > 0 ? ItemCount : Items.Count;
if (value < -1)
{
throw new ArgumentOutOfRangeException("SelectedIndex",
SR.GetString(SR.ObjectList_SelectedIndexTooSmall, value));
}
else if (itemCount > 0 && value >= itemCount)
{
throw new ArgumentOutOfRangeException("SelectedIndex",
SR.GetString(SR.ObjectList_SelectedIndexTooBig, value, itemCount));
}
// End of guard clauses.
_selectedIndexDirty = (value != _selectedIndex) && IsTrackingViewState;
DeselectItemIfLoaded(_selectedIndex);
SelectItemIfLoaded(value);
_selectedIndex = value;
}
}
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.Selection"]/*' />
[
Bindable(false),
Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
]
public ObjectListItem Selection
{
get
{
if (SelectedIndex == -1)
{
return null;
}
EnsureItemLoaded (SelectedIndex);
int selectedIndex = TranslateVirtualItemIndex(SelectedIndex);
if (selectedIndex >= 0 && selectedIndex < Items.Count)
{
Debug.Assert (Items[selectedIndex].Selected);
return Items[selectedIndex];
}
else
{
return null;
}
}
}
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.AutoGenerateFields"]/*' />
[
Bindable(false),
Browsable(true),
DefaultValue(true),
MobileCategory(SR.Category_Behavior),
MobileSysDescription(SR.ObjectList_AutoGenerateFields)
]
public bool AutoGenerateFields
{
get
{
Object b = ViewState["AutoGenerateFields"];
return (b != null) ? (bool)b : true;
}
set
{
if (value != AutoGenerateFields)
{
ViewState["AutoGenerateFields"] = value;
_allFields = null;
_autoGeneratedFields = null;
_items = null;
InvalidateDisplayFieldIndices();
}
}
}
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.AllFields"]/*' />
[
Bindable(false),
Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
]
public IObjectListFieldCollection AllFields
{
get
{
if (_allFields == null)
{
if (_autoGeneratedFields == null)
{
if (_fields == null)
{
return null;
}
else
{
_allFields = _fields;
}
}
else
{
if (_fields == null)
{
_allFields = _autoGeneratedFields;
}
else
{
int count = _fields.Count + _autoGeneratedFields.Count;
ArrayList list = new ArrayList(count);
foreach (ObjectListField field in _fields)
{
list.Add(field);
}
foreach (ObjectListField field in _autoGeneratedFields)
{
list.Add(field);
}
_allFields = new ObjectListFieldCollection(this, list);
}
}
}
return _allFields;
}
}
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.LabelFieldIndex"]/*' />
[
Bindable(false),
Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
]
public int LabelFieldIndex
{
get
{
if (_labelFieldIndex == -1)
{
CalculateDisplayFieldIndices();
}
return _labelFieldIndex;
}
}
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.Details"]/*' />
[
Bindable(false),
Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
]
public Panel Details
{
get
{
EnsureChildControls();
if (ViewMode != ObjectListViewMode.Details)
{
throw new Exception(SR.GetString(SR.ObjectList_MustBeInDetailsModeToGetDetails));
}
return Selection;
}
}
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.TableFieldIndices"]/*' />
[
Bindable(false),
Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
]
public int[] TableFieldIndices
{
get
{
if (_labelFieldIndex == -1)
{
CalculateDisplayFieldIndices();
}
Debug.Assert(_tableFieldIndices != null, "_tableFieldIndices is null.");
return _tableFieldIndices;
}
}
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.EnsureTemplatedUI"]/*' />
public override void EnsureTemplatedUI()
{
EnsureChildControls();
}
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.EnsureChildControls"]/*' />
protected override void EnsureChildControls()
{
// if EnsureChildControls is called before items are created (e.g., at
// LoadPrivateViewState), there will be no controls. Need to build child
// controls in this case, so we set ChildControlsCreated to false.
ChildControlsCreated = ChildControlsCreated && Controls.Count > 0;
base.EnsureChildControls();
}
private void CalculateDisplayFieldIndices()
{
String labelField = LabelField;
if (labelField.Length > 0)
{
_labelFieldIndex = GetFieldIndex(labelField);
}
else
{
_labelFieldIndex = 0;
}
String tableFields = TableFields;
int length = tableFields.Length;
// Populate the _tableFieldIndices array.
ArrayList tableFieldIndexList = new ArrayList();
for (int pos = 0; pos < length; )
{
int nextSemicolon = tableFields.IndexOf(';', pos);
String fieldName = (nextSemicolon == -1) ?
tableFields.Substring(pos) :
tableFields.Substring(pos, nextSemicolon - pos);
tableFieldIndexList.Add(GetFieldIndex(fieldName));
pos = nextSemicolon == -1 ? length : nextSemicolon + 1;
}
_tableFieldIndices = (int[])tableFieldIndexList.ToArray(typeof(int));
}
internal void InvalidateDisplayFieldIndices()
{
_labelFieldIndex = -1;
_tableFieldIndices = null;
}
private int GetFieldIndex(String field)
{
int index = AllFields.IndexOf(field);
if (index == -1)
{
throw new ArgumentException(SR.GetString(
SR.ObjectList_FieldNotFound, field));
}
return index;
}
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.AddParsedSubObject"]/*' />
protected override void AddParsedSubObject(Object obj)
{
if (!(obj is LiteralControl))
{
if (obj is ObjectListField)
{
Fields.Add((ObjectListField)obj);
}
else if (obj is ObjectListCommand)
{
Commands.Add((ObjectListCommand)obj);
}
else
{
base.AddParsedSubObject(obj);
}
}
}
private IEnumerable ResolvedDataSource
{
get
{
if (_resolvedDataSource == null)
{
_resolvedDataSource =
DataSourceHelper.GetResolvedDataSource(DataSource, DataMember);
}
return _resolvedDataSource;
}
}
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.CreateChildControls"]/*' />
protected override void CreateChildControls()
{
Controls.Clear();
if (ViewState[_itemCountViewStateKey] != null)
{
CreateChildControls(false);
}
}
private void CreateChildControls(bool doDataBind)
{
if (IsTemplated)
{
Controls.Clear();
CreateTemplatedUI(doDataBind);
ChildControlsCreated = true;
}
}
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.DataBind"]/*' />
public override void DataBind()
{
// Do our own databinding
OnDataBinding(EventArgs.Empty);
// Contained items will be databound after they have been created,
// so we don't want to walk the hierarchy here.
}
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.OnDataBinding"]/*' />
protected override void OnDataBinding(EventArgs e)
{
base.OnDataBinding(e);
if (ResolvedDataSource == null)
{
ClearItemsAndControls();
return;
}
if (AutoGenerateFields)
{
CreateAutoGeneratedFields(ResolvedDataSource);
}
if ((AllFields == null || AllFields.Count == 0)
&& MobilePage != null
&& !MobilePage.DesignMode)
{
throw new Exception(
SR.GetString(SR.ObjectList_MustHaveOneOrMoreFields));
}
CreateItems(ResolvedDataSource);
if (!_loadingItems)
{
// To clear the selected index, the ViewMode must be list.
ViewMode = ObjectListViewMode.List;
SelectedIndex = -1;
}
else
{
SelectItemIfLoaded(SelectedIndex);
}
CreateChildControls(true);
}
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.CreateTemplatedItemsList"]/*' />
public void CreateTemplatedItemsList(bool doDataBind)
{
ObjectListItemCollection items = Items;
ITemplate headerTemplate = GetTemplate(Constants.HeaderTemplateTag);
ITemplate footerTemplate = GetTemplate(Constants.FooterTemplateTag);
ITemplate itemTemplate = GetTemplate(Constants.ItemTemplateTag);
ITemplate separatorTemplate = GetTemplate(Constants.SeparatorTemplateTag);
ITemplate alternatingItemTemplate = GetTemplate(Constants.AlternatingItemTemplateTag);
if (alternatingItemTemplate == null)
{
alternatingItemTemplate = itemTemplate;
}
CreateControlItem(MobileListItemType.HeaderItem, headerTemplate, doDataBind);
for (int i = 0; i < items.Count; i++)
{
if (i > 0)
{
CreateControlItem(MobileListItemType.SeparatorItem,
separatorTemplate,
doDataBind);
}
AddItemAsControl(i, items[i],
((i & 1) == 1) ? alternatingItemTemplate : itemTemplate,
doDataBind);
}
CreateControlItem(MobileListItemType.FooterItem, footerTemplate, doDataBind);
}
private void AddItemAsControl(
int itemIndex,
MobileListItem item,
ITemplate itemTemplate,
bool doDataBind)
{
if (itemTemplate != null)
{
// No need to do it again, since CreateItems already does it.
item.Controls.Clear();
item.ID = null;
Controls.Add(item);
CheckedInstantiateTemplate (itemTemplate, item, this);
if (doDataBind)
{
item.DataBind();
}
}
}
private void CreateControlItem(
MobileListItemType itemType,
ITemplate itemTemplate,
bool doDataBind)
{
if (itemTemplate != null)
{
MobileListItem item = new MobileListItem(itemType);
AddItemAsControl(-1, item, itemTemplate, doDataBind);
}
}
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.CreateTemplatedItemDetails"]/*' />
public void CreateTemplatedItemDetails(bool doDataBind)
{
ITemplate detailsTemplate = GetTemplate(Constants.ItemDetailsTemplateTag);
Selection.Controls.Clear();
// Selection ID must be the same on each request. AUI 8007.
Selection.ID = "_ctl";
if (detailsTemplate != null)
{
if (!Controls.Contains (Selection))
{
Controls.Add (Selection);
}
CheckedInstantiateTemplate (detailsTemplate, Selection, this);
if (doDataBind)
{
Selection.DataBind();
}
}
}
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.CreateItems"]/*' />
protected virtual void CreateItems(IEnumerable dataSource)
{
Debug.Assert (dataSource != null, "dataSource is null");
Items.Clear();
int count = 0;
IEnumerator enumerator;
if(_storedDataValid && _firstDataItem != null)
{
enumerator = _storedEnumerator;
ObjectListItem item = CreateItem(_firstDataItem);
item.SetIndex(count + Items.BaseIndex);
Items.Add(item);
count++;
_storedDataValid = false;
_firstDataItem = null;
_storedEnumerator = null;
}
else
{
enumerator = dataSource.GetEnumerator();
}
while(enumerator.MoveNext())
{
Object dataItem = enumerator.Current;
ObjectListItem item = CreateItem(dataItem);
item.SetIndex(count + Items.BaseIndex);
Items.Add(item);
count++;
}
}
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.CreateItem"]/*' />
protected virtual ObjectListItem CreateItem(Object dataItem)
{
ObjectListItem item = new ObjectListItem(this, dataItem);
// Set fields.
IObjectListFieldCollection allFields = AllFields;
int fieldIndex = 0;
foreach (ObjectListField field in AllFields)
{
field.DataBindItem(fieldIndex, item);
fieldIndex++;
}
// Use delegated data binding, if specified.
if (dataItem != null)
{
OnItemDataBind(new ObjectListDataBindEventArgs(item, dataItem));
}
return item;
}
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.OnPreRender"]/*' />
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
if (IsTemplated)
{
int firstVisibleItem = FirstVisibleItemIndex;
int pageSize = VisibleItemCount;
int lastVisibleItem = firstVisibleItem + pageSize - 1;
int itemIndex = 0;
int separatorIndex = 0;
foreach(Control ctl in Controls)
{
MobileListItem item = ctl as MobileListItem;
if (item != null)
{
if (item.ItemType == MobileListItemType.ListItem)
{
item.Visible = itemIndex >= firstVisibleItem && itemIndex <= lastVisibleItem;
itemIndex++;
}
else if (item.ItemType == MobileListItemType.SeparatorItem)
{
item.Visible = separatorIndex >= firstVisibleItem &&
separatorIndex < lastVisibleItem;
separatorIndex++;
}
}
}
}
}
/////////////////////////////////////////////////////////////////////////
// FIELD AUTO-GENERATION
/////////////////////////////////////////////////////////////////////////
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.CreateAutoGeneratedFields"]/*' />
protected void CreateAutoGeneratedFields(IEnumerable dataSource)
{
if (dataSource == null)
{
return;
}
ArrayList list = new ArrayList();
PropertyDescriptorCollection propertyDescriptors = null;
if (dataSource is ITypedList)
{
propertyDescriptors =
((ITypedList)dataSource).GetItemProperties(new PropertyDescriptor[0]);
}
if (propertyDescriptors == null)
{
IEnumerator enumerator = dataSource.GetEnumerator();
if (enumerator.MoveNext())
{
Object sampleItem = enumerator.Current;
StoreEnumerator(enumerator, sampleItem);
if (IsBindableType(sampleItem.GetType()))
{
list.Add(CreateAutoGeneratedField(
SR.GetString(SR.ObjectList_ItemTitle),
null));
}
else
{
propertyDescriptors = TypeDescriptor.GetProperties(sampleItem);
}
}
}
if (propertyDescriptors != null && propertyDescriptors.Count > 0)
{
foreach (PropertyDescriptor pd in propertyDescriptors)
{
if (IsBindableType(pd.PropertyType))
{
String title;
ObjectListTitleAttribute attr =
(ObjectListTitleAttribute)pd.Attributes[typeof(ObjectListTitleAttribute)];
if (attr != null)
{
title = attr.Title;
}
else
{
title = pd.Name;
}
list.Add(CreateAutoGeneratedField(title, pd.Name));
}
}
}
_autoGeneratedFields = new ObjectListFieldCollection(this, list);
}
/// Caches the fact that we have already consumed the first item from the enumeration
/// and must use it first during our item creation.
internal void StoreEnumerator(IEnumerator enumerator, object firstDataItem)
{
_storedEnumerator = enumerator;
_firstDataItem = firstDataItem;
_storedDataValid = true;
}
private bool IsBindableType(Type type)
{
return(type.IsPrimitive ||
(type == typeof(String)) ||
(type == typeof(DateTime)) ||
(type == typeof(Decimal)));
}
private ObjectListField CreateAutoGeneratedField(String title, String dataField)
{
ObjectListField field = new ObjectListField();
((IStateManager)field).TrackViewState();
field.Title = title;
if (dataField != null)
{
field.DataField = dataField;
}
else
{
field.SelfReference = true;
}
return field;
}
Object SaveAutoFieldsState()
{
int autoGeneratedCount = (_autoGeneratedFields != null) ? _autoGeneratedFields.Count : 0;
if (autoGeneratedCount != 0)
{
Object[] fieldStates = new Object[autoGeneratedCount];
for (int i = 0; i < autoGeneratedCount; i++)
{
fieldStates[i] = ((IStateManager)_autoGeneratedFields[i]).SaveViewState();
}
return fieldStates;
}
else
{
return null;
}
}
void LoadAutoFieldsState(Object state)
{
if (state != null)
{
Object[] fieldStates = (Object[])state;
int count = fieldStates.Length;
ArrayList list = new ArrayList(count);
foreach (Object fieldState in fieldStates)
{
ObjectListField field = new ObjectListField();
((IStateManager)field).TrackViewState();
((IStateManager)field).LoadViewState (fieldState);
list.Add(field);
}
_autoGeneratedFields = new ObjectListFieldCollection(this, list);
}
}
internal void OnFieldChanged(bool fieldAddedOrRemoved)
{
// Called when a field is added, removed, etc.
if (IsTrackingViewState)
{
_items = null;
// avoid view state being out of sync with fields.
_ignoreFieldsItemsViewModeViewState = true;
if (fieldAddedOrRemoved)
{
_allFields = null;
}
InvalidateDisplayFieldIndices();
}
}
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.InternalItemCount"]/*' />
protected override int InternalItemCount
{
get
{
if (_items != null && Items.Count > 0)
{
return Items.Count;
}
else
{
return 0;
}
}
}
/////////////////////////////////////////////////////////////////////////
// EVENT HANDLING
/////////////////////////////////////////////////////////////////////////
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.ItemDataBind"]/*' />
[
MobileCategory(SR.Category_Action),
MobileSysDescription(SR.ObjectList_OnItemDataBind)
]
public event ObjectListDataBindEventHandler ItemDataBind
{
add
{
Events.AddHandler(EventItemDataBind, value);
}
remove
{
Events.RemoveHandler(EventItemDataBind, value);
}
}
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.OnItemDataBind"]/*' />
protected virtual void OnItemDataBind(ObjectListDataBindEventArgs e)
{
ObjectListDataBindEventHandler onItemDataBindHandler =
(ObjectListDataBindEventHandler)Events[EventItemDataBind];
if (onItemDataBindHandler != null)
{
onItemDataBindHandler(this, e);
}
}
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.ItemCommand"]/*' />
[
MobileCategory(SR.Category_Action),
MobileSysDescription(SR.ObjectList_OnItemCommand)
]
public event ObjectListCommandEventHandler ItemCommand
{
add
{
Events.AddHandler(EventItemCommand, value);
}
remove
{
Events.RemoveHandler(EventItemCommand, value);
}
}
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.OnItemCommand"]/*' />
protected virtual void OnItemCommand(ObjectListCommandEventArgs e)
{
ObjectListCommandEventHandler onItemCommandHandler = (ObjectListCommandEventHandler)Events[EventItemCommand];
if (onItemCommandHandler != null)
{
onItemCommandHandler(this, e);
}
}
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.ItemSelect"]/*' />
[
MobileCategory(SR.Category_Action),
MobileSysDescription(SR.ObjectList_OnItemSelect)
]
public event ObjectListSelectEventHandler ItemSelect
{
add
{
Events.AddHandler(EventItemSelect, value);
}
remove
{
Events.RemoveHandler(EventItemSelect, value);
}
}
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.OnItemSelect"]/*' />
protected virtual void OnItemSelect(ObjectListSelectEventArgs e)
{
ObjectListSelectEventHandler onItemSelectHandler = (ObjectListSelectEventHandler)Events[EventItemSelect];
if (onItemSelectHandler != null)
{
onItemSelectHandler(this, e);
}
}
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.HasItemCommandHandler"]/*' />
[
Bindable(false),
Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
]
public bool HasItemCommandHandler
{
get
{
return Events[EventItemCommand] != null;
}
}
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.ShowItemCommands"]/*' />
[
MobileCategory(SR.Category_Action),
MobileSysDescription(SR.ObjectList_OnShowItemCommands)
]
public event ObjectListShowCommandsEventHandler ShowItemCommands
{
add
{
Events.AddHandler(EventShowItemCommands, value);
}
remove
{
Events.RemoveHandler(EventShowItemCommands, value);
}
}
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.OnShowItemCommands"]/*' />
protected virtual void OnShowItemCommands(ObjectListShowCommandsEventArgs e)
{
ObjectListShowCommandsEventHandler onShowItemCommandsHandler
= (ObjectListShowCommandsEventHandler)Events[EventShowItemCommands];
if (onShowItemCommandsHandler != null)
{
onShowItemCommandsHandler(this, e);
}
}
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.OnBubbleEvent"]/*' />
protected override bool OnBubbleEvent(Object sender, EventArgs e)
{
bool handled = false;
if (e is CommandEventArgs)
{
if (e is ObjectListCommandEventArgs)
{
OnItemCommand((ObjectListCommandEventArgs)e);
handled = true;
}
}
return handled;
}
/// <internalonly/>
protected void RaisePostBackEvent(String eventArgument)
{
if (!Adapter.HandlePostBackEvent(eventArgument))
{
OnItemCommand(new ObjectListCommandEventArgs(Selection, eventArgument));
}
}
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.RaiseDefaultItemEvent"]/*' />
public void RaiseDefaultItemEvent(int itemIndex)
{
EnsureItemLoaded (itemIndex);
int itemCollIndex = TranslateVirtualItemIndex(itemIndex);
SelectedIndex = itemIndex;
OnItemCommand(new ObjectListCommandEventArgs(Items[itemCollIndex], DefaultCommand));
}
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.SelectListItem"]/*' />
public bool SelectListItem(int itemIndex, bool selectMore)
{
EnsureItemLoaded (itemIndex);
int itemCollIndex = TranslateVirtualItemIndex(itemIndex);
ObjectListSelectEventArgs args = new ObjectListSelectEventArgs(
Items[itemCollIndex],
selectMore);
SelectedIndex = itemIndex;
OnItemSelect(args);
return args.UseDefaultHandling;
}
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.PreShowItemCommands"]/*' />
public void PreShowItemCommands(int itemIndex)
{
// Called just before commands are shown for a given item. We call
// an event handler that can modify (or even replace) the commands collection,
// but first we mark the collection, and save it off, so that we can
// save the state of the collection at this point.
if (_commands != null)
{
_globalCommands = _commands;
_commands.GlobalStateSet();
}
SelectedIndex = itemIndex;
ObjectListShowCommandsEventArgs eventArgs =
new ObjectListShowCommandsEventArgs(Selection, Commands);
OnShowItemCommands(eventArgs);
if (eventArgs.Commands != _commands)
{
_commands = eventArgs.Commands;
}
}
private void EnsureItemLoaded(int virtualIndex)
{
Debug.Assert (virtualIndex >= 0, "virtualIndex < 0");
if (ItemCount > 0 &&
(_items == null ||
virtualIndex < Items.BaseIndex ||
Items.Count <= virtualIndex - Items.BaseIndex))
{
OnLoadItems(new LoadItemsEventArgs(virtualIndex, 1));
}
}
private int TranslateVirtualItemIndex(int virtualIndex)
{
Debug.Assert(ItemCount > 0 || Items.BaseIndex == 0);
// Translate virtual index to true index within collection.
// If custom pagination is off, virtual index is the true index.
return virtualIndex - Items.BaseIndex;
}
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.OnLoadItems"]/*' />
protected override void OnLoadItems(LoadItemsEventArgs e)
{
// We should only load items if the base index has changed, or if
// the desired items do not exist in the list. Otherwise, we are making
// the app reload the same items over and over.
if (e.ItemIndex != Items.BaseIndex || e.ItemCount != Items.Count)
{
_loadingItems = true;
Items.BaseIndex = e.ItemIndex;
Items.Clear();
base.OnLoadItems(e);
_loadingItems = false;
}
}
/////////////////////////////////////////////////////////////////////////
// STATE MANAGEMENT
/////////////////////////////////////////////////////////////////////////
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.TrackViewState"]/*' />
protected override void TrackViewState()
{
base.TrackViewState();
if (_fields != null)
{
((IStateManager)_fields).TrackViewState();
}
if (_commands != null)
{
((IStateManager)_commands).TrackViewState();
}
if (_items != null)
{
((IStateManager)_items).TrackViewState();
}
}
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.SavePrivateViewState"]/*' />
protected override Object SavePrivateViewState()
{
Object baseState = base.SavePrivateViewState();
if (ViewMode != ObjectListViewMode.List || _selectedIndexDirty)
{
return new Triplet(baseState, (int) ViewMode, SelectedIndex);
}
else if (baseState != null)
{
return baseState;
}
return null;
}
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.LoadPrivateViewState"]/*' />
protected override void LoadPrivateViewState(Object state)
{
if (state != null)
{
Triplet stateTriplet = state as Triplet;
if (stateTriplet != null)
{
base.LoadPrivateViewState (stateTriplet.First);
ObjectListViewMode originalViewMode = _viewMode;
// use private field because property get calls CreateChildControls.
_viewMode = (ObjectListViewMode) stateTriplet.Second;
// use property to insure we load items if necessary and set selected index dirty.
SelectedIndex = (int)stateTriplet.Third;
bool viewModeChanged = (originalViewMode != _viewMode);
if (ChildControlsCreated && viewModeChanged)
{
// This is before items loaded in LVS, so we only do this if
// child controls already created in init (e.g., no VS.)
CreateChildControls (true);
}
}
else
{
base.LoadPrivateViewState(state);
}
}
}
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.SaveViewState"]/*' />
protected override Object SaveViewState()
{
Object baseState, fieldsState, autoFieldsState, commandsState, itemsState;
Debug.Assert (Items != null, "get_Items should initialize Items collection.");
int count = Items.Count;
// HasControls implies DataBound on this or a prev req (but not converse).
if (count > 0 || HasControls())
{
ViewState[_itemCountViewStateKey] = count;
}
baseState = base.SaveViewState();
fieldsState = (_fields != null) ? ((IStateManager)_fields).SaveViewState() : null;
autoFieldsState = SaveAutoFieldsState();
commandsState = (_commands != null) ? ((IStateManager)_commands).SaveViewState() : null;
itemsState = (_items != null) ? ((IStateManager)_items).SaveViewState() : null;
if (itemsState != null ||
fieldsState != null ||
autoFieldsState != null ||
commandsState != null )
{
return new Object[5]
{
baseState,
fieldsState,
autoFieldsState,
commandsState,
itemsState
};
}
else if (baseState != null)
{
return new Object[1] { baseState };
}
return null;
}
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.LoadViewState"]/*' />
protected override void LoadViewState(Object savedState)
{
// copy locally (can change during Fields.LVS).
bool ignoreFieldsItemsViewModeViewState = _ignoreFieldsItemsViewModeViewState;
if (savedState != null)
{
Object[] state = (Object[])savedState;
base.LoadViewState(state[0]);
if (state.Length > 1)
{
// Always load items after loading fields, because field changes can wipe out
// items!
if(!ignoreFieldsItemsViewModeViewState)
{
((IStateManager)Fields).LoadViewState(state[1]);
LoadAutoFieldsState(state[2]);
}
((IStateManager)Commands).LoadViewState(state[3]);
if(!ignoreFieldsItemsViewModeViewState)
{
((IStateManager)Items).LoadViewState(state[4]);
SelectItemIfLoaded(SelectedIndex);
}
}
}
}
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.ViewMode"]/*' />
[
Bindable(false),
Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
]
public ObjectListViewMode ViewMode
{
get
{
return _viewMode;
}
set
{
if (SelectedIndex == -1 && value != ObjectListViewMode.List)
{
throw new Exception(SR.GetString(
SR.ObjectList_CannotSetViewModeWithNoSelectedItem));
}
if (value == ObjectListViewMode.List)
{
// Set pagination state changed to refresh pagination.
Form.PaginationStateChanged = true;
}
_viewMode = value;
CreateChildControls(true);
}
}
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.DetailsCommandText"]/*' />
[
Bindable(true),
Browsable(true),
DefaultValue(""),
MobileCategory(SR.Category_Appearance),
MobileSysDescription(SR.ObjectList_DetailsCommandText),
]
public String DetailsCommandText
{
get
{
String detailsCommandText = (String)ViewState["DetailsCommandText"];
return detailsCommandText != null ? detailsCommandText : String.Empty;
}
set
{
ViewState["DetailsCommandText"] = value;
}
}
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.BackCommandText"]/*' />
[
Bindable(true),
Browsable(true),
DefaultValue(""),
MobileCategory(SR.Category_Appearance),
MobileSysDescription(SR.ObjectList_BackCommandText),
]
public String BackCommandText
{
get
{
String backCommandText = (String) ViewState["BackCommandText"];
return backCommandText != null ? backCommandText : String.Empty;
}
set
{
ViewState["BackCommandText"] = value;
}
}
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.MoreText"]/*' />
[
Bindable(true),
Browsable(true),
DefaultValue(""),
MobileCategory(SR.Category_Appearance),
MobileSysDescription(SR.ObjectList_MoreText)
]
public String MoreText
{
get
{
String moreText = (String)ViewState["MoreText"];
return moreText != null ? moreText : String.Empty;
}
set
{
ViewState["MoreText"] = value;
}
}
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.CommandStyle"]/*' />
[
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
MobileCategory(SR.Category_Style),
MobileSysDescription(SR.ObjectList_CommandStyle),
NotifyParentProperty(true)
]
public Style CommandStyle
{
get
{
if (_commandStyle == null)
{
_commandStyle = new Style();
_commandStyle.SetControl(this);
_commandStyle.StyleReference = "subcommand";
}
return _commandStyle;
}
set
{
_commandStyle = value;
}
}
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectList.LabelStyle"]/*' />
[
DefaultValue(null),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
MobileCategory(SR.Category_Style),
MobileSysDescription(SR.ObjectList_LabelStyle),
NotifyParentProperty(true)
]
public Style LabelStyle
{
get
{
if (_labelStyle == null)
{
_labelStyle = new Style();
_labelStyle.SetControl(this);
_labelStyle.StyleReference = "title";
}
return _labelStyle;
}
set
{
_labelStyle = value;
}
}
internal override void InvalidateParentStyles()
{
if (_commandStyle != null)
{
_commandStyle.InvalidateParentStyle();
}
if (_labelStyle != null)
{
_labelStyle.InvalidateParentStyle();
}
base.InvalidateParentStyles();
}
internal override void InternalItemCountChangedHandler(int newItemCount)
{
if (newItemCount == 0)
{
ClearItemsAndControls();
}
}
private void ClearItemsAndControls()
{
ViewMode = ObjectListViewMode.List;
SelectedIndex = -1;
Items.Clear();
Controls.Clear();
}
// Wrapper to increase intelligibility at point of call.
private void SelectItemIfLoaded(int virtualIndex)
{
SetItemSelectedPropertyIfItemLoaded(virtualIndex, true);
}
// Wrapper to increase intelligibility at point of call.
private void DeselectItemIfLoaded(int virtualIndex)
{
SetItemSelectedPropertyIfItemLoaded(virtualIndex, false);
}
private void SetItemSelectedPropertyIfItemLoaded(int virtualIndex, bool newValue)
{
if (virtualIndex < 0)
{
return;
}
int physicalIndex = TranslateVirtualItemIndex(virtualIndex);
if (physicalIndex >= 0 && physicalIndex < Items.Count)
{
Items[physicalIndex].Selected = newValue;
}
}
#region IPostBackEventHandler implementation
void IPostBackEventHandler.RaisePostBackEvent(String eventArgument) {
RaisePostBackEvent(eventArgument);
}
#endregion
}
/*
* Control builder for object lists.
*
* Copyright (c) 2000 Microsoft Corporation
*/
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectListControlBuilder"]/*' />
[AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)]
[AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)]
[Obsolete("The System.Web.Mobile.dll assembly has been deprecated and should no longer be used. For information about how to develop ASP.NET mobile applications, see http://go.microsoft.com/fwlink/?LinkId=157231.")]
public class ObjectListControlBuilder : MobileControlBuilder
{
/// <include file='doc\ObjectList.uex' path='docs/doc[@for="ObjectListControlBuilder.GetChildControlType"]/*' />
public override Type GetChildControlType(String tagName, IDictionary attributes)
{
if (String.Compare(tagName, "Field", StringComparison.OrdinalIgnoreCase) == 0)
{
return typeof(ObjectListField);
}
else if (String.Compare(tagName, "Command", StringComparison.OrdinalIgnoreCase) == 0)
{
return typeof(ObjectListCommand);
}
else
{
return base.GetChildControlType(tagName, attributes);
}
}
}
}
|