2016-08-03 10:59:49 +00:00
//------------------------------------------------------------------------------
// <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 ;
2017-08-21 15:34:15 +00:00
// avoid view state being out of sync with fields.
2016-08-03 10:59:49 +00:00
_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 ) ;
}
}
}
}