Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / xsp / System / Web / UI / WebControls / DataBoundControl.cs / 1305376 / DataBoundControl.cs
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//-----------------------------------------------------------------------------
namespace System.Web.UI.WebControls {
using System;
using System.Collections;
using System.ComponentModel;
using System.Web.Util;
using System.Web.UI.WebControls.Adapters;
///
/// A DataBoundControl is bound to a data source and generates its
/// user interface (or child control hierarchy typically), by enumerating
/// the items in the data source it is bound to.
/// DataBoundControl is an abstract base class that defines the common
/// characteristics of all controls that use a list as a data source, such as
/// DataGrid, DataBoundTable, ListBox etc. It encapsulates the logic
/// of how a data-bound control binds to collections or DataControl instances.
///
[
Designer("System.Web.UI.Design.WebControls.DataBoundControlDesigner, " + AssemblyRef.SystemDesign),
]
public abstract class DataBoundControl : BaseDataBoundControl {
private DataSourceView _currentView;
private bool _currentViewIsFromDataSourceID;
private bool _currentViewValid;
private IDataSource _currentDataSource;
private bool _currentDataSourceValid;
private DataSourceSelectArguments _arguments;
private bool _pagePreLoadFired;
private bool _ignoreDataSourceViewChanged;
private const string DataBoundViewStateKey = "_!DataBound";
///
/// The name of the list that the DataBoundControl should bind to when
/// its data source contains more than one list of data items.
///
[
DefaultValue(""),
Themeable(false),
WebCategory("Data"),
WebSysDescription(SR.DataBoundControl_DataMember)
]
public virtual string DataMember {
get {
object o = ViewState["DataMember"];
if (o != null) {
return (string)o;
}
return String.Empty;
}
set {
ViewState["DataMember"] = value;
OnDataPropertyChanged();
}
}
///
[
IDReferenceProperty(typeof(DataSourceControl))
]
public override string DataSourceID {
get {
return base.DataSourceID;
}
set {
base.DataSourceID = value;
}
}
[
Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
]
public IDataSource DataSourceObject {
get {
return GetDataSource();
}
}
protected DataSourceSelectArguments SelectArguments {
get {
if (_arguments == null) {
_arguments = CreateDataSourceSelectArguments();
}
return _arguments;
}
}
///
/// 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
_currentDataSource = GetDataSource();
string dataMember = DataMember;
if (_currentDataSource == null) {
// DataSource control was not found, construct a temporary data source to wrap the data
_currentDataSource = 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));
}
}
_currentDataSourceValid = true;
// IDataSource was found, extract the appropriate view and return it
DataSourceView newView = _currentDataSource.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;
}
///
/// Override to create the DataSourceSelectArguments that will be passed to the view's Select command.
///
protected virtual DataSourceSelectArguments CreateDataSourceSelectArguments() {
return DataSourceSelectArguments.Empty;
}
///
/// Gets the DataSourceView of the IDataSource that this control is
/// bound to, if any.
///
protected virtual DataSourceView GetData() {
DataSourceView view = ConnectToDataSourceView();
Debug.Assert(_currentViewValid);
return view;
}
///
/// Gets the IDataSource that this control is bound to, if any.
/// Because this method can be called directly by derived classes, it's virtual so data can be retrieved
/// from data sources that don't live on the page.
///
protected virtual IDataSource GetDataSource() {
if (!DesignMode && _currentDataSourceValid && (_currentDataSource != null)) {
return _currentDataSource;
}
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));
}
}
return ds;
}
protected void MarkAsDataBound() {
ViewState[DataBoundViewStateKey] = true;
}
protected override void OnDataPropertyChanged() {
_currentViewValid = false;
_currentDataSourceValid = false;
base.OnDataPropertyChanged();
}
///
/// This method is called when the DataSourceView raises a DataSourceViewChanged event.
///
protected virtual void OnDataSourceViewChanged(object sender, EventArgs e) {
if (!_ignoreDataSourceViewChanged) {
RequiresDataBinding = true;
}
}
private void OnDataSourceViewSelectCallback(IEnumerable data) {
_ignoreDataSourceViewChanged = false;
// We only call OnDataBinding here if we haven't done it already in PerformSelect().
if (DataSourceID.Length > 0) {
OnDataBinding(EventArgs.Empty);
}
if (AdapterInternal != null) {
DataBoundControlAdapter dataBoundControlAdapter = AdapterInternal as DataBoundControlAdapter;
if(dataBoundControlAdapter != null) {
dataBoundControlAdapter.PerformDataBinding(data);
}
else {
PerformDataBinding(data);
}
}
else {
PerformDataBinding(data);
}
OnDataBound(EventArgs.Empty);
}
protected internal override void OnLoad(EventArgs e) {
ConfirmInitState();
ConnectToDataSourceView();
if (Page != null && !_pagePreLoadFired && ViewState[DataBoundViewStateKey] == 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);
}
protected override void OnPagePreLoad(object sender, EventArgs e) {
base.OnPagePreLoad(sender, e);
if (Page != null) {
// 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.
else if (IsViewStateEnabled && ViewState[DataBoundViewStateKey] == null) {
RequiresDataBinding = true;
}
}
_pagePreLoadFired = true;
}
///
/// This method should be overridden by databound controls to perform their databinding.
/// Overriding this method instead of DataBind() will allow the DataBound control developer
/// to not worry about DataBinding events to be called in the right order.
///
protected internal virtual void PerformDataBinding(IEnumerable data) {
}
///
/// Issues an asynchronous request for data to the data source using the arguments from CreateDataSourceSelectArguments.
///
protected override void PerformSelect() {
// We need to call OnDataBinding here if we're potentially bound to a DataSource (instead of a DataSourceID)
// because the databinding statement that is the datasource needs to be evaluated before the call to GetData()
// happens, because we don't rebind when the datasource is changed unless DataSourceID.Length > 0.
if (DataSourceID.Length == 0) {
OnDataBinding(EventArgs.Empty);
}
DataSourceView view = GetData();
_arguments = CreateDataSourceSelectArguments();
_ignoreDataSourceViewChanged = true;
RequiresDataBinding = false;
MarkAsDataBound();
view.Select(_arguments, OnDataSourceViewSelectCallback);
}
protected override void ValidateDataSource(object dataSource) {
if ((dataSource == null) ||
(dataSource is IListSource) ||
(dataSource is IEnumerable) ||
(dataSource is IDataSource)) {
return;
}
throw new InvalidOperationException(SR.GetString(SR.DataBoundControl_InvalidDataSourceType));
}
}
}
// 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.Web.Util;
using System.Web.UI.WebControls.Adapters;
///
/// A DataBoundControl is bound to a data source and generates its
/// user interface (or child control hierarchy typically), by enumerating
/// the items in the data source it is bound to.
/// DataBoundControl is an abstract base class that defines the common
/// characteristics of all controls that use a list as a data source, such as
/// DataGrid, DataBoundTable, ListBox etc. It encapsulates the logic
/// of how a data-bound control binds to collections or DataControl instances.
///
[
Designer("System.Web.UI.Design.WebControls.DataBoundControlDesigner, " + AssemblyRef.SystemDesign),
]
public abstract class DataBoundControl : BaseDataBoundControl {
private DataSourceView _currentView;
private bool _currentViewIsFromDataSourceID;
private bool _currentViewValid;
private IDataSource _currentDataSource;
private bool _currentDataSourceValid;
private DataSourceSelectArguments _arguments;
private bool _pagePreLoadFired;
private bool _ignoreDataSourceViewChanged;
private const string DataBoundViewStateKey = "_!DataBound";
///
/// The name of the list that the DataBoundControl should bind to when
/// its data source contains more than one list of data items.
///
[
DefaultValue(""),
Themeable(false),
WebCategory("Data"),
WebSysDescription(SR.DataBoundControl_DataMember)
]
public virtual string DataMember {
get {
object o = ViewState["DataMember"];
if (o != null) {
return (string)o;
}
return String.Empty;
}
set {
ViewState["DataMember"] = value;
OnDataPropertyChanged();
}
}
///
[
IDReferenceProperty(typeof(DataSourceControl))
]
public override string DataSourceID {
get {
return base.DataSourceID;
}
set {
base.DataSourceID = value;
}
}
[
Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
]
public IDataSource DataSourceObject {
get {
return GetDataSource();
}
}
protected DataSourceSelectArguments SelectArguments {
get {
if (_arguments == null) {
_arguments = CreateDataSourceSelectArguments();
}
return _arguments;
}
}
///
/// 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
_currentDataSource = GetDataSource();
string dataMember = DataMember;
if (_currentDataSource == null) {
// DataSource control was not found, construct a temporary data source to wrap the data
_currentDataSource = 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));
}
}
_currentDataSourceValid = true;
// IDataSource was found, extract the appropriate view and return it
DataSourceView newView = _currentDataSource.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;
}
///
/// Override to create the DataSourceSelectArguments that will be passed to the view's Select command.
///
protected virtual DataSourceSelectArguments CreateDataSourceSelectArguments() {
return DataSourceSelectArguments.Empty;
}
///
/// Gets the DataSourceView of the IDataSource that this control is
/// bound to, if any.
///
protected virtual DataSourceView GetData() {
DataSourceView view = ConnectToDataSourceView();
Debug.Assert(_currentViewValid);
return view;
}
///
/// Gets the IDataSource that this control is bound to, if any.
/// Because this method can be called directly by derived classes, it's virtual so data can be retrieved
/// from data sources that don't live on the page.
///
protected virtual IDataSource GetDataSource() {
if (!DesignMode && _currentDataSourceValid && (_currentDataSource != null)) {
return _currentDataSource;
}
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));
}
}
return ds;
}
protected void MarkAsDataBound() {
ViewState[DataBoundViewStateKey] = true;
}
protected override void OnDataPropertyChanged() {
_currentViewValid = false;
_currentDataSourceValid = false;
base.OnDataPropertyChanged();
}
///
/// This method is called when the DataSourceView raises a DataSourceViewChanged event.
///
protected virtual void OnDataSourceViewChanged(object sender, EventArgs e) {
if (!_ignoreDataSourceViewChanged) {
RequiresDataBinding = true;
}
}
private void OnDataSourceViewSelectCallback(IEnumerable data) {
_ignoreDataSourceViewChanged = false;
// We only call OnDataBinding here if we haven't done it already in PerformSelect().
if (DataSourceID.Length > 0) {
OnDataBinding(EventArgs.Empty);
}
if (AdapterInternal != null) {
DataBoundControlAdapter dataBoundControlAdapter = AdapterInternal as DataBoundControlAdapter;
if(dataBoundControlAdapter != null) {
dataBoundControlAdapter.PerformDataBinding(data);
}
else {
PerformDataBinding(data);
}
}
else {
PerformDataBinding(data);
}
OnDataBound(EventArgs.Empty);
}
protected internal override void OnLoad(EventArgs e) {
ConfirmInitState();
ConnectToDataSourceView();
if (Page != null && !_pagePreLoadFired && ViewState[DataBoundViewStateKey] == 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);
}
protected override void OnPagePreLoad(object sender, EventArgs e) {
base.OnPagePreLoad(sender, e);
if (Page != null) {
// 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.
else if (IsViewStateEnabled && ViewState[DataBoundViewStateKey] == null) {
RequiresDataBinding = true;
}
}
_pagePreLoadFired = true;
}
///
/// This method should be overridden by databound controls to perform their databinding.
/// Overriding this method instead of DataBind() will allow the DataBound control developer
/// to not worry about DataBinding events to be called in the right order.
///
protected internal virtual void PerformDataBinding(IEnumerable data) {
}
///
/// Issues an asynchronous request for data to the data source using the arguments from CreateDataSourceSelectArguments.
///
protected override void PerformSelect() {
// We need to call OnDataBinding here if we're potentially bound to a DataSource (instead of a DataSourceID)
// because the databinding statement that is the datasource needs to be evaluated before the call to GetData()
// happens, because we don't rebind when the datasource is changed unless DataSourceID.Length > 0.
if (DataSourceID.Length == 0) {
OnDataBinding(EventArgs.Empty);
}
DataSourceView view = GetData();
_arguments = CreateDataSourceSelectArguments();
_ignoreDataSourceViewChanged = true;
RequiresDataBinding = false;
MarkAsDataBound();
view.Select(_arguments, OnDataSourceViewSelectCallback);
}
protected override void ValidateDataSource(object dataSource) {
if ((dataSource == null) ||
(dataSource is IListSource) ||
(dataSource is IEnumerable) ||
(dataSource is IDataSource)) {
return;
}
throw new InvalidOperationException(SR.GetString(SR.DataBoundControl_InvalidDataSourceType));
}
}
}
// 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
- ImageInfo.cs
- CharEntityEncoderFallback.cs
- IdentityReference.cs
- MenuItem.cs
- LocalizationParserHooks.cs
- DES.cs
- PolicyValidator.cs
- CodeObjectCreateExpression.cs
- Decorator.cs
- Animatable.cs
- GridViewUpdateEventArgs.cs
- WebReferenceCollection.cs
- XsltSettings.cs
- CalendarDateRangeChangingEventArgs.cs
- Screen.cs
- SvcMapFileLoader.cs
- MSG.cs
- DragAssistanceManager.cs
- FamilyTypeface.cs
- TextMessageEncoder.cs
- Graphics.cs
- VBCodeProvider.cs
- counter.cs
- IteratorFilter.cs
- EmptyEnumerable.cs
- TextEmbeddedObject.cs
- AffineTransform3D.cs
- ValueChangedEventManager.cs
- LongValidator.cs
- CatalogUtil.cs
- ConfigurationElement.cs
- NativeCppClassAttribute.cs
- ConnectionPoolManager.cs
- Section.cs
- DataContext.cs
- precedingquery.cs
- DesignerUtility.cs
- SoapHeaders.cs
- MenuCommandService.cs
- HideDisabledControlAdapter.cs
- GridViewItemAutomationPeer.cs
- ServerIdentity.cs
- CompiledRegexRunner.cs
- HttpModuleCollection.cs
- LinearGradientBrush.cs
- IIS7UserPrincipal.cs
- SmtpNegotiateAuthenticationModule.cs
- XsdDataContractImporter.cs
- ThousandthOfEmRealPoints.cs
- TraceSwitch.cs
- CryptoKeySecurity.cs
- SafeBitVector32.cs
- ListQueryResults.cs
- Completion.cs
- FlowPosition.cs
- PtsCache.cs
- ConfigurationValidatorAttribute.cs
- GeometryHitTestResult.cs
- UndoManager.cs
- ConsoleKeyInfo.cs
- EditingCoordinator.cs
- PropagatorResult.cs
- Image.cs
- AnimationTimeline.cs
- TraceSwitch.cs
- BuiltInPermissionSets.cs
- RequestSecurityTokenForRemoteTokenFactory.cs
- TextBoxView.cs
- BinHexDecoder.cs
- PropertyItemInternal.cs
- EventDrivenDesigner.cs
- clipboard.cs
- NavigationPropertyEmitter.cs
- SqlFacetAttribute.cs
- NominalTypeEliminator.cs
- XmlExpressionDumper.cs
- SecurityHelper.cs
- ListMarkerSourceInfo.cs
- SudsParser.cs
- AnnotationResource.cs
- OptimalBreakSession.cs
- TextBox.cs
- KeyNotFoundException.cs
- coordinatorfactory.cs
- SQLDecimalStorage.cs
- HttpApplication.cs
- ReachBasicContext.cs
- ExpandoObject.cs
- BitmapPalettes.cs
- FolderBrowserDialog.cs
- BitmapFrame.cs
- SafeFileHandle.cs
- Process.cs
- CellTreeNode.cs
- SizeAnimationBase.cs
- DoubleLinkListEnumerator.cs
- PriorityChain.cs
- IntSecurity.cs
- SetterBaseCollection.cs
- DatePickerDateValidationErrorEventArgs.cs