536cd135cc
Former-commit-id: 5624ac747d633e885131e8349322922b6a59baaa
1590 lines
56 KiB
C#
1590 lines
56 KiB
C#
//------------------------------------------------------------------------------
|
|
// <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);
|
|
}
|
|
}
|
|
}
|
|
}
|