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 160 161 162 163 164 165 166
|
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Web.DynamicData.Util;
using System.Web.Resources;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace System.Web.DynamicData {
/// <summary>
/// DynamicControlParameter is similar to ControlParameter, but understainds higher level concepts. e.g. in a
/// master-details scenario using a GridView and DetailsView, you only need to point the DetailsView's datasource
/// to the GridView (using a DynamicControlParameter), and it does the right thing. This works even for
/// multi-part primary keys
/// </summary>
public class DynamicControlParameter : Parameter, IWhereParametersProvider {
/// <summary>
/// </summary>
public DynamicControlParameter() { }
/// <summary>
/// </summary>
public DynamicControlParameter(string controlId) { ControlId = controlId; }
/// <summary>
/// The ID of the control from which the parameter gets its data
/// </summary>
public string ControlId { get; set; }
/// <summary>
/// See IWhereParametersProvider.GetWhereParameters
/// </summary>
public virtual IEnumerable<Parameter> GetWhereParameters(IDynamicDataSource dataSource) {
Debug.Assert(dataSource != null);
// Find the control that the ControlParameter uses
Control control = Misc.FindControl((Control)dataSource, ControlId);
if (control == null) {
throw new InvalidOperationException(String.Format(
CultureInfo.CurrentCulture, DynamicDataResources.DynamicControlParameter_DynamicDataSourceControlNotFound, ControlId));
}
// If the control is itself a parameter provider, delegate to it
var whereParametersProvider = control as IWhereParametersProvider;
if (whereParametersProvider != null) {
return whereParametersProvider.GetWhereParameters(dataSource);
}
IControlParameterTarget paramTarget = DynamicDataManager.GetControlParameterTarget(control);
if (paramTarget == null) {
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture,
DynamicDataResources.DynamicControlParameter_DynamicDataSourceControlCannotBeUsedAsParent, ControlId));
}
string columnName = Name;
MetaColumn column = null;
MetaTable table = MetaTableHelper.GetTableWithFullFallback(dataSource, HttpContext.Current.ToWrapper());
if (!String.IsNullOrEmpty(columnName)) {
column = table.GetColumn(columnName);
}
else {
// There was no Name attribute telling us what field to filter, but maybe
// the control given us data has that info
column = paramTarget.FilteredColumn;
}
if (column == null) {
// If there is no specific column, we're setting the primary key
if (paramTarget.Table != table) {
throw new Exception(String.Format(CultureInfo.CurrentCulture,
DynamicDataResources.DynamicControlParameter_InvalidPK,
ControlId, paramTarget.Table, table.Name));
}
return GetPrimaryKeyControlWhereParameters(control, paramTarget);
}
else if (column is MetaForeignKeyColumn) {
return GetForeignKeyControlWhereParameters(control, paramTarget, (MetaForeignKeyColumn)column);
}
return GetPropertyControlWhereParameters(control, paramTarget, column);
}
private IEnumerable<Parameter> GetPropertyControlWhereParameters(Control control,
IControlParameterTarget paramTarget, MetaColumn column) {
ControlParameter controlParameter = new ControlParameter() {
Name = column.Name,
ControlID = control.UniqueID,
PropertyName = paramTarget.GetPropertyNameExpression(column.Name)
};
DataSourceUtil.SetParameterTypeCodeAndDbType(controlParameter, column);
yield return controlParameter;
}
private IEnumerable<Parameter> GetPrimaryKeyControlWhereParameters(Control control,
IControlParameterTarget paramTarget) {
MetaTable parentTable = paramTarget.Table;
if (parentTable != null) {
// For each PK column in the table, we need to create a ControlParameter
foreach (var keyColumn in parentTable.PrimaryKeyColumns) {
var controlParameter = new ControlParameter() {
Name = keyColumn.Name,
ControlID = control.UniqueID,
PropertyName = paramTarget.GetPropertyNameExpression(keyColumn.Name)
};
DataSourceUtil.SetParameterTypeCodeAndDbType(controlParameter, keyColumn);
yield return controlParameter;
}
}
}
private IEnumerable<Parameter> GetForeignKeyControlWhereParameters(Control control,
IControlParameterTarget paramTarget, MetaForeignKeyColumn column) {
MetaTable parentTable = paramTarget.Table;
if (parentTable != null) {
string namePrefix = String.Empty;
// Make sure the data types match
if (column.ColumnType != parentTable.EntityType) {
throw new Exception(String.Format(CultureInfo.CurrentCulture,
DynamicDataResources.DynamicControlParameter_DynamicDataSourceColumnNotCompatibleWithTable,
column.DisplayName, parentTable.Name));
}
// For each underlying FK, we need to create a ControlParameter
Debug.Assert(column.ForeignKeyNames.Count == parentTable.PrimaryKeyColumns.Count);
int index = 0;
foreach (var fkName in column.ForeignKeyNames) {
MetaColumn parentTablePKColumn = parentTable.PrimaryKeyColumns[index++];
var controlParameter = new ControlParameter() {
Name = fkName,
ControlID = control.UniqueID,
PropertyName = paramTarget.GetPropertyNameExpression(parentTablePKColumn.Name)
};
DataSourceUtil.SetParameterTypeCodeAndDbType(controlParameter, parentTablePKColumn);
yield return controlParameter;
}
}
}
/// <summary>
/// same as base
/// </summary>
/// <param name="context"></param>
/// <param name="control"></param>
/// <returns></returns>
protected override object Evaluate(HttpContext context, Control control) {
// If this gets called, it means we never had a chance to expand the parameter. Give an error
// telling the user to use a DynamicDataManager
throw new InvalidOperationException(String.Format(
CultureInfo.CurrentCulture, DynamicDataResources.DynamicParameter_NeedExpansion, typeof(DynamicControlParameter).Name));
}
}
}
|