1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
|
//------------------------------------------------------------------------------
// <copyright file="CompositeDataBoundControl.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
namespace System.Web.UI.WebControls {
using System;
using System.Collections;
using System.ComponentModel;
public abstract class CompositeDataBoundControl : DataBoundControl, INamingContainer {
internal const string ItemCountViewStateKey = "_!ItemCount";
private string _updateMethod;
private string _insertMethod;
private string _deleteMethod;
protected override bool IsUsingModelBinders {
get {
return !String.IsNullOrEmpty(SelectMethod) ||
!String.IsNullOrEmpty(UpdateMethod) ||
!String.IsNullOrEmpty(DeleteMethod) ||
!String.IsNullOrEmpty(InsertMethod);
}
}
/// <summary>
/// The name of the method on the page which is called when this Control does an update operation.
/// </summary>
protected internal string UpdateMethod {
get {
return _updateMethod ?? String.Empty;
}
set {
if (!String.Equals(_updateMethod, value, StringComparison.OrdinalIgnoreCase)) {
_updateMethod = value;
OnDataPropertyChanged();
}
}
}
/// <summary>
/// The name of the method on the page which is called when this Control does a delete operation.
/// </summary>
protected internal string DeleteMethod {
get {
return _deleteMethod ?? String.Empty;
}
set {
if (!String.Equals(_deleteMethod, value, StringComparison.OrdinalIgnoreCase)) {
_deleteMethod = value;
OnDataPropertyChanged();
}
}
}
/// <summary>
/// The name of the method on the page which is called when this Control does an insert operation.
/// </summary>
protected internal string InsertMethod {
get {
return _insertMethod ?? String.Empty;
}
set {
if (!String.Equals(_insertMethod, value, StringComparison.OrdinalIgnoreCase)) {
_insertMethod = value;
OnDataPropertyChanged();
}
}
}
public override ControlCollection Controls {
get {
EnsureChildControls();
return base.Controls;
}
}
/// <summary>
/// Overriden by DataBoundControl to determine if the control should
/// recreate its control hierarchy based on values in view state.
/// If the control hierarchy should be created, i.e. view state does
/// exist, it calls CreateChildControls with a dummy (empty) data source
/// which is usable for enumeration purposes only.
/// </summary>
protected internal override void CreateChildControls() {
Controls.Clear();
object controlCount = ViewState[ItemCountViewStateKey];
if (controlCount == null && RequiresDataBinding) {
EnsureDataBound();
}
if (controlCount != null && ((int)controlCount) != -1) {
DummyDataSource dummyDataSource = new DummyDataSource((int)controlCount);
CreateChildControls(dummyDataSource, false);
ClearChildViewState();
}
}
/// <summary>
/// Performs the work of creating the control hierarchy based on a data source.
/// When dataBinding is true, the specified data source contains real
/// data, and the data is supposed to be pushed into the UI.
/// When dataBinding is false, the specified data source is a dummy data
/// source, that allows enumerating the right number of items, but the items
/// themselves are null and do not contain data. In this case, the recreated
/// control hierarchy reinitializes its state from view state.
/// It enables a DataBoundControl to encapsulate the logic of creating its
/// control hierarchy in both modes into a single code path.
/// </summary>
/// <param name="dataSource">
/// The data source to be used to enumerate items.
/// </param>
/// <param name="dataBinding">
/// Whether the method has been called from DataBind or not.
/// </param>
/// <returns>
/// The number of items created based on the data source. Put another way, its
/// the number of items enumerated from the data source.
/// </returns>
protected abstract int CreateChildControls(IEnumerable dataSource,
bool dataBinding);
/// <summary>
/// Overriden by DataBoundControl to use its properties to determine the real
/// data source that the control should bind to. It then clears the existing
/// control hierarchy, and calls createChildControls to create a new control
/// hierarchy based on the resolved data source.
/// The implementation resolves various data source related properties to
/// arrive at the appropriate IEnumerable implementation to use as the real
/// data source.
/// When resolving data sources, the DataSourceControlID takes highest precedence.
/// In this mode, DataMember is used to access the appropriate list from the
/// DataControl.
/// If DataSourceControlID is not set, the value of the DataSource property is used.
/// In this second alternative, DataMember is used to extract the appropriate
/// list if the control has been handed an IListSource as a data source.
/// </summary>
protected internal override void PerformDataBinding(IEnumerable data) {
base.PerformDataBinding(data);
Controls.Clear();
ClearChildViewState();
TrackViewState();
int controlCount = CreateChildControls(data, true);
ChildControlsCreated = true;
ViewState[ItemCountViewStateKey] = controlCount;
}
}
}
|