Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / xsp / System / Web / UI / WebControls / Repeater.cs / 1305376 / Repeater.cs
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//-----------------------------------------------------------------------------
namespace System.Web.UI.WebControls {
using System;
using System.Collections;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Web;
using System.Web.UI;
using System.Web.Util;
///
/// Defines the properties, methods, and events of a class.
///
[
DefaultEvent("ItemCommand"),
DefaultProperty("DataSource"),
Designer("System.Web.UI.Design.WebControls.RepeaterDesigner, " + AssemblyRef.SystemDesign),
ParseChildren(true),
PersistChildren(false)
]
public class Repeater : Control, INamingContainer {
private static readonly object EventItemCreated = new object();
private static readonly object EventItemDataBound = new object();
private static readonly object EventItemCommand = new object();
internal const string ItemCountViewStateKey = "_!ItemCount";
private object dataSource;
private ITemplate headerTemplate;
private ITemplate footerTemplate;
private ITemplate itemTemplate;
private ITemplate alternatingItemTemplate;
private ITemplate separatorTemplate;
private ArrayList itemsArray;
private RepeaterItemCollection itemsCollection;
private bool _requiresDataBinding;
private bool _inited;
private bool _throwOnDataPropertyChange;
private DataSourceView _currentView;
private bool _currentViewIsFromDataSourceID;
private bool _currentViewValid;
private DataSourceSelectArguments _arguments;
private bool _pagePreLoadFired;
///
/// Initializes a new instance of the class.
///
public Repeater() {
}
///
/// Gets or sets the that defines how alternating (even-indexed) items
/// are rendered.
///
[
Browsable(false),
DefaultValue(null),
PersistenceMode(PersistenceMode.InnerProperty),
TemplateContainer(typeof(RepeaterItem)),
WebSysDescription(SR.Repeater_AlternatingItemTemplate)
]
public virtual ITemplate AlternatingItemTemplate {
get {
return alternatingItemTemplate;
}
set {
alternatingItemTemplate = value;
}
}
public override ControlCollection Controls {
get {
EnsureChildControls();
return base.Controls;
}
}
///
/// [To be supplied.]
///
[
DefaultValue(""),
WebCategory("Data"),
WebSysDescription(SR.Repeater_DataMember)
]
public virtual string DataMember {
get {
object o = ViewState["DataMember"];
if (o != null)
return (string)o;
return String.Empty;
}
set {
ViewState["DataMember"] = value;
OnDataPropertyChanged();
}
}
///
/// Gets or sets the data source that provides data for
/// populating the list.
///
[
Bindable(true),
WebCategory("Data"),
DefaultValue(null),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
WebSysDescription(SR.BaseDataBoundControl_DataSource)
]
public virtual object DataSource {
get {
return dataSource;
}
set {
if ((value == null) || (value is IListSource) || (value is IEnumerable)) {
dataSource = value;
OnDataPropertyChanged();
}
else {
throw new ArgumentException(SR.GetString(SR.Invalid_DataSource_Type, ID));
}
}
}
///
/// The ID of the DataControl that this control should use to retrieve
/// its data source. When the control is bound to a DataControl, it
/// can retrieve a data source instance on-demand, and thereby attempt
/// to work in auto-DataBind mode.
///
[
DefaultValue(""),
IDReferenceProperty(typeof(DataSourceControl)),
WebCategory("Data"),
WebSysDescription(SR.BaseDataBoundControl_DataSourceID)
]
public virtual string DataSourceID {
get {
object o = ViewState["DataSourceID"];
if (o != null) {
return (string)o;
}
return String.Empty;
}
set {
ViewState["DataSourceID"] = value;
OnDataPropertyChanged();
}
}
///
/// Gets and sets a value indicating whether theme is enabled.
///
[
Browsable(true)
]
public override bool EnableTheming {
get {
return base.EnableTheming;
}
set {
base.EnableTheming = value;
}
}
///
/// Gets or sets the that defines how the control footer is
/// rendered.
///
[
Browsable(false),
DefaultValue(null),
PersistenceMode(PersistenceMode.InnerProperty),
TemplateContainer(typeof(RepeaterItem)),
WebSysDescription(SR.Repeater_FooterTemplate)
]
public virtual ITemplate FooterTemplate {
get {
return footerTemplate;
}
set {
footerTemplate = value;
}
}
///
/// Gets or sets the that defines how the control header is rendered.
///
[
Browsable(false),
DefaultValue(null),
PersistenceMode(PersistenceMode.InnerProperty),
TemplateContainer(typeof(RepeaterItem)),
WebSysDescription(SR.WebControl_HeaderTemplate)
]
public virtual ITemplate HeaderTemplate {
get {
return headerTemplate;
}
set {
headerTemplate = value;
}
}
protected bool Initialized {
get {
return _inited;
}
}
protected bool IsBoundUsingDataSourceID {
get {
return (DataSourceID.Length > 0);
}
}
///
/// Gets the collection.
///
[
Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
WebSysDescription(SR.Repeater_Items)
]
public virtual RepeaterItemCollection Items {
get {
if (itemsCollection == null) {
if (itemsArray == null) {
EnsureChildControls();
}
itemsCollection = new RepeaterItemCollection(itemsArray);
}
return itemsCollection;
}
}
///
/// Gets or sets the that defines how items are rendered.
///
[
Browsable(false),
DefaultValue(null),
PersistenceMode(PersistenceMode.InnerProperty),
TemplateContainer(typeof(RepeaterItem)),
WebSysDescription(SR.Repeater_ItemTemplate)
]
public virtual ITemplate ItemTemplate {
get {
return itemTemplate;
}
set {
itemTemplate = value;
}
}
protected bool RequiresDataBinding {
get {
return _requiresDataBinding;
}
set {
_requiresDataBinding = value;
}
}
protected DataSourceSelectArguments SelectArguments {
get {
if (_arguments == null) {
_arguments = CreateDataSourceSelectArguments();
}
return _arguments;
}
}
///
/// Gets or sets the that defines how separators
/// in between items are rendered.
///
[
Browsable(false),
DefaultValue(null),
PersistenceMode(PersistenceMode.InnerProperty),
TemplateContainer(typeof(RepeaterItem)),
WebSysDescription(SR.Repeater_SeparatorTemplate)
]
public virtual ITemplate SeparatorTemplate {
get {
return separatorTemplate;
}
set {
separatorTemplate = value;
}
}
///
/// Occurs when a button is clicked within the control tree.
///
[
WebCategory("Action"),
WebSysDescription(SR.Repeater_OnItemCommand)
]
public event RepeaterCommandEventHandler ItemCommand {
add {
Events.AddHandler(EventItemCommand, value);
}
remove {
Events.RemoveHandler(EventItemCommand, value);
}
}
///
/// Occurs when an item is created within the control tree.
///
[
WebCategory("Behavior"),
WebSysDescription(SR.DataControls_OnItemCreated)
]
public event RepeaterItemEventHandler ItemCreated {
add {
Events.AddHandler(EventItemCreated, value);
}
remove {
Events.RemoveHandler(EventItemCreated, value);
}
}
///
/// Occurs when an item is databound within a control tree.
///
[
WebCategory("Behavior"),
WebSysDescription(SR.DataControls_OnItemDataBound)
]
public event RepeaterItemEventHandler ItemDataBound {
add {
Events.AddHandler(EventItemDataBound, value);
}
remove {
Events.RemoveHandler(EventItemDataBound, value);
}
}
///
/// Connects this data bound control to the appropriate DataSourceView
/// and hooks up the appropriate event listener for the
/// DataSourceViewChanged event. The return value is the new view (if
/// any) that was connected to. An exception is thrown if there is
/// a problem finding the requested view or data source.
///
private DataSourceView ConnectToDataSourceView() {
if (_currentViewValid && !DesignMode) {
// If the current view is correct, there is no need to reconnect
return _currentView;
}
// Disconnect from old view, if necessary
if ((_currentView != null) && (_currentViewIsFromDataSourceID)) {
// We only care about this event if we are bound through the DataSourceID property
_currentView.DataSourceViewChanged -= new EventHandler(OnDataSourceViewChanged);
}
// Connect to new view
IDataSource ds = null;
string dataSourceID = DataSourceID;
if (dataSourceID.Length != 0) {
// Try to find a DataSource control with the ID specified in DataSourceID
Control control = DataBoundControlHelper.FindControl(this, dataSourceID);
if (control == null) {
throw new HttpException(SR.GetString(SR.DataControl_DataSourceDoesntExist, ID, dataSourceID));
}
ds = control as IDataSource;
if (ds == null) {
throw new HttpException(SR.GetString(SR.DataControl_DataSourceIDMustBeDataControl, ID, dataSourceID));
}
}
if (ds == null) {
// DataSource control was not found, construct a temporary data source to wrap the data
ds = new ReadOnlyDataSource(DataSource, DataMember);
}
else {
// Ensure that both DataSourceID as well as DataSource are not set at the same time
if (DataSource != null) {
throw new InvalidOperationException(SR.GetString(SR.DataControl_MultipleDataSources, ID));
}
}
// IDataSource was found, extract the appropriate view and return it
DataSourceView newView = ds.GetView(DataMember);
if (newView == null) {
throw new InvalidOperationException(SR.GetString(SR.DataControl_ViewNotFound, ID));
}
_currentViewIsFromDataSourceID = IsBoundUsingDataSourceID;
_currentView = newView;
if ((_currentView != null) && (_currentViewIsFromDataSourceID)) {
// We only care about this event if we are bound through the DataSourceID property
_currentView.DataSourceViewChanged += new EventHandler(OnDataSourceViewChanged);
}
_currentViewValid = true;
return _currentView;
}
///
///
protected internal override void CreateChildControls() {
Controls.Clear();
if (ViewState[ItemCountViewStateKey] != null) {
// create the control hierarchy using the view state (and
// not the datasource)
CreateControlHierarchy(false);
}
else {
itemsArray = new ArrayList();
}
ClearChildViewState();
}
///
/// A protected method. Creates a control
/// hierarchy, with or without the data source as specified.
///
protected virtual void CreateControlHierarchy(bool useDataSource) {
IEnumerable dataSource = null;
int count = -1;
if (itemsArray != null) {
itemsArray.Clear();
}
else {
itemsArray = new ArrayList();
}
if (useDataSource == false) {
// ViewState must have a non-null value for ItemCount because we check for
// this in CreateChildControls
count = (int)ViewState[ItemCountViewStateKey];
if (count != -1) {
dataSource = new DummyDataSource(count);
itemsArray.Capacity = count;
}
}
else {
dataSource = GetData();
ICollection collection = dataSource as ICollection;
if (collection != null) {
itemsArray.Capacity = collection.Count;
}
}
if (dataSource != null) {
RepeaterItem item;
ListItemType itemType;
int index = 0;
bool hasSeparators = (separatorTemplate != null);
count = 0;
if (headerTemplate != null) {
CreateItem(-1, ListItemType.Header, useDataSource, null);
}
foreach (object dataItem in dataSource) {
// rather than creating separators after the item, we create the separator
// for the previous item in all iterations of this loop.
// this is so that we don't create a separator for the last item
if (hasSeparators && (count > 0)) {
CreateItem(index - 1, ListItemType.Separator, useDataSource, null);
}
itemType = (index % 2 == 0) ? ListItemType.Item : ListItemType.AlternatingItem;
item = CreateItem(index, itemType, useDataSource, dataItem);
itemsArray.Add(item);
count++;
index++;
}
if (footerTemplate != null) {
CreateItem(-1, ListItemType.Footer, useDataSource, null);
}
}
if (useDataSource) {
// save the number of items contained in the repeater for use in round-trips
ViewState[ItemCountViewStateKey] = ((dataSource != null) ? count : -1);
}
}
protected virtual DataSourceSelectArguments CreateDataSourceSelectArguments() {
return DataSourceSelectArguments.Empty;
}
///
///
private RepeaterItem CreateItem(int itemIndex, ListItemType itemType, bool dataBind, object dataItem) {
RepeaterItem item = CreateItem(itemIndex, itemType);
RepeaterItemEventArgs e = new RepeaterItemEventArgs(item);
InitializeItem(item);
if (dataBind) {
item.DataItem = dataItem;
}
OnItemCreated(e);
Controls.Add(item);
if (dataBind) {
item.DataBind();
OnItemDataBound(e);
item.DataItem = null;
}
return item;
}
///
/// A protected method. Creates a with the specified item type and
/// location within the .
///
protected virtual RepeaterItem CreateItem(int itemIndex, ListItemType itemType) {
return new RepeaterItem(itemIndex, itemType);
}
///
///
///
public override void DataBind() {
// Don't databind to a data source control when the control is in the designer but not top-level
if (IsBoundUsingDataSourceID && DesignMode && (Site == null)) {
return;
}
// do our own databinding
RequiresDataBinding = false;
OnDataBinding(EventArgs.Empty);
// contained items will be databound after they have been created,
// so we don't want to walk the hierarchy here.
}
protected void EnsureDataBound() {
try {
_throwOnDataPropertyChange = true;
if (RequiresDataBinding && DataSourceID.Length > 0) {
DataBind();
}
}
finally {
_throwOnDataPropertyChange = false;
}
}
///
/// Returns an IEnumerable that is the DataSource, which either came
/// from the DataSource property or from the control bound via the
/// DataSourceID property.
///
protected virtual IEnumerable GetData() {
DataSourceView view = ConnectToDataSourceView();
Debug.Assert(_currentViewValid);
if (view != null) {
return view.ExecuteSelect(SelectArguments);
}
return null;
}
///
/// A protected method. Populates iteratively the specified with a
/// sub-hierarchy of child controls.
///
protected virtual void InitializeItem(RepeaterItem item) {
ITemplate contentTemplate = null;
switch (item.ItemType) {
case ListItemType.Header:
contentTemplate = headerTemplate;
break;
case ListItemType.Footer:
contentTemplate = footerTemplate;
break;
case ListItemType.Item:
contentTemplate = itemTemplate;
break;
case ListItemType.AlternatingItem:
contentTemplate = alternatingItemTemplate;
if (contentTemplate == null)
goto case ListItemType.Item;
break;
case ListItemType.Separator:
contentTemplate = separatorTemplate;
break;
}
if (contentTemplate != null) {
contentTemplate.InstantiateIn(item);
}
}
///
///
///
protected override bool OnBubbleEvent(object sender, EventArgs e) {
bool handled = false;
if (e is RepeaterCommandEventArgs) {
OnItemCommand((RepeaterCommandEventArgs)e);
handled = true;
}
return handled;
}
///
///
/// A protected method. Raises the event.
///
protected override void OnDataBinding(EventArgs e) {
base.OnDataBinding(e);
// reset the control state
Controls.Clear();
ClearChildViewState();
// and then create the control hierarchy using the datasource
CreateControlHierarchy(true);
ChildControlsCreated = true;
}
///
/// This method is called when DataMember, DataSource, or DataSourceID is changed.
///
protected virtual void OnDataPropertyChanged() {
if (_throwOnDataPropertyChange) {
throw new HttpException(SR.GetString(SR.DataBoundControl_InvalidDataPropertyChange, ID));
}
if (_inited) {
RequiresDataBinding = true;
}
_currentViewValid = false;
}
protected virtual void OnDataSourceViewChanged(object sender, EventArgs e) {
RequiresDataBinding = true;
}
protected internal override void OnInit(EventArgs e) {
base.OnInit(e);
if (Page != null) {
Page.PreLoad += new EventHandler(this.OnPagePreLoad);
if (!IsViewStateEnabled && Page.IsPostBack) {
RequiresDataBinding = true;
}
}
}
///
/// A protected method. Raises the event.
///
protected virtual void OnItemCommand(RepeaterCommandEventArgs e) {
RepeaterCommandEventHandler onItemCommandHandler = (RepeaterCommandEventHandler)Events[EventItemCommand];
if (onItemCommandHandler != null) onItemCommandHandler(this, e);
}
///
/// A protected method. Raises the event.
///
protected virtual void OnItemCreated(RepeaterItemEventArgs e) {
RepeaterItemEventHandler onItemCreatedHandler = (RepeaterItemEventHandler)Events[EventItemCreated];
if (onItemCreatedHandler != null) onItemCreatedHandler(this, e);
}
///
/// A protected method. Raises the
/// event.
///
protected virtual void OnItemDataBound(RepeaterItemEventArgs e) {
RepeaterItemEventHandler onItemDataBoundHandler = (RepeaterItemEventHandler)Events[EventItemDataBound];
if (onItemDataBoundHandler != null) onItemDataBoundHandler(this, e);
}
protected internal override void OnLoad(EventArgs e) {
_inited = true; // just in case we were added to the page after PreLoad
ConnectToDataSourceView();
if (Page != null && !_pagePreLoadFired && ViewState[ItemCountViewStateKey] == null) {
// If the control was added after PagePreLoad, we still need to databind it because it missed its
// first change in PagePreLoad. If this control was created by a call to a parent control's DataBind
// in Page_Load (with is relatively common), this control will already have been databound even
// though pagePreLoad never fired and the page isn't a postback.
if (!Page.IsPostBack) {
RequiresDataBinding = true;
}
// If the control was added to the page after page.PreLoad, we'll never get the event and we'll
// never databind the control. So if we're catching up and Load happens but PreLoad never happened,
// call DataBind. This may make the control get databound twice if the user called DataBind on the control
// directly in Page.OnLoad, but better to bind twice than never to bind at all.
else if (IsViewStateEnabled) {
RequiresDataBinding = true;
}
}
base.OnLoad(e);
}
private void OnPagePreLoad(object sender, EventArgs e) {
_inited = true;
if (Page != null) {
Page.PreLoad -= new EventHandler(this.OnPagePreLoad);
// Setting RequiresDataBinding to true in OnLoad is too late because the OnLoad page event
// happens before the control.OnLoad method gets called. So a page_load handler on the page
// that calls DataBind won't prevent DataBind from getting called again in PreRender.
if (!Page.IsPostBack) {
RequiresDataBinding = true;
}
// If this is a postback and viewstate is enabled, but we have never bound the control
// before, it is probably because its visibility was changed in the postback. In this
// case, we need to bind the control or it will never appear. This is a common scenario
// for Wizard and MultiView.
if (Page.IsPostBack && IsViewStateEnabled && ViewState[ItemCountViewStateKey] == null) {
RequiresDataBinding = true;
}
_pagePreLoadFired = true;
}
}
protected internal override void OnPreRender(EventArgs e) {
EnsureDataBound();
base.OnPreRender(e);
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//-----------------------------------------------------------------------------
namespace System.Web.UI.WebControls {
using System;
using System.Collections;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Web;
using System.Web.UI;
using System.Web.Util;
///
/// Defines the properties, methods, and events of a class.
///
[
DefaultEvent("ItemCommand"),
DefaultProperty("DataSource"),
Designer("System.Web.UI.Design.WebControls.RepeaterDesigner, " + AssemblyRef.SystemDesign),
ParseChildren(true),
PersistChildren(false)
]
public class Repeater : Control, INamingContainer {
private static readonly object EventItemCreated = new object();
private static readonly object EventItemDataBound = new object();
private static readonly object EventItemCommand = new object();
internal const string ItemCountViewStateKey = "_!ItemCount";
private object dataSource;
private ITemplate headerTemplate;
private ITemplate footerTemplate;
private ITemplate itemTemplate;
private ITemplate alternatingItemTemplate;
private ITemplate separatorTemplate;
private ArrayList itemsArray;
private RepeaterItemCollection itemsCollection;
private bool _requiresDataBinding;
private bool _inited;
private bool _throwOnDataPropertyChange;
private DataSourceView _currentView;
private bool _currentViewIsFromDataSourceID;
private bool _currentViewValid;
private DataSourceSelectArguments _arguments;
private bool _pagePreLoadFired;
///
/// Initializes a new instance of the class.
///
public Repeater() {
}
///
/// Gets or sets the that defines how alternating (even-indexed) items
/// are rendered.
///
[
Browsable(false),
DefaultValue(null),
PersistenceMode(PersistenceMode.InnerProperty),
TemplateContainer(typeof(RepeaterItem)),
WebSysDescription(SR.Repeater_AlternatingItemTemplate)
]
public virtual ITemplate AlternatingItemTemplate {
get {
return alternatingItemTemplate;
}
set {
alternatingItemTemplate = value;
}
}
public override ControlCollection Controls {
get {
EnsureChildControls();
return base.Controls;
}
}
///
/// [To be supplied.]
///
[
DefaultValue(""),
WebCategory("Data"),
WebSysDescription(SR.Repeater_DataMember)
]
public virtual string DataMember {
get {
object o = ViewState["DataMember"];
if (o != null)
return (string)o;
return String.Empty;
}
set {
ViewState["DataMember"] = value;
OnDataPropertyChanged();
}
}
///
/// Gets or sets the data source that provides data for
/// populating the list.
///
[
Bindable(true),
WebCategory("Data"),
DefaultValue(null),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
WebSysDescription(SR.BaseDataBoundControl_DataSource)
]
public virtual object DataSource {
get {
return dataSource;
}
set {
if ((value == null) || (value is IListSource) || (value is IEnumerable)) {
dataSource = value;
OnDataPropertyChanged();
}
else {
throw new ArgumentException(SR.GetString(SR.Invalid_DataSource_Type, ID));
}
}
}
///
/// The ID of the DataControl that this control should use to retrieve
/// its data source. When the control is bound to a DataControl, it
/// can retrieve a data source instance on-demand, and thereby attempt
/// to work in auto-DataBind mode.
///
[
DefaultValue(""),
IDReferenceProperty(typeof(DataSourceControl)),
WebCategory("Data"),
WebSysDescription(SR.BaseDataBoundControl_DataSourceID)
]
public virtual string DataSourceID {
get {
object o = ViewState["DataSourceID"];
if (o != null) {
return (string)o;
}
return String.Empty;
}
set {
ViewState["DataSourceID"] = value;
OnDataPropertyChanged();
}
}
///
/// Gets and sets a value indicating whether theme is enabled.
///
[
Browsable(true)
]
public override bool EnableTheming {
get {
return base.EnableTheming;
}
set {
base.EnableTheming = value;
}
}
///
/// Gets or sets the that defines how the control footer is
/// rendered.
///
[
Browsable(false),
DefaultValue(null),
PersistenceMode(PersistenceMode.InnerProperty),
TemplateContainer(typeof(RepeaterItem)),
WebSysDescription(SR.Repeater_FooterTemplate)
]
public virtual ITemplate FooterTemplate {
get {
return footerTemplate;
}
set {
footerTemplate = value;
}
}
///
/// Gets or sets the that defines how the control header is rendered.
///
[
Browsable(false),
DefaultValue(null),
PersistenceMode(PersistenceMode.InnerProperty),
TemplateContainer(typeof(RepeaterItem)),
WebSysDescription(SR.WebControl_HeaderTemplate)
]
public virtual ITemplate HeaderTemplate {
get {
return headerTemplate;
}
set {
headerTemplate = value;
}
}
protected bool Initialized {
get {
return _inited;
}
}
protected bool IsBoundUsingDataSourceID {
get {
return (DataSourceID.Length > 0);
}
}
///
/// Gets the collection.
///
[
Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
WebSysDescription(SR.Repeater_Items)
]
public virtual RepeaterItemCollection Items {
get {
if (itemsCollection == null) {
if (itemsArray == null) {
EnsureChildControls();
}
itemsCollection = new RepeaterItemCollection(itemsArray);
}
return itemsCollection;
}
}
///
/// Gets or sets the that defines how items are rendered.
///
[
Browsable(false),
DefaultValue(null),
PersistenceMode(PersistenceMode.InnerProperty),
TemplateContainer(typeof(RepeaterItem)),
WebSysDescription(SR.Repeater_ItemTemplate)
]
public virtual ITemplate ItemTemplate {
get {
return itemTemplate;
}
set {
itemTemplate = value;
}
}
protected bool RequiresDataBinding {
get {
return _requiresDataBinding;
}
set {
_requiresDataBinding = value;
}
}
protected DataSourceSelectArguments SelectArguments {
get {
if (_arguments == null) {
_arguments = CreateDataSourceSelectArguments();
}
return _arguments;
}
}
///
/// Gets or sets the that defines how separators
/// in between items are rendered.
///
[
Browsable(false),
DefaultValue(null),
PersistenceMode(PersistenceMode.InnerProperty),
TemplateContainer(typeof(RepeaterItem)),
WebSysDescription(SR.Repeater_SeparatorTemplate)
]
public virtual ITemplate SeparatorTemplate {
get {
return separatorTemplate;
}
set {
separatorTemplate = value;
}
}
///
/// Occurs when a button is clicked within the control tree.
///
[
WebCategory("Action"),
WebSysDescription(SR.Repeater_OnItemCommand)
]
public event RepeaterCommandEventHandler ItemCommand {
add {
Events.AddHandler(EventItemCommand, value);
}
remove {
Events.RemoveHandler(EventItemCommand, value);
}
}
///
/// Occurs when an item is created within the control tree.
///
[
WebCategory("Behavior"),
WebSysDescription(SR.DataControls_OnItemCreated)
]
public event RepeaterItemEventHandler ItemCreated {
add {
Events.AddHandler(EventItemCreated, value);
}
remove {
Events.RemoveHandler(EventItemCreated, value);
}
}
///
/// Occurs when an item is databound within a control tree.
///
[
WebCategory("Behavior"),
WebSysDescription(SR.DataControls_OnItemDataBound)
]
public event RepeaterItemEventHandler ItemDataBound {
add {
Events.AddHandler(EventItemDataBound, value);
}
remove {
Events.RemoveHandler(EventItemDataBound, value);
}
}
///
/// Connects this data bound control to the appropriate DataSourceView
/// and hooks up the appropriate event listener for the
/// DataSourceViewChanged event. The return value is the new view (if
/// any) that was connected to. An exception is thrown if there is
/// a problem finding the requested view or data source.
///
private DataSourceView ConnectToDataSourceView() {
if (_currentViewValid && !DesignMode) {
// If the current view is correct, there is no need to reconnect
return _currentView;
}
// Disconnect from old view, if necessary
if ((_currentView != null) && (_currentViewIsFromDataSourceID)) {
// We only care about this event if we are bound through the DataSourceID property
_currentView.DataSourceViewChanged -= new EventHandler(OnDataSourceViewChanged);
}
// Connect to new view
IDataSource ds = null;
string dataSourceID = DataSourceID;
if (dataSourceID.Length != 0) {
// Try to find a DataSource control with the ID specified in DataSourceID
Control control = DataBoundControlHelper.FindControl(this, dataSourceID);
if (control == null) {
throw new HttpException(SR.GetString(SR.DataControl_DataSourceDoesntExist, ID, dataSourceID));
}
ds = control as IDataSource;
if (ds == null) {
throw new HttpException(SR.GetString(SR.DataControl_DataSourceIDMustBeDataControl, ID, dataSourceID));
}
}
if (ds == null) {
// DataSource control was not found, construct a temporary data source to wrap the data
ds = new ReadOnlyDataSource(DataSource, DataMember);
}
else {
// Ensure that both DataSourceID as well as DataSource are not set at the same time
if (DataSource != null) {
throw new InvalidOperationException(SR.GetString(SR.DataControl_MultipleDataSources, ID));
}
}
// IDataSource was found, extract the appropriate view and return it
DataSourceView newView = ds.GetView(DataMember);
if (newView == null) {
throw new InvalidOperationException(SR.GetString(SR.DataControl_ViewNotFound, ID));
}
_currentViewIsFromDataSourceID = IsBoundUsingDataSourceID;
_currentView = newView;
if ((_currentView != null) && (_currentViewIsFromDataSourceID)) {
// We only care about this event if we are bound through the DataSourceID property
_currentView.DataSourceViewChanged += new EventHandler(OnDataSourceViewChanged);
}
_currentViewValid = true;
return _currentView;
}
///
///
protected internal override void CreateChildControls() {
Controls.Clear();
if (ViewState[ItemCountViewStateKey] != null) {
// create the control hierarchy using the view state (and
// not the datasource)
CreateControlHierarchy(false);
}
else {
itemsArray = new ArrayList();
}
ClearChildViewState();
}
///
/// A protected method. Creates a control
/// hierarchy, with or without the data source as specified.
///
protected virtual void CreateControlHierarchy(bool useDataSource) {
IEnumerable dataSource = null;
int count = -1;
if (itemsArray != null) {
itemsArray.Clear();
}
else {
itemsArray = new ArrayList();
}
if (useDataSource == false) {
// ViewState must have a non-null value for ItemCount because we check for
// this in CreateChildControls
count = (int)ViewState[ItemCountViewStateKey];
if (count != -1) {
dataSource = new DummyDataSource(count);
itemsArray.Capacity = count;
}
}
else {
dataSource = GetData();
ICollection collection = dataSource as ICollection;
if (collection != null) {
itemsArray.Capacity = collection.Count;
}
}
if (dataSource != null) {
RepeaterItem item;
ListItemType itemType;
int index = 0;
bool hasSeparators = (separatorTemplate != null);
count = 0;
if (headerTemplate != null) {
CreateItem(-1, ListItemType.Header, useDataSource, null);
}
foreach (object dataItem in dataSource) {
// rather than creating separators after the item, we create the separator
// for the previous item in all iterations of this loop.
// this is so that we don't create a separator for the last item
if (hasSeparators && (count > 0)) {
CreateItem(index - 1, ListItemType.Separator, useDataSource, null);
}
itemType = (index % 2 == 0) ? ListItemType.Item : ListItemType.AlternatingItem;
item = CreateItem(index, itemType, useDataSource, dataItem);
itemsArray.Add(item);
count++;
index++;
}
if (footerTemplate != null) {
CreateItem(-1, ListItemType.Footer, useDataSource, null);
}
}
if (useDataSource) {
// save the number of items contained in the repeater for use in round-trips
ViewState[ItemCountViewStateKey] = ((dataSource != null) ? count : -1);
}
}
protected virtual DataSourceSelectArguments CreateDataSourceSelectArguments() {
return DataSourceSelectArguments.Empty;
}
///
///
private RepeaterItem CreateItem(int itemIndex, ListItemType itemType, bool dataBind, object dataItem) {
RepeaterItem item = CreateItem(itemIndex, itemType);
RepeaterItemEventArgs e = new RepeaterItemEventArgs(item);
InitializeItem(item);
if (dataBind) {
item.DataItem = dataItem;
}
OnItemCreated(e);
Controls.Add(item);
if (dataBind) {
item.DataBind();
OnItemDataBound(e);
item.DataItem = null;
}
return item;
}
///
/// A protected method. Creates a with the specified item type and
/// location within the .
///
protected virtual RepeaterItem CreateItem(int itemIndex, ListItemType itemType) {
return new RepeaterItem(itemIndex, itemType);
}
///
///
///
public override void DataBind() {
// Don't databind to a data source control when the control is in the designer but not top-level
if (IsBoundUsingDataSourceID && DesignMode && (Site == null)) {
return;
}
// do our own databinding
RequiresDataBinding = false;
OnDataBinding(EventArgs.Empty);
// contained items will be databound after they have been created,
// so we don't want to walk the hierarchy here.
}
protected void EnsureDataBound() {
try {
_throwOnDataPropertyChange = true;
if (RequiresDataBinding && DataSourceID.Length > 0) {
DataBind();
}
}
finally {
_throwOnDataPropertyChange = false;
}
}
///
/// Returns an IEnumerable that is the DataSource, which either came
/// from the DataSource property or from the control bound via the
/// DataSourceID property.
///
protected virtual IEnumerable GetData() {
DataSourceView view = ConnectToDataSourceView();
Debug.Assert(_currentViewValid);
if (view != null) {
return view.ExecuteSelect(SelectArguments);
}
return null;
}
///
/// A protected method. Populates iteratively the specified with a
/// sub-hierarchy of child controls.
///
protected virtual void InitializeItem(RepeaterItem item) {
ITemplate contentTemplate = null;
switch (item.ItemType) {
case ListItemType.Header:
contentTemplate = headerTemplate;
break;
case ListItemType.Footer:
contentTemplate = footerTemplate;
break;
case ListItemType.Item:
contentTemplate = itemTemplate;
break;
case ListItemType.AlternatingItem:
contentTemplate = alternatingItemTemplate;
if (contentTemplate == null)
goto case ListItemType.Item;
break;
case ListItemType.Separator:
contentTemplate = separatorTemplate;
break;
}
if (contentTemplate != null) {
contentTemplate.InstantiateIn(item);
}
}
///
///
///
protected override bool OnBubbleEvent(object sender, EventArgs e) {
bool handled = false;
if (e is RepeaterCommandEventArgs) {
OnItemCommand((RepeaterCommandEventArgs)e);
handled = true;
}
return handled;
}
///
///
/// A protected method. Raises the event.
///
protected override void OnDataBinding(EventArgs e) {
base.OnDataBinding(e);
// reset the control state
Controls.Clear();
ClearChildViewState();
// and then create the control hierarchy using the datasource
CreateControlHierarchy(true);
ChildControlsCreated = true;
}
///
/// This method is called when DataMember, DataSource, or DataSourceID is changed.
///
protected virtual void OnDataPropertyChanged() {
if (_throwOnDataPropertyChange) {
throw new HttpException(SR.GetString(SR.DataBoundControl_InvalidDataPropertyChange, ID));
}
if (_inited) {
RequiresDataBinding = true;
}
_currentViewValid = false;
}
protected virtual void OnDataSourceViewChanged(object sender, EventArgs e) {
RequiresDataBinding = true;
}
protected internal override void OnInit(EventArgs e) {
base.OnInit(e);
if (Page != null) {
Page.PreLoad += new EventHandler(this.OnPagePreLoad);
if (!IsViewStateEnabled && Page.IsPostBack) {
RequiresDataBinding = true;
}
}
}
///
/// A protected method. Raises the event.
///
protected virtual void OnItemCommand(RepeaterCommandEventArgs e) {
RepeaterCommandEventHandler onItemCommandHandler = (RepeaterCommandEventHandler)Events[EventItemCommand];
if (onItemCommandHandler != null) onItemCommandHandler(this, e);
}
///
/// A protected method. Raises the event.
///
protected virtual void OnItemCreated(RepeaterItemEventArgs e) {
RepeaterItemEventHandler onItemCreatedHandler = (RepeaterItemEventHandler)Events[EventItemCreated];
if (onItemCreatedHandler != null) onItemCreatedHandler(this, e);
}
///
/// A protected method. Raises the
/// event.
///
protected virtual void OnItemDataBound(RepeaterItemEventArgs e) {
RepeaterItemEventHandler onItemDataBoundHandler = (RepeaterItemEventHandler)Events[EventItemDataBound];
if (onItemDataBoundHandler != null) onItemDataBoundHandler(this, e);
}
protected internal override void OnLoad(EventArgs e) {
_inited = true; // just in case we were added to the page after PreLoad
ConnectToDataSourceView();
if (Page != null && !_pagePreLoadFired && ViewState[ItemCountViewStateKey] == null) {
// If the control was added after PagePreLoad, we still need to databind it because it missed its
// first change in PagePreLoad. If this control was created by a call to a parent control's DataBind
// in Page_Load (with is relatively common), this control will already have been databound even
// though pagePreLoad never fired and the page isn't a postback.
if (!Page.IsPostBack) {
RequiresDataBinding = true;
}
// If the control was added to the page after page.PreLoad, we'll never get the event and we'll
// never databind the control. So if we're catching up and Load happens but PreLoad never happened,
// call DataBind. This may make the control get databound twice if the user called DataBind on the control
// directly in Page.OnLoad, but better to bind twice than never to bind at all.
else if (IsViewStateEnabled) {
RequiresDataBinding = true;
}
}
base.OnLoad(e);
}
private void OnPagePreLoad(object sender, EventArgs e) {
_inited = true;
if (Page != null) {
Page.PreLoad -= new EventHandler(this.OnPagePreLoad);
// Setting RequiresDataBinding to true in OnLoad is too late because the OnLoad page event
// happens before the control.OnLoad method gets called. So a page_load handler on the page
// that calls DataBind won't prevent DataBind from getting called again in PreRender.
if (!Page.IsPostBack) {
RequiresDataBinding = true;
}
// If this is a postback and viewstate is enabled, but we have never bound the control
// before, it is probably because its visibility was changed in the postback. In this
// case, we need to bind the control or it will never appear. This is a common scenario
// for Wizard and MultiView.
if (Page.IsPostBack && IsViewStateEnabled && ViewState[ItemCountViewStateKey] == null) {
RequiresDataBinding = true;
}
_pagePreLoadFired = true;
}
}
protected internal override void OnPreRender(EventArgs e) {
EnsureDataBound();
base.OnPreRender(e);
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- WindowsGrip.cs
- ClockGroup.cs
- PolyBezierSegment.cs
- RelationshipDetailsRow.cs
- ExpandedProjectionNode.cs
- WindowsEditBoxRange.cs
- SafeCryptContextHandle.cs
- EventLogPermissionAttribute.cs
- EntitySetBase.cs
- TTSEvent.cs
- TableStyle.cs
- ThreadNeutralSemaphore.cs
- EtwTrace.cs
- SqlDataSourceFilteringEventArgs.cs
- XmlSchemaIdentityConstraint.cs
- AttributeExtensions.cs
- BitmapCache.cs
- CodePageUtils.cs
- QueryAccessibilityHelpEvent.cs
- PrefixHandle.cs
- CodeBinaryOperatorExpression.cs
- WeakReferenceList.cs
- InvocationExpression.cs
- ComponentEditorForm.cs
- MenuItemAutomationPeer.cs
- StateDesigner.Layouts.cs
- Effect.cs
- ClaimComparer.cs
- SemanticValue.cs
- TypeBuilderInstantiation.cs
- BaseHashHelper.cs
- ToolStripRendererSwitcher.cs
- AutoSizeComboBox.cs
- DataGridItemCollection.cs
- DropShadowBitmapEffect.cs
- ArgumentException.cs
- Sql8ConformanceChecker.cs
- PolyLineSegmentFigureLogic.cs
- DefaultParameterValueAttribute.cs
- Path.cs
- HwndProxyElementProvider.cs
- RewritingSimplifier.cs
- Shared.cs
- DeviceOverridableAttribute.cs
- AssemblyCollection.cs
- ForeignConstraint.cs
- Ticks.cs
- DataBinding.cs
- UrlMappingsSection.cs
- SessionParameter.cs
- Nodes.cs
- SqlDataSourceQueryEditor.cs
- SoapConverter.cs
- HttpClientCertificate.cs
- ClientUtils.cs
- ForceCopyBuildProvider.cs
- Constant.cs
- RemotingConfiguration.cs
- PerformanceCounter.cs
- NumberFormatInfo.cs
- ConvertersCollection.cs
- DesigntimeLicenseContextSerializer.cs
- ConfigXmlComment.cs
- SignedInfo.cs
- WebPartDisplayMode.cs
- ExpressionBuilder.cs
- WorkflowMarkupElementEventArgs.cs
- DataBoundControlHelper.cs
- WindowsAuthenticationEventArgs.cs
- QilDataSource.cs
- ConfigurationLocation.cs
- ApplicationSecurityManager.cs
- ParameterDataSourceExpression.cs
- CodeLabeledStatement.cs
- followingsibling.cs
- mediapermission.cs
- MailAddressCollection.cs
- FormDocumentDesigner.cs
- OrderedDictionary.cs
- DefaultClaimSet.cs
- SafeEventLogWriteHandle.cs
- Geometry.cs
- ConnectivityStatus.cs
- TileBrush.cs
- RandomNumberGenerator.cs
- ScrollChrome.cs
- HealthMonitoringSection.cs
- PolicyUnit.cs
- QueueNameHelper.cs
- PreloadedPackages.cs
- TableStyle.cs
- FilterEventArgs.cs
- SiteIdentityPermission.cs
- DecoderNLS.cs
- XmlCharCheckingWriter.cs
- PrintPreviewGraphics.cs
- ComAwareEventInfo.cs
- SecurityCapabilities.cs
- XmlValidatingReader.cs
- SafeProcessHandle.cs