You've already forked linux-packaging-mono
Imported Upstream version 4.0.0~alpha1
Former-commit-id: 806294f5ded97629b74c85c09952f2a74fe182d9
This commit is contained in:
16
external/referencesource/System.Web.DynamicData/DynamicData/ContainerType.cs
vendored
Normal file
16
external/referencesource/System.Web.DynamicData/DynamicData/ContainerType.cs
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
namespace System.Web.DynamicData {
|
||||
|
||||
/// <summary>
|
||||
/// A data control container type
|
||||
/// </summary>
|
||||
public enum ContainerType {
|
||||
/// <summary>
|
||||
/// A list container, such as ListView, GridView, Repeater (or a control implementing IDataBoundListControl)
|
||||
/// </summary>
|
||||
List,
|
||||
/// <summary>
|
||||
/// An item container, such as DetailsView, FormView (or a control implementing IDataBoundItemControl)
|
||||
/// </summary>
|
||||
Item
|
||||
}
|
||||
}
|
31
external/referencesource/System.Web.DynamicData/DynamicData/ContextConfiguration.cs
vendored
Normal file
31
external/referencesource/System.Web.DynamicData/DynamicData/ContextConfiguration.cs
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Permissions;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel;
|
||||
using System.Web.DynamicData.ModelProviders;
|
||||
|
||||
namespace System.Web.DynamicData {
|
||||
/// <summary>
|
||||
/// Allows for providing extra config information to a context
|
||||
/// </summary>
|
||||
public class ContextConfiguration {
|
||||
/// <summary>
|
||||
/// An optional factory for obtaining a metadata source for a given entity type
|
||||
/// </summary>
|
||||
public Func<Type, TypeDescriptionProvider> MetadataProviderFactory { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// scaffold all tables
|
||||
/// </summary>
|
||||
public bool ScaffoldAllTables { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
[SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "This can be set by the user to support inline dictionary intializers")]
|
||||
public ContextConfiguration() {
|
||||
MetadataProviderFactory = type => new AssociatedMetadataTypeTypeDescriptionProvider(type);
|
||||
}
|
||||
}
|
||||
}
|
160
external/referencesource/System.Web.DynamicData/DynamicData/ControlFilterExpression.cs
vendored
Normal file
160
external/referencesource/System.Web.DynamicData/DynamicData/ControlFilterExpression.cs
vendored
Normal file
@ -0,0 +1,160 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Web.Resources;
|
||||
using System.Web.UI;
|
||||
using System.Web.UI.WebControls;
|
||||
using System.Web.UI.WebControls.Expressions;
|
||||
|
||||
namespace System.Web.DynamicData {
|
||||
/// <summary>
|
||||
/// A Dynamic Data-specific implementation of DataSourceExpression that modifies an IQueryable based on a data key (selected row)
|
||||
/// in a data bound controls such as GridView, ListView, DetailsView, or FormView.
|
||||
/// If the Column property is left empty, the control treats the data key as the primary key of current table (this is useful
|
||||
/// in a List-Details scenario where the databound control and the datasource are displaying items of the same type). If the
|
||||
/// Column property is not empty, this control treats the data key as a foreign key (this is useful in a Parent-Children scenario,
|
||||
/// where the databound control is displaying a list of Categories, and the data source is to be filtered to only display the
|
||||
/// Products that belong to the selected Category).
|
||||
/// </summary>
|
||||
public class ControlFilterExpression : DataSourceExpression {
|
||||
private PropertyExpression _propertyExpression;
|
||||
/// <summary>
|
||||
/// The ID of a data-bound control such as a GridView, ListView, DetailsView, or FormView whose data key will be used to build
|
||||
/// the expression that gets used in a QueryExtender.
|
||||
/// </summary>
|
||||
[SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "ID", Justification = "The property refers to the ID property of a Control")]
|
||||
public string ControlID { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Optional property which when set indicates that the data key should be treated as a foreign key.
|
||||
/// </summary>
|
||||
public string Column { get; set; }
|
||||
|
||||
private PropertyExpression Expression {
|
||||
get {
|
||||
if (_propertyExpression == null) {
|
||||
_propertyExpression = new PropertyExpression();
|
||||
}
|
||||
return _propertyExpression;
|
||||
}
|
||||
}
|
||||
|
||||
public override void SetContext(Control owner, HttpContext context, IQueryableDataSource dataSource) {
|
||||
base.SetContext(owner, context, dataSource);
|
||||
|
||||
Owner.Page.InitComplete += new EventHandler(Page_InitComplete);
|
||||
Owner.Page.LoadComplete += new EventHandler(Page_LoadComplete);
|
||||
}
|
||||
|
||||
private void Page_InitComplete(object sender, EventArgs e) {
|
||||
if (!Owner.Page.IsPostBack) {
|
||||
// Do not reconfigure the Expression on postback. It's values should be preserved via ViewState.
|
||||
Control control = FindTargetControl();
|
||||
MetaTable table = DataSource.GetMetaTable();
|
||||
|
||||
if (String.IsNullOrEmpty(Column)) {
|
||||
foreach (var param in GetPrimaryKeyControlParameters(control, table)) {
|
||||
Expression.Parameters.Add(param);
|
||||
}
|
||||
} else {
|
||||
MetaForeignKeyColumn column = (MetaForeignKeyColumn)table.GetColumn(Column);
|
||||
foreach (var param in GetForeignKeyControlParameters(control, column)) {
|
||||
Expression.Parameters.Add(param);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Expression.SetContext(Owner, Context, DataSource);
|
||||
}
|
||||
|
||||
private Control FindTargetControl() {
|
||||
Control control = Misc.FindControl(Owner, ControlID);
|
||||
if (control == null) {
|
||||
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture,
|
||||
DynamicDataResources.ControlFilterExpression_CouldNotFindControlID,
|
||||
Owner.ID,
|
||||
ControlID));
|
||||
}
|
||||
return control;
|
||||
}
|
||||
|
||||
private void Page_LoadComplete(object sender, EventArgs e) {
|
||||
Expression.Parameters.UpdateValues(Context, Owner);
|
||||
}
|
||||
|
||||
protected override object SaveViewState() {
|
||||
Pair p = new Pair();
|
||||
p.First = base.SaveViewState();
|
||||
p.Second = ((IStateManager)Expression.Parameters).SaveViewState();
|
||||
return p;
|
||||
}
|
||||
|
||||
protected override void LoadViewState(object savedState) {
|
||||
Pair p = (Pair)savedState;
|
||||
base.LoadViewState(p.First);
|
||||
if (p.Second != null) {
|
||||
((IStateManager)Expression.Parameters).LoadViewState(p.Second);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void TrackViewState() {
|
||||
base.TrackViewState();
|
||||
((IStateManager)Expression.Parameters).TrackViewState();
|
||||
}
|
||||
|
||||
private IEnumerable<Parameter> GetPrimaryKeyControlParameters(Control control, MetaTable table) {
|
||||
// For each PK column in the table, we need to create a ControlParameter
|
||||
var nameColumnMapping = table.PrimaryKeyColumns.ToDictionary(c => c.Name);
|
||||
return GetControlParameters(control, nameColumnMapping);
|
||||
}
|
||||
|
||||
private IEnumerable<Parameter> GetForeignKeyControlParameters(Control control, MetaForeignKeyColumn column) {
|
||||
// For each underlying FK, we need to create a ControlParameter
|
||||
MetaTable otherTable = column.ParentTable;
|
||||
Dictionary<string, MetaColumn> nameColumnMapping = CreateColumnMapping(column, otherTable.PrimaryKeyColumns);
|
||||
return GetControlParameters(control, nameColumnMapping);
|
||||
}
|
||||
|
||||
private static Dictionary<string, MetaColumn> CreateColumnMapping(MetaForeignKeyColumn column, IList<MetaColumn> columns) {
|
||||
var names = column.ForeignKeyNames;
|
||||
Debug.Assert(names.Count == columns.Count);
|
||||
Dictionary<string, MetaColumn> nameColumnMapping = new Dictionary<string, MetaColumn>();
|
||||
for (int i = 0; i < names.Count; i++) {
|
||||
// Get the filter expression for this foreign key name
|
||||
string filterExpression = column.GetFilterExpression(names[i]);
|
||||
nameColumnMapping[filterExpression] = columns[i];
|
||||
}
|
||||
return nameColumnMapping;
|
||||
}
|
||||
|
||||
internal static IEnumerable<Parameter> GetControlParameters(Control control, IDictionary<string, MetaColumn> nameColumnMapping) {
|
||||
IControlParameterTarget target = null;
|
||||
|
||||
target = DynamicDataManager.GetControlParameterTarget(control);
|
||||
Debug.Assert(target != null);
|
||||
|
||||
foreach (var entry in nameColumnMapping) {
|
||||
string parameterName = entry.Key;
|
||||
MetaColumn column = entry.Value;
|
||||
|
||||
ControlParameter controlParameter = new ControlParameter() {
|
||||
Name = parameterName,
|
||||
ControlID = control.UniqueID
|
||||
};
|
||||
if (target != null) {
|
||||
// this means the relationship consists of more than one key and we need to expand the property name
|
||||
controlParameter.PropertyName = target.GetPropertyNameExpression(column.Name);
|
||||
}
|
||||
DataSourceUtil.SetParameterTypeCodeAndDbType(controlParameter, column);
|
||||
yield return controlParameter;
|
||||
}
|
||||
}
|
||||
|
||||
public override IQueryable GetQueryable(IQueryable source) {
|
||||
return Expression.GetQueryable(source);
|
||||
}
|
||||
}
|
||||
}
|
40
external/referencesource/System.Web.DynamicData/DynamicData/DataBoundControlParameterTarget.cs
vendored
Normal file
40
external/referencesource/System.Web.DynamicData/DynamicData/DataBoundControlParameterTarget.cs
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
namespace System.Web.DynamicData {
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web.UI;
|
||||
using System.Web.UI.WebControls;
|
||||
using System.Globalization;
|
||||
|
||||
internal class DataBoundControlParameterTarget : IControlParameterTarget {
|
||||
private Control _control;
|
||||
public DataBoundControlParameterTarget(Control control) {
|
||||
if (control == null) {
|
||||
throw new ArgumentNullException("control");
|
||||
}
|
||||
_control = control;
|
||||
}
|
||||
|
||||
public MetaTable Table {
|
||||
get {
|
||||
return _control.FindMetaTable();
|
||||
}
|
||||
}
|
||||
|
||||
public MetaColumn FilteredColumn {
|
||||
get {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public string GetPropertyNameExpression(string columnName) {
|
||||
// Get the DataKeyPropertyAttribute and use that as the to get the correct property name expression
|
||||
DataKeyPropertyAttribute attribute = _control.GetType().GetCustomAttributes(true).OfType<DataKeyPropertyAttribute>().FirstOrDefault();
|
||||
if ((attribute != null) && !String.IsNullOrEmpty(attribute.Name)) {
|
||||
return attribute.Name + String.Format(CultureInfo.InvariantCulture, "['{0}']", columnName);
|
||||
}
|
||||
//
|
||||
return String.Empty;
|
||||
}
|
||||
}
|
||||
}
|
48
external/referencesource/System.Web.DynamicData/DynamicData/DataControlReference.cs
vendored
Normal file
48
external/referencesource/System.Web.DynamicData/DynamicData/DataControlReference.cs
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
namespace System.Web.DynamicData {
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Drawing.Design;
|
||||
using System.Security.Permissions;
|
||||
using System.Web.UI;
|
||||
|
||||
/// <summary>
|
||||
/// Registers a DataControl for use with Dynamic Data
|
||||
/// </summary>
|
||||
public class DataControlReference {
|
||||
/// <summary>
|
||||
/// Dynamic data manager registering the data control
|
||||
/// </summary>
|
||||
[Browsable(false)]
|
||||
public DynamicDataManager Owner {
|
||||
get;
|
||||
internal set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ControlID of the DataControl
|
||||
/// </summary>
|
||||
[
|
||||
Category("Behavior"),
|
||||
DefaultValue(""),
|
||||
IDReferenceProperty(),
|
||||
ResourceDescription("DataControlReference_ControlID"),
|
||||
TypeConverter("System.Web.DynamicData.Design.DataControlReferenceIDConverter, " + AssemblyRef.SystemWebDynamicDataDesign),
|
||||
SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "ID")
|
||||
]
|
||||
public string ControlID {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]
|
||||
public override string ToString() {
|
||||
if (String.IsNullOrEmpty(ControlID)) {
|
||||
return "DataControl";
|
||||
}
|
||||
else {
|
||||
return "DataControl: " + ControlID;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
50
external/referencesource/System.Web.DynamicData/DynamicData/DataControlReferenceCollection.cs
vendored
Normal file
50
external/referencesource/System.Web.DynamicData/DynamicData/DataControlReferenceCollection.cs
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
namespace System.Web.DynamicData {
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Security.Permissions;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a collectin of DataControlReferences
|
||||
/// </summary>
|
||||
public class DataControlReferenceCollection : Collection<DataControlReference> {
|
||||
public DataControlReferenceCollection(DynamicDataManager owner) {
|
||||
if (owner == null) {
|
||||
throw new ArgumentNullException("owner");
|
||||
}
|
||||
|
||||
Owner = owner;
|
||||
}
|
||||
|
||||
public DynamicDataManager Owner {
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
internal void Initialize() {
|
||||
foreach (DataControlReference reference in this) {
|
||||
reference.Owner = Owner;
|
||||
}
|
||||
}
|
||||
|
||||
[SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]
|
||||
protected override void SetItem(int index, DataControlReference item) {
|
||||
item.Owner = Owner;
|
||||
base.SetItem(index, item);
|
||||
}
|
||||
|
||||
[SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]
|
||||
protected override void InsertItem(int index, DataControlReference item) {
|
||||
item.Owner = Owner;
|
||||
base.InsertItem(index, item);
|
||||
}
|
||||
|
||||
[SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]
|
||||
protected override void RemoveItem(int index) {
|
||||
this[index].Owner = null;
|
||||
base.RemoveItem(index);
|
||||
}
|
||||
}
|
||||
}
|
70
external/referencesource/System.Web.DynamicData/DynamicData/DataSourceUtil.cs
vendored
Normal file
70
external/referencesource/System.Web.DynamicData/DynamicData/DataSourceUtil.cs
vendored
Normal file
@ -0,0 +1,70 @@
|
||||
namespace System.Web.DynamicData {
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Web.Resources;
|
||||
using System.Web.UI;
|
||||
using System.Web.UI.WebControls;
|
||||
using System.Collections;
|
||||
using System.Data;
|
||||
|
||||
static class DataSourceUtil {
|
||||
|
||||
private static object s_lock = new object();
|
||||
private static Dictionary<Type, TypeCode> s_typeToTypeCodeMap;
|
||||
|
||||
internal static TypeCode TypeCodeFromType(Type type) {
|
||||
if (s_typeToTypeCodeMap == null) {
|
||||
lock (s_lock) {
|
||||
if (s_typeToTypeCodeMap == null) {
|
||||
|
||||
//
|
||||
Dictionary<Type, TypeCode> typeNameToTypeCode = new Dictionary<Type, TypeCode>();
|
||||
typeNameToTypeCode[typeof(Boolean)] = TypeCode.Boolean;
|
||||
typeNameToTypeCode[typeof(String)] = TypeCode.String;
|
||||
typeNameToTypeCode[typeof(Byte)] = TypeCode.Byte;
|
||||
typeNameToTypeCode[typeof(Int16)] = TypeCode.Int16;
|
||||
typeNameToTypeCode[typeof(Int32)] = TypeCode.Int32;
|
||||
typeNameToTypeCode[typeof(Int64)] = TypeCode.Int64;
|
||||
typeNameToTypeCode[typeof(Single)] = TypeCode.Single;
|
||||
typeNameToTypeCode[typeof(Double)] = TypeCode.Double;
|
||||
typeNameToTypeCode[typeof(Decimal)] = TypeCode.Decimal;
|
||||
typeNameToTypeCode[typeof(DateTime)] = TypeCode.DateTime;
|
||||
typeNameToTypeCode[typeof(Char)] = TypeCode.Char;
|
||||
|
||||
// We don't support columns of type 'sqlvariant', which show up as Object
|
||||
//
|
||||
typeNameToTypeCode[typeof(Object)] = TypeCode.DBNull;
|
||||
|
||||
// We don't support byte arrays. This include columns of type 'timestamp'
|
||||
typeNameToTypeCode[typeof(Byte[])] = TypeCode.DBNull;
|
||||
|
||||
// Use Object for Guid's (though we need to do some special processing)
|
||||
typeNameToTypeCode[typeof(Guid)] = TypeCode.Object;
|
||||
|
||||
s_typeToTypeCodeMap = typeNameToTypeCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If it's an Nullable<T>, work with T instead
|
||||
type = Misc.RemoveNullableFromType(type);
|
||||
|
||||
TypeCode typeCode;
|
||||
if (s_typeToTypeCodeMap.TryGetValue(type, out typeCode))
|
||||
return typeCode;
|
||||
|
||||
return TypeCode.Object;
|
||||
}
|
||||
|
||||
internal static void SetParameterTypeCodeAndDbType(Parameter parameter, MetaColumn column) {
|
||||
// If it's a Guid, use a DbType, since TypeCode doesn't support it. For everything else, use TypeCode
|
||||
if (column.ColumnType == typeof(Guid)) {
|
||||
parameter.DbType = DbType.Guid;
|
||||
}
|
||||
else {
|
||||
parameter.Type = column.TypeCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
68
external/referencesource/System.Web.DynamicData/DynamicData/DefaultAutoFieldGenerator.cs
vendored
Normal file
68
external/referencesource/System.Web.DynamicData/DynamicData/DefaultAutoFieldGenerator.cs
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
namespace System.Web.DynamicData {
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Web.DynamicData.Util;
|
||||
using System.Web.UI;
|
||||
using System.Web.UI.WebControls;
|
||||
|
||||
public class DefaultAutoFieldGenerator : IAutoFieldGenerator {
|
||||
private IMetaTable _metaTable;
|
||||
|
||||
public DefaultAutoFieldGenerator(MetaTable table)
|
||||
: this((IMetaTable)table) {
|
||||
}
|
||||
|
||||
internal DefaultAutoFieldGenerator(IMetaTable table) {
|
||||
if (table == null) {
|
||||
throw new ArgumentNullException("table");
|
||||
}
|
||||
_metaTable = table;
|
||||
}
|
||||
|
||||
public ICollection GenerateFields(Control control) {
|
||||
DataBoundControlMode mode = GetMode(control);
|
||||
ContainerType containerType = GetControlContainerType(control);
|
||||
|
||||
// Auto-generate fields from metadata.
|
||||
List<DynamicField> fields = new List<DynamicField>();
|
||||
foreach (MetaColumn column in _metaTable.GetScaffoldColumns(mode, containerType)) {
|
||||
fields.Add(CreateField(column, containerType, mode));
|
||||
}
|
||||
|
||||
return fields;
|
||||
}
|
||||
|
||||
protected virtual DynamicField CreateField(MetaColumn column, ContainerType containerType, DataBoundControlMode mode) {
|
||||
string headerText = (containerType == ContainerType.List ? column.ShortDisplayName : column.DisplayName);
|
||||
|
||||
var field = new DynamicField() {
|
||||
DataField = column.Name,
|
||||
HeaderText = headerText
|
||||
};
|
||||
// Turn wrapping off by default so that error messages don't show up on the next line.
|
||||
field.ItemStyle.Wrap = false;
|
||||
|
||||
return field;
|
||||
}
|
||||
|
||||
internal static ContainerType GetControlContainerType(Control control) {
|
||||
if (control is IDataBoundListControl || control is Repeater) {
|
||||
return ContainerType.List;
|
||||
} else if (control is IDataBoundItemControl) {
|
||||
return ContainerType.Item;
|
||||
}
|
||||
return ContainerType.List;
|
||||
}
|
||||
|
||||
internal static DataBoundControlMode GetMode(Control control) {
|
||||
// Only item controls have distinct modes
|
||||
IDataBoundItemControl itemControl = control as IDataBoundItemControl;
|
||||
if (itemControl != null && GetControlContainerType(control) != ContainerType.List) {
|
||||
return itemControl.Mode;
|
||||
}
|
||||
|
||||
return DataBoundControlMode.ReadOnly;
|
||||
}
|
||||
}
|
||||
}
|
435
external/referencesource/System.Web.DynamicData/DynamicData/DynamicControl.cs
vendored
Normal file
435
external/referencesource/System.Web.DynamicData/DynamicData/DynamicControl.cs
vendored
Normal file
@ -0,0 +1,435 @@
|
||||
namespace System.Web.DynamicData {
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
using System.Web.Resources;
|
||||
using System.Web.UI;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Web.UI.WebControls;
|
||||
using System.Drawing;
|
||||
using System.Diagnostics;
|
||||
|
||||
/// <summary>
|
||||
/// Control used to render Dynamic Data driven UI
|
||||
/// </summary>
|
||||
[ToolboxBitmap(typeof(DynamicControl), "DynamicControl.bmp")]
|
||||
public class DynamicControl : Control, IAttributeAccessor, IFieldTemplateHost, IFieldFormattingOptions {
|
||||
|
||||
private bool _customConvertEmptyStringToNullSet;
|
||||
private bool _customApplyFormatInEditModeSet;
|
||||
private MetaTable _table;
|
||||
private IMetaTable _iMetaTable;
|
||||
private IDictionary<string, string> _attributes;
|
||||
private IMetaColumn _iMetaColumn;
|
||||
private MetaColumn _column;
|
||||
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
public DynamicControl() {
|
||||
}
|
||||
|
||||
internal DynamicControl(IMetaTable table) {
|
||||
_iMetaTable = table;
|
||||
}
|
||||
|
||||
internal DynamicControl(IMetaColumn column) {
|
||||
_iMetaColumn = column;
|
||||
}
|
||||
|
||||
/// <param name="mode">The mode that the associated field template should be in (readonly, edit, insert)</param>
|
||||
public DynamicControl(DataBoundControlMode mode) {
|
||||
Mode = mode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The name of the column that this control handles
|
||||
/// </summary>
|
||||
[
|
||||
Category("Data"),
|
||||
DefaultValue(""),
|
||||
ResourceDescription("DynamicControlFieldCommon_DataField")
|
||||
]
|
||||
public string DataField {
|
||||
get {
|
||||
object o = ViewState["DataField"];
|
||||
return ((o == null) ? String.Empty : (string)o);
|
||||
}
|
||||
set {
|
||||
if (!String.Equals(value, ViewState["DataField"])) {
|
||||
ViewState["DataField"] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The MetaColumn that this control is working with
|
||||
/// </summary>
|
||||
[Browsable(false)]
|
||||
public MetaColumn Column {
|
||||
get {
|
||||
return _column;
|
||||
}
|
||||
set {
|
||||
_column = value;
|
||||
_iMetaColumn = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The UIHint used by this control to locate the proper field template
|
||||
/// </summary>
|
||||
[
|
||||
Category("Behavior"),
|
||||
DefaultValue(""),
|
||||
ResourceDescription("DynamicControlFieldCommon_UIHint")
|
||||
]
|
||||
public virtual string UIHint {
|
||||
get {
|
||||
object o = ViewState["UIHint"];
|
||||
return ((o == null) ? String.Empty : (string)o);
|
||||
}
|
||||
set {
|
||||
ViewState["UIHint"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the CSS class property of the DynamicControl
|
||||
/// </summary>
|
||||
[
|
||||
Category("Appearance"),
|
||||
DefaultValue(""),
|
||||
CssClassProperty()
|
||||
]
|
||||
public virtual string CssClass {
|
||||
get {
|
||||
object o = ViewState["CssClass"];
|
||||
return ((o == null) ? String.Empty : (string)o);
|
||||
}
|
||||
set {
|
||||
ViewState["CssClass"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The MetaTable that this control is associated with
|
||||
/// </summary>
|
||||
[Browsable(false)]
|
||||
public virtual MetaTable Table {
|
||||
get {
|
||||
if (_table == null) {
|
||||
_table = this.FindMetaTable();
|
||||
|
||||
if (_table == null) {
|
||||
throw new Exception(String.Format(CultureInfo.CurrentCulture,
|
||||
DynamicDataResources.DynamicControl_ControlNeedsToExistInADataControlUsingDynamicDataSource));
|
||||
}
|
||||
}
|
||||
return _table;
|
||||
}
|
||||
}
|
||||
|
||||
private IMetaTable IMetaTable {
|
||||
get {
|
||||
return _iMetaTable ?? Table;
|
||||
}
|
||||
}
|
||||
|
||||
private IMetaColumn IMetaColumn {
|
||||
get {
|
||||
return _iMetaColumn;
|
||||
}
|
||||
set {
|
||||
_iMetaColumn = value;
|
||||
_column = value as MetaColumn;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The rendering mode: readonly, edit or insert
|
||||
/// </summary>
|
||||
[
|
||||
DefaultValue(DataBoundControlMode.ReadOnly),
|
||||
Category("Behavior"),
|
||||
ResourceDescription("DynamicField_Mode")
|
||||
]
|
||||
public DataBoundControlMode Mode {
|
||||
get {
|
||||
object o = ViewState["Mode"];
|
||||
return ((o == null) ? DataBoundControlMode.ReadOnly : (DataBoundControlMode)o);
|
||||
}
|
||||
set {
|
||||
ViewState["Mode"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The validation group that the field template need to be in
|
||||
/// </summary>
|
||||
[
|
||||
Category("Behavior"),
|
||||
DefaultValue(""),
|
||||
Themeable(false),
|
||||
ResourceDescription("DynamicControlFieldCommon_ValidationGroup")
|
||||
]
|
||||
public virtual string ValidationGroup {
|
||||
get {
|
||||
object o = ViewState["ValidationGroup"];
|
||||
return ((o == null) ? String.Empty : (string)o);
|
||||
}
|
||||
set {
|
||||
ViewState["ValidationGroup"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal Control CreateControl() {
|
||||
Debug.Assert(FieldTemplate == null);
|
||||
|
||||
FieldTemplate = (Control)IMetaColumn.Model.FieldTemplateFactory.CreateFieldTemplate(Column, Mode, UIHint);
|
||||
if (FieldTemplate != null) {
|
||||
((IFieldTemplate)FieldTemplate).SetHost(this);
|
||||
|
||||
// If we got some extra attributes declared on the tag, assign them to the user control if it has matching properties
|
||||
if (_attributes != null) {
|
||||
var ucType = FieldTemplate.GetType();
|
||||
foreach (var entry in _attributes) {
|
||||
// Look for a public property by that name on th user control
|
||||
var propInfo = ucType.GetProperty(entry.Key, BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
|
||||
if (propInfo != null) {
|
||||
// Convert the value to the type of the property and set it
|
||||
var value = PropertyConverter.ObjectFromString(propInfo.PropertyType, propInfo, entry.Value);
|
||||
propInfo.SetValue(FieldTemplate, value, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Give it the column name as its ID, unless there is already a control by that name
|
||||
string id = GetControlIDFromColumnName(IMetaColumn.Name);
|
||||
if (FindControl(id) == null)
|
||||
FieldTemplate.ID = id;
|
||||
}
|
||||
return FieldTemplate;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See base class documentation
|
||||
/// </summary>
|
||||
[SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers")]
|
||||
protected override void OnInit(EventArgs e) {
|
||||
base.OnInit(e);
|
||||
|
||||
// Don't do anything in Design mode
|
||||
if (DesignMode)
|
||||
return;
|
||||
|
||||
ResolveColumn();
|
||||
FieldTemplate = CreateControl();
|
||||
// Add it to the tree
|
||||
if (FieldTemplate != null) {
|
||||
Controls.Add(FieldTemplate);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Renders the underlying field template control. If this DynamicControl's CssClass tag is defined,
|
||||
/// the underlying control's output will be wrapped in a span tag with that css class applied.
|
||||
/// </summary>
|
||||
/// <param name="writer"></param>
|
||||
protected override void Render(HtmlTextWriter writer) {
|
||||
|
||||
// In Design mode, simply render the string Databound. Ideally, we'd do something fancier
|
||||
// that takes into account the type of the column. But at lesat, rendering *something* makes
|
||||
// the design layout look reasonable
|
||||
if (DesignMode) {
|
||||
writer.Write(DynamicDataResources.DynamicControlDesignRender);
|
||||
return;
|
||||
}
|
||||
|
||||
// If there is a CSS class, output it in a span tag. Otherwise, don't use any extra tag.
|
||||
if (!String.IsNullOrEmpty(CssClass)) {
|
||||
writer.AddAttribute(HtmlTextWriterAttribute.Class, CssClass);
|
||||
writer.RenderBeginTag(HtmlTextWriterTag.Span);
|
||||
base.Render(writer);
|
||||
writer.RenderEndTag();
|
||||
}
|
||||
else {
|
||||
base.Render(writer);
|
||||
}
|
||||
}
|
||||
|
||||
internal void ResolveColumn() {
|
||||
if (IMetaColumn == null) {
|
||||
if (String.IsNullOrEmpty(DataField)) {
|
||||
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture,
|
||||
DynamicDataResources.DynamicControl_ControlMustHaveDateFieldAttribute, GetType().Name, ID));
|
||||
}
|
||||
|
||||
IMetaColumn = IMetaTable.GetColumn(DataField);
|
||||
|
||||
|
||||
// Try to get them various settings from the model, unless they were explicitely
|
||||
// specified on the control
|
||||
if (String.IsNullOrEmpty(UIHint)) {
|
||||
UIHint = IMetaColumn.UIHint;
|
||||
}
|
||||
if (String.IsNullOrEmpty(DataFormatString)) {
|
||||
DataFormatString = IMetaColumn.DataFormatString;
|
||||
}
|
||||
if (String.IsNullOrEmpty(NullDisplayText)) {
|
||||
NullDisplayText = IMetaColumn.NullDisplayText;
|
||||
}
|
||||
if (!_customConvertEmptyStringToNullSet) {
|
||||
ConvertEmptyStringToNull = IMetaColumn.ConvertEmptyStringToNull;
|
||||
}
|
||||
if (!_customApplyFormatInEditModeSet) {
|
||||
ApplyFormatInEditMode = IMetaColumn.ApplyFormatInEditMode;
|
||||
}
|
||||
if (ViewState["HtmlEncode"] == null) {
|
||||
HtmlEncode = IMetaColumn.HtmlEncode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The Field Template that was created for this control
|
||||
/// </summary>
|
||||
[Browsable(false)]
|
||||
public Control FieldTemplate { get; private set; }
|
||||
|
||||
internal static string GetControlIDFromColumnName(string columnName) {
|
||||
return "__" + columnName;
|
||||
}
|
||||
|
||||
internal void SetAttributes(IDictionary<string, string> attributes) {
|
||||
_attributes = attributes;
|
||||
}
|
||||
|
||||
#region IAttributeAccessor Members
|
||||
|
||||
/// <summary>
|
||||
/// See IAttributeAccessor
|
||||
/// </summary>
|
||||
public string GetAttribute(string key) {
|
||||
if (_attributes == null)
|
||||
return String.Empty;
|
||||
return _attributes[key];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See IAttributeAccessor
|
||||
/// </summary>
|
||||
public void SetAttribute(string key, string value) {
|
||||
if (_attributes == null) {
|
||||
_attributes = new Dictionary<string, string>();
|
||||
}
|
||||
_attributes[key] = value;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IFieldTemplateHost Members
|
||||
|
||||
IFieldFormattingOptions IFieldTemplateHost.FormattingOptions {
|
||||
get { return this; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IFieldFormattingOptions Members
|
||||
|
||||
/// <summary>
|
||||
/// See IFieldFormattingOptions
|
||||
/// </summary>
|
||||
[
|
||||
Category("Behavior"),
|
||||
DefaultValue(false),
|
||||
ResourceDescription("DynamicControlFieldCommon_ConvertEmptyStringToNull")
|
||||
]
|
||||
public bool ConvertEmptyStringToNull {
|
||||
get {
|
||||
object o = ViewState["ConvertEmptyStringToNull"];
|
||||
return (o == null ? false : (bool)o);
|
||||
}
|
||||
set {
|
||||
_customConvertEmptyStringToNullSet = true;
|
||||
ViewState["ConvertEmptyStringToNull"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See IFieldFormattingOptions
|
||||
/// </summary>
|
||||
[
|
||||
Category("Behavior"),
|
||||
DefaultValue(false),
|
||||
ResourceDescription("DynamicControlFieldCommon_ApplyFormatInEditMode")
|
||||
]
|
||||
public bool ApplyFormatInEditMode {
|
||||
get {
|
||||
object o = ViewState["ApplyFormatInEditMode"];
|
||||
return (o == null ? false : (bool)o);
|
||||
}
|
||||
set {
|
||||
_customApplyFormatInEditModeSet = true;
|
||||
ViewState["ApplyFormatInEditMode"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See IFieldFormattingOptions
|
||||
/// </summary>
|
||||
[
|
||||
Category("Data"),
|
||||
DefaultValue(""),
|
||||
ResourceDescription("DynamicControlFieldCommon_DataFormatString")
|
||||
]
|
||||
public string DataFormatString {
|
||||
get {
|
||||
object o = ViewState["DataFormatString"];
|
||||
return (o == null ? String.Empty : (string)o);
|
||||
}
|
||||
set {
|
||||
ViewState["DataFormatString"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See IFieldFormattingOptions
|
||||
/// </summary>
|
||||
[
|
||||
Category("Behavior"),
|
||||
DefaultValue(true),
|
||||
ResourceDescription("DynamicControlFieldCommon_HtmlEncode")
|
||||
]
|
||||
public bool HtmlEncode {
|
||||
get {
|
||||
object o = ViewState["HtmlEncode"];
|
||||
return (o == null ? true : (bool)o);
|
||||
}
|
||||
set {
|
||||
ViewState["HtmlEncode"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See IFieldFormattingOptions
|
||||
/// </summary>
|
||||
[
|
||||
Category("Behavior"),
|
||||
DefaultValue(""),
|
||||
ResourceDescription("DynamicControlFieldCommon_NullDisplayText")
|
||||
]
|
||||
public string NullDisplayText {
|
||||
get {
|
||||
object o = ViewState["NullDisplayText"];
|
||||
return (o == null ? String.Empty : (string)o);
|
||||
}
|
||||
set {
|
||||
ViewState["NullDisplayText"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
166
external/referencesource/System.Web.DynamicData/DynamicData/DynamicControlParameter.cs
vendored
Normal file
166
external/referencesource/System.Web.DynamicData/DynamicData/DynamicControlParameter.cs
vendored
Normal file
@ -0,0 +1,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));
|
||||
}
|
||||
}
|
||||
}
|
398
external/referencesource/System.Web.DynamicData/DynamicData/DynamicDataExtensions.cs
vendored
Normal file
398
external/referencesource/System.Web.DynamicData/DynamicData/DynamicDataExtensions.cs
vendored
Normal file
@ -0,0 +1,398 @@
|
||||
namespace System.Web.DynamicData {
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Data.Linq;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Linq.Expressions;
|
||||
using System.Web;
|
||||
using System.Web.DynamicData.Util;
|
||||
using System.Web.Resources;
|
||||
using System.Web.UI;
|
||||
using System.Web.UI.WebControls;
|
||||
/// <summary>
|
||||
/// Extension methods used by DynamicData
|
||||
/// </summary>
|
||||
public static class DynamicDataExtensions {
|
||||
public static void SetMetaTable(this INamingContainer control, MetaTable table) {
|
||||
SetMetaTableInternal(control, table, null/* defaultValues*/, new HttpContextWrapper(HttpContext.Current));
|
||||
}
|
||||
|
||||
public static void SetMetaTable(this INamingContainer control, MetaTable table, IDictionary<string, object> defaultValues) {
|
||||
if (defaultValues == null) {
|
||||
throw new ArgumentNullException("defaultValues");
|
||||
}
|
||||
SetMetaTableInternal(control, table, defaultValues, new HttpContextWrapper(HttpContext.Current));
|
||||
}
|
||||
|
||||
public static void SetMetaTable(this INamingContainer control, MetaTable table, object defaultValues) {
|
||||
if (defaultValues == null) {
|
||||
throw new ArgumentNullException("defaultValues");
|
||||
}
|
||||
SetMetaTableInternal(control, table, Misc.ConvertObjectToDictionary(defaultValues), new HttpContextWrapper(HttpContext.Current));
|
||||
}
|
||||
|
||||
public static IDictionary<string, object> GetDefaultValues(this IDataSource dataSource) {
|
||||
return GetDefaultValues(dataSource, new HttpContextWrapper(HttpContext.Current));
|
||||
}
|
||||
|
||||
public static IDictionary<string, object> GetDefaultValues(this INamingContainer control) {
|
||||
return GetDefaultValues(control, new HttpContextWrapper(HttpContext.Current));
|
||||
}
|
||||
|
||||
public static MetaTable GetMetaTable(this IDataSource dataSource) {
|
||||
return GetMetaTable(dataSource, new HttpContextWrapper(HttpContext.Current));
|
||||
}
|
||||
|
||||
public static bool TryGetMetaTable(this IDataSource dataSource, out MetaTable table) {
|
||||
return TryGetMetaTable(dataSource, new HttpContextWrapper(HttpContext.Current), out table);
|
||||
}
|
||||
|
||||
public static MetaTable GetMetaTable(this INamingContainer control) {
|
||||
return GetMetaTable(control, new HttpContextWrapper(HttpContext.Current));
|
||||
}
|
||||
|
||||
public static bool TryGetMetaTable(this INamingContainer control, out MetaTable table) {
|
||||
return TryGetMetaTable(control, new HttpContextWrapper(HttpContext.Current), out table);
|
||||
}
|
||||
|
||||
internal static void ApplyFieldGenerator(INamingContainer control, MetaTable table) {
|
||||
GridView gridView = control as GridView;
|
||||
if (gridView != null && gridView.AutoGenerateColumns && gridView.ColumnsGenerator == null) {
|
||||
gridView.ColumnsGenerator = new DefaultAutoFieldGenerator(table);
|
||||
}
|
||||
else {
|
||||
DetailsView detailsView = control as DetailsView;
|
||||
if (detailsView != null && detailsView.AutoGenerateRows && detailsView.RowsGenerator == null) {
|
||||
detailsView.RowsGenerator = new DefaultAutoFieldGenerator(table);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static DefaultValueMapping GetDefaultValueMapping(object control, HttpContextBase context) {
|
||||
IDictionary<object, MappingInfo> mapping = MetaTableHelper.GetMapping(context);
|
||||
MappingInfo mappingInfo;
|
||||
if (mapping.TryGetValue(control, out mappingInfo)) {
|
||||
return mappingInfo.DefaultValueMapping;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
internal static IDictionary<string, object> GetDefaultValues(object control, HttpContextBase context) {
|
||||
DefaultValueMapping mapping = GetDefaultValueMapping(control, context);
|
||||
if (mapping != null) {
|
||||
return mapping.Values;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
internal static MetaTable GetMetaTable(IDataSource dataSource, HttpContextBase context) {
|
||||
MetaTable table;
|
||||
if (TryGetMetaTable(dataSource, context, out table)) {
|
||||
return table;
|
||||
}
|
||||
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, DynamicDataResources.MetaTable_CannotGetTableFromDataSource));
|
||||
}
|
||||
|
||||
internal static bool TryGetMetaTable(IDataSource dataSource, HttpContextBase context, out MetaTable table) {
|
||||
if (dataSource == null) {
|
||||
throw new ArgumentNullException("dataSource");
|
||||
}
|
||||
|
||||
Debug.Assert(context != null);
|
||||
|
||||
table = MetaTableHelper.GetTableFromMapping(context, dataSource);
|
||||
if (table == null) {
|
||||
var dynamicDataSource = dataSource as IDynamicDataSource;
|
||||
if (dynamicDataSource != null) {
|
||||
table = MetaTableHelper.GetTableFromDynamicDataSource(dynamicDataSource);
|
||||
}
|
||||
}
|
||||
return table != null;
|
||||
}
|
||||
|
||||
internal static MetaTable GetMetaTable(INamingContainer control, HttpContextBase context) {
|
||||
MetaTable table;
|
||||
if (!TryGetMetaTable(control, context, out table)) {
|
||||
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, DynamicDataResources.MetaTable_CannotGetTableFromControl));
|
||||
}
|
||||
return table;
|
||||
}
|
||||
|
||||
internal static bool TryGetMetaTable(INamingContainer control, HttpContextBase context, out MetaTable table) {
|
||||
if (control == null) {
|
||||
throw new ArgumentNullException("control");
|
||||
}
|
||||
|
||||
table = MetaTableHelper.GetTableFromMapping(context, control);
|
||||
return table != null;
|
||||
}
|
||||
|
||||
internal static void SetMetaTableInternal(INamingContainer control, MetaTable table, IDictionary<string, object> defaultValues, HttpContextBase context) {
|
||||
if (control == null) {
|
||||
throw new ArgumentNullException("control");
|
||||
}
|
||||
if (table == null) {
|
||||
throw new ArgumentNullException("table");
|
||||
}
|
||||
IDataBoundControl dataBoundControl = control as IDataBoundControl;
|
||||
IDataSource dataSource = null;
|
||||
if (dataBoundControl != null) {
|
||||
dataSource = dataBoundControl.DataSourceObject;
|
||||
}
|
||||
MetaTableHelper.SetTableInMapping(context, control, table, defaultValues);
|
||||
if (dataSource != null) {
|
||||
// If the control being mapped is a databound control then register its datasource
|
||||
MetaTableHelper.SetTableInMapping(context, dataSource, table, defaultValues);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the MetaTable association with a datasource
|
||||
/// </summary>
|
||||
[SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "This is a legacy API and cannot be changed")]
|
||||
public static MetaTable GetTable(this IDynamicDataSource dataSource) {
|
||||
return MetaTableHelper.GetTableWithFullFallback(dataSource, HttpContext.Current.ToWrapper());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Expand Dynamic where parameter (e.g. DynamicControlParameter, DynamicQueryStringParameter) into
|
||||
/// 'regular' parameters that the datasource can understand
|
||||
/// </summary>
|
||||
/// <param name="dataSource">The datasource which Where parameters need to be expanded</param>
|
||||
public static void ExpandDynamicWhereParameters(this IDynamicDataSource dataSource) {
|
||||
|
||||
ParameterCollection whereParameters = dataSource.WhereParameters;
|
||||
|
||||
// First, check if any parameters need to be expanded
|
||||
bool needProcessing = false;
|
||||
foreach (Parameter parameter in whereParameters) {
|
||||
if (parameter is IWhereParametersProvider) {
|
||||
needProcessing = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If not, don't do anything
|
||||
if (!needProcessing)
|
||||
return;
|
||||
|
||||
// Make a copy of the parameters, and clear the collection
|
||||
var whereParametersCopy = new Parameter[whereParameters.Count];
|
||||
whereParameters.CopyTo(whereParametersCopy, 0);
|
||||
whereParameters.Clear();
|
||||
|
||||
// Go through all the parameters and expand them
|
||||
foreach (Parameter parameter in whereParametersCopy) {
|
||||
ExpandWhereParameter(dataSource, parameter);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ExpandWhereParameter(IDynamicDataSource dataSource, Parameter parameter) {
|
||||
var provider = parameter as IWhereParametersProvider;
|
||||
if (provider == null) {
|
||||
// If it's a standard parameter, just add it
|
||||
dataSource.WhereParameters.Add(parameter);
|
||||
}
|
||||
else {
|
||||
// Get the list of sub-parameters and expand them recursively
|
||||
IEnumerable<Parameter> newParameters = provider.GetWhereParameters(dataSource);
|
||||
foreach (Parameter newParameter in newParameters) {
|
||||
ExpandWhereParameter(dataSource, newParameter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find the containing data control, and return the data source it points to
|
||||
/// </summary>
|
||||
public static IDynamicDataSource FindDataSourceControl(this Control current) {
|
||||
return DataControlHelper.FindDataSourceControl(current);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find the containing data control, and return the MetaTable associated with it, if any
|
||||
/// </summary>
|
||||
public static MetaTable FindMetaTable(this Control current) {
|
||||
return MetaTableHelper.FindMetaTable(current, HttpContext.Current.ToWrapper());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find the field template for a column within the current naming container
|
||||
/// </summary>
|
||||
public static Control FindFieldTemplate(this Control control, string columnName) {
|
||||
return control.FindControl(DynamicControl.GetControlIDFromColumnName(columnName));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Make the SelectedIndex [....] up with the PersistedSelection. Concretely, what it means is that
|
||||
/// if you select a row and then page away (or sort), the selection remains on that row
|
||||
/// even if it's not currently visible.
|
||||
/// </summary>
|
||||
[Obsolete("Use the EnablePersistedSelection property on a databound control such as GridView or ListView.")]
|
||||
public static void EnablePersistedSelection(this BaseDataBoundControl dataBoundControl) {
|
||||
EnablePersistedSelectionInternal(dataBoundControl);
|
||||
}
|
||||
|
||||
internal static void EnablePersistedSelectionInternal(BaseDataBoundControl dataBoundControl) {
|
||||
IDataBoundListControl dataBoundListControl = dataBoundControl as IDataBoundListControl;
|
||||
if (dataBoundListControl != null) {
|
||||
dataBoundListControl.EnablePersistedSelection = true;
|
||||
//
|
||||
|
||||
if (dataBoundListControl.SelectedIndex < 0) {
|
||||
// Force the first item to be selected
|
||||
dataBoundListControl.SelectedIndex = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the DataLoadOptions on a Linq To Sql datasource to force all the FK entities
|
||||
/// to be directly loaded.
|
||||
/// </summary>
|
||||
/// <param name="dataSource">The data source for which we want to preload FKs</param>
|
||||
/// <param name="rowType">The type of the entities returned by the data source</param>
|
||||
public static void LoadWithForeignKeys(this LinqDataSource dataSource, Type rowType) {
|
||||
dataSource.ContextCreated += delegate(object sender, LinqDataSourceStatusEventArgs e) {
|
||||
// This only applies to a DLinq data context
|
||||
var context = e.Result as DataContext;
|
||||
if (context == null)
|
||||
return;
|
||||
|
||||
DataLoadOptions loadOptions = null;
|
||||
ParameterExpression tableParameter = null;
|
||||
System.Data.Linq.Mapping.MetaTable metaTable = context.Mapping.GetTable(rowType);
|
||||
foreach (System.Data.Linq.Mapping.MetaDataMember member in metaTable.RowType.DataMembers) {
|
||||
if (member.IsAssociation && !member.Association.IsMany) {
|
||||
if (member.Type.Equals(rowType)) continue;
|
||||
if (loadOptions == null) {
|
||||
loadOptions = new DataLoadOptions();
|
||||
tableParameter = Expression.Parameter(rowType, "e");
|
||||
}
|
||||
var memberExpression = Expression.Property(tableParameter, member.Name);
|
||||
loadOptions.LoadWith(Expression.Lambda(memberExpression, tableParameter));
|
||||
}
|
||||
}
|
||||
|
||||
if (loadOptions != null) {
|
||||
context.LoadOptions = loadOptions;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static void LoadWith<TEntity>(this LinqDataSource dataSource) {
|
||||
LoadWithForeignKeys(dataSource, typeof(TEntity));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Apply potential HTML encoding and formatting to a string that needs to be displayed
|
||||
/// This logic is mostly copied from BoundField.FormatDataValue, but omits the old Whidbey behavior path
|
||||
/// </summary>
|
||||
/// <param name="fieldValue">The value that should be formatted</param>
|
||||
/// <param name="formattingOptions">The IFieldFormattingOptions to use. This is useful when using options different from the column's</param>
|
||||
/// <returns>the formatted value</returns>
|
||||
public static string FormatValue(this IFieldFormattingOptions formattingOptions, object fieldValue) {
|
||||
|
||||
string formattedValue = String.Empty;
|
||||
|
||||
if (fieldValue != null) {
|
||||
string dataValueString = fieldValue.ToString();
|
||||
string formatting = formattingOptions.DataFormatString;
|
||||
int dataValueStringLength = dataValueString.Length;
|
||||
|
||||
// If the result is still empty and ConvertEmptyStringToNull=true, replace the value with the NullDisplayText
|
||||
if (dataValueStringLength == 0 && formattingOptions.ConvertEmptyStringToNull) {
|
||||
dataValueString = formattingOptions.NullDisplayText;
|
||||
}
|
||||
else {
|
||||
// If there's a format string, apply it to the raw data value
|
||||
// If there's no format string, then dataValueString already has the right value
|
||||
if (!String.IsNullOrEmpty(formatting)) {
|
||||
dataValueString = String.Format(CultureInfo.CurrentCulture, formatting, fieldValue);
|
||||
}
|
||||
|
||||
// Optionally HTML encode the value (including the format string, if any was applied)
|
||||
if (!String.IsNullOrEmpty(dataValueString) && formattingOptions.HtmlEncode) {
|
||||
dataValueString = HttpUtility.HtmlEncode(dataValueString);
|
||||
}
|
||||
}
|
||||
|
||||
formattedValue = dataValueString;
|
||||
}
|
||||
else {
|
||||
formattedValue = formattingOptions.NullDisplayText;
|
||||
}
|
||||
|
||||
return formattedValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Similar to FormatValue, but the string is to be used when the field is in edit mode
|
||||
/// </summary>
|
||||
public static string FormatEditValue(this IFieldFormattingOptions formattingOptions, object fieldValue) {
|
||||
string valueString;
|
||||
|
||||
// Apply the format string to it if that flag is set. Otherwise use it as is.
|
||||
if (formattingOptions.ApplyFormatInEditMode) {
|
||||
valueString = formattingOptions.FormatValue(fieldValue);
|
||||
}
|
||||
else {
|
||||
valueString = (fieldValue != null) ? fieldValue.ToString() : String.Empty;
|
||||
}
|
||||
|
||||
// Trim any trailing spaces as they cause unwanted behavior (since we limit the input length and the
|
||||
// spaces cause the limit to be reach prematurely)
|
||||
valueString = valueString.TrimEnd();
|
||||
|
||||
return valueString;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return either the input value or null based on ConvertEmptyStringToNull and NullDisplayText
|
||||
/// </summary>
|
||||
/// <param name="formattingOptions">the formatting options object</param>
|
||||
/// <param name="value">The input value</param>
|
||||
/// <returns>The converted value</returns>
|
||||
public static object ConvertEditedValue(this IFieldFormattingOptions formattingOptions, string value) {
|
||||
// If it's an empty string and ConvertEmptyStringToNull is set, make it null
|
||||
if (String.IsNullOrEmpty(value) && formattingOptions.ConvertEmptyStringToNull) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// If it's the NullDisplayText, return null
|
||||
string nullDisplayText = formattingOptions.NullDisplayText;
|
||||
if (value == nullDisplayText && !String.IsNullOrEmpty(nullDisplayText)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Otherwise, return it unchanged
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If this column represents an enumeration type, this method returns that type. The caloumn can represent
|
||||
/// an enumeration type if the underlying type is an enum, or if it is decoareted with EnumDataTypeAttribute.
|
||||
/// If this column does not represent an enum, this method returns null.
|
||||
/// </summary>
|
||||
/// <param name="column"></param>
|
||||
/// <returns></returns>
|
||||
[SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "The interface is internal")]
|
||||
public static Type GetEnumType(this MetaColumn column) {
|
||||
return GetEnumType((IMetaColumn)column);
|
||||
}
|
||||
|
||||
internal static Type GetEnumType(this IMetaColumn column) {
|
||||
return column.Attributes.GetAttributePropertyValue<EnumDataTypeAttribute, Type>(a => a.EnumType, null) ??
|
||||
(column.ColumnType.IsEnum ? column.ColumnType : null);
|
||||
}
|
||||
|
||||
internal static bool IsEnumType(this MetaColumn column, out Type enumType) {
|
||||
enumType = column.GetEnumType();
|
||||
return enumType != null;
|
||||
}
|
||||
}
|
||||
}
|
261
external/referencesource/System.Web.DynamicData/DynamicData/DynamicDataManager.cs
vendored
Normal file
261
external/referencesource/System.Web.DynamicData/DynamicData/DynamicDataManager.cs
vendored
Normal file
@ -0,0 +1,261 @@
|
||||
namespace System.Web.DynamicData {
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Drawing;
|
||||
using System.Globalization;
|
||||
using System.Security.Permissions;
|
||||
using System.Web.Resources;
|
||||
using System.Web.UI;
|
||||
using System.Web.UI.WebControls;
|
||||
using System.Web.DynamicData.Util;
|
||||
using System.Data.Objects;
|
||||
using IDataBoundControlInterface = System.Web.UI.WebControls.IDataBoundControl;
|
||||
|
||||
/// <summary>
|
||||
/// Adds behavior to certain control to make them work with Dynamic Data
|
||||
/// </summary>
|
||||
[NonVisualControl()]
|
||||
[ParseChildren(true)]
|
||||
[PersistChildren(false)]
|
||||
[ToolboxBitmap(typeof(DynamicDataManager), "DynamicDataManager.bmp")]
|
||||
[Designer("System.Web.DynamicData.Design.DynamicDataManagerDesigner, " + AssemblyRef.SystemWebDynamicDataDesign)]
|
||||
public class DynamicDataManager : Control {
|
||||
private DataControlReferenceCollection _dataControls;
|
||||
// Key is used as the set of registered data source controls. Value is ignored.
|
||||
private Dictionary<IDynamicDataSource, object> _dataSources = new Dictionary<IDynamicDataSource, object>();
|
||||
|
||||
/// <summary>
|
||||
/// Causes foreign entities to be loaded as well setting the proper DataLoadOptions.
|
||||
/// Only works with Linq To Sql.
|
||||
/// </summary>
|
||||
[
|
||||
Category("Behavior"),
|
||||
DefaultValue(false),
|
||||
ResourceDescription("DynamicDataManager_AutoLoadForeignKeys")
|
||||
]
|
||||
public bool AutoLoadForeignKeys {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[
|
||||
Browsable(false),
|
||||
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
|
||||
EditorBrowsable(EditorBrowsableState.Never)
|
||||
]
|
||||
public override string ClientID {
|
||||
get {
|
||||
return base.ClientID;
|
||||
}
|
||||
}
|
||||
|
||||
[
|
||||
Browsable(false),
|
||||
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
|
||||
EditorBrowsable(EditorBrowsableState.Never)
|
||||
]
|
||||
public override ClientIDMode ClientIDMode {
|
||||
get {
|
||||
return base.ClientIDMode;
|
||||
}
|
||||
set {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
[
|
||||
Category("Behavior"),
|
||||
DefaultValue(null),
|
||||
PersistenceMode(PersistenceMode.InnerProperty),
|
||||
MergableProperty(false),
|
||||
]
|
||||
public DataControlReferenceCollection DataControls {
|
||||
get {
|
||||
if (_dataControls == null) {
|
||||
_dataControls = new DataControlReferenceCollection(this);
|
||||
}
|
||||
return _dataControls;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See base class documentation
|
||||
/// </summary>
|
||||
[
|
||||
Browsable(false),
|
||||
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
|
||||
EditorBrowsable(EditorBrowsableState.Never)
|
||||
]
|
||||
public override bool Visible {
|
||||
get {
|
||||
return base.Visible;
|
||||
}
|
||||
set {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See base class documentation
|
||||
/// </summary>
|
||||
[SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers")]
|
||||
protected override void OnInit(EventArgs e) {
|
||||
base.OnInit(e);
|
||||
|
||||
// Initialize the collection
|
||||
DataControls.Initialize();
|
||||
|
||||
// Subscribe to the Page's Init to register the controls set in the DataControls collection
|
||||
Page.Init += OnPageInit;
|
||||
}
|
||||
|
||||
|
||||
private void OnPageInit(object sender, EventArgs e) {
|
||||
foreach (DataControlReference controlReference in DataControls) {
|
||||
Control targetControl = Misc.FindControl(this, controlReference.ControlID);
|
||||
if (targetControl == null) {
|
||||
throw new InvalidOperationException(
|
||||
String.Format(CultureInfo.CurrentCulture,
|
||||
DynamicDataResources.DynamicDataManager_ControlNotFound,
|
||||
controlReference.ControlID));
|
||||
}
|
||||
|
||||
RegisterControl(targetControl);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See base class documentation
|
||||
/// </summary>
|
||||
[SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers")]
|
||||
protected override void OnLoad(EventArgs e) {
|
||||
base.OnLoad(e);
|
||||
|
||||
// Go through all the registered data sources
|
||||
foreach (IDynamicDataSource dataSource in _dataSources.Keys) {
|
||||
|
||||
// Expand any dynamic where parameters that they may use
|
||||
dataSource.ExpandDynamicWhereParameters();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Register a data control to give it Dynamic Data behavior
|
||||
/// </summary>
|
||||
/// <param name="control"></param>
|
||||
public void RegisterControl(Control control) {
|
||||
RegisterControl(control, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Register a data control to give it Dynamic Data behavior
|
||||
/// </summary>
|
||||
/// <param name="setSelectionFromUrl">When true, if a primary key is found in the route values
|
||||
/// (typically on the query string), it will get be set as the selected item. This only applies
|
||||
/// to list controls.</param>
|
||||
public void RegisterControl(Control control, bool setSelectionFromUrl) {
|
||||
//
|
||||
if (DesignMode) {
|
||||
return;
|
||||
}
|
||||
|
||||
IDataBoundControlInterface dataBoundControl = DataControlHelper.GetDataBoundControl(control, true /*failIfNotFound*/);
|
||||
|
||||
// If we can't get an associated IDynamicDataSource, don't do anything
|
||||
IDynamicDataSource dataSource = dataBoundControl.DataSourceObject as IDynamicDataSource;
|
||||
if (dataSource == null) {
|
||||
return;
|
||||
}
|
||||
// If we can't get a MetaTable from the data source, don't do anything
|
||||
MetaTable table = MetaTableHelper.GetTableWithFullFallback(dataSource, Context.ToWrapper());
|
||||
|
||||
// Save the datasource so we can process its parameters in OnLoad. The value we set is irrelevant
|
||||
_dataSources[dataSource] = null;
|
||||
|
||||
((INamingContainer)control).SetMetaTable(table);
|
||||
|
||||
BaseDataBoundControl baseDataBoundControl = control as BaseDataBoundControl;
|
||||
if (baseDataBoundControl != null) {
|
||||
EnablePersistedSelection(baseDataBoundControl, table);
|
||||
}
|
||||
|
||||
RegisterControlInternal(dataBoundControl, dataSource, table, setSelectionFromUrl, Page.IsPostBack);
|
||||
}
|
||||
|
||||
internal static void EnablePersistedSelection(BaseDataBoundControl baseDataBoundControl, IMetaTable table) {
|
||||
Debug.Assert(baseDataBoundControl != null, "NULL!");
|
||||
// Make the persisted selection [....] up with the selected index if possible
|
||||
if (!table.IsReadOnly) {
|
||||
DynamicDataExtensions.EnablePersistedSelectionInternal(baseDataBoundControl);
|
||||
}
|
||||
}
|
||||
|
||||
internal void RegisterControlInternal(IDataBoundControlInterface dataBoundControl, IDynamicDataSource dataSource, IMetaTable table, bool setSelectionFromUrl, bool isPostBack) {
|
||||
// Set the auto field generator (for controls that support it - GridView and DetailsView)
|
||||
IFieldControl fieldControl = dataBoundControl as IFieldControl;
|
||||
if (fieldControl != null) {
|
||||
fieldControl.FieldsGenerator = new DefaultAutoFieldGenerator(table);
|
||||
}
|
||||
var linqDataSource = dataSource as LinqDataSource;
|
||||
var entityDataSource = dataSource as EntityDataSource;
|
||||
// If the context type is not set, we need to set it
|
||||
if (dataSource.ContextType == null) {
|
||||
dataSource.ContextType = table.DataContextType;
|
||||
|
||||
// If it's a LinqDataSurce, register for ContextCreating so the context gets created using the correct ctor
|
||||
// Ideally, this would work with other datasource, but we just don't have the right abstraction
|
||||
if (linqDataSource != null) {
|
||||
linqDataSource.ContextCreating += delegate(object sender, LinqDataSourceContextEventArgs e) {
|
||||
e.ObjectInstance = table.CreateContext();
|
||||
};
|
||||
}
|
||||
|
||||
if (entityDataSource != null) {
|
||||
entityDataSource.ContextCreating += delegate(object sender, EntityDataSourceContextCreatingEventArgs e) {
|
||||
e.Context = (ObjectContext)table.CreateContext();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// If the datasource doesn't have an EntitySetName (aka TableName), set it from the meta table
|
||||
if (String.IsNullOrEmpty(dataSource.EntitySetName)) {
|
||||
dataSource.EntitySetName = table.DataContextPropertyName;
|
||||
}
|
||||
|
||||
// If there is no Where clause, turn on auto generate
|
||||
if (String.IsNullOrEmpty(dataSource.Where)) {
|
||||
dataSource.AutoGenerateWhereClause = true;
|
||||
}
|
||||
|
||||
// If it's a LinqDataSource and the flag is set, pre load the foreign keys
|
||||
if (AutoLoadForeignKeys && linqDataSource != null) {
|
||||
linqDataSource.LoadWithForeignKeys(table.EntityType);
|
||||
}
|
||||
|
||||
if (!isPostBack) {
|
||||
if (table.HasPrimaryKey) {
|
||||
dataBoundControl.DataKeyNames = table.PrimaryKeyNames;
|
||||
|
||||
// Set the virtual selection from the URL if needed
|
||||
var dataKeySelector = dataBoundControl as IPersistedSelector;
|
||||
if (dataKeySelector != null && setSelectionFromUrl) {
|
||||
DataKey dataKey = table.GetDataKeyFromRoute();
|
||||
if (dataKey != null) {
|
||||
dataKeySelector.DataKey = dataKey;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internal static IControlParameterTarget GetControlParameterTarget(Control control) {
|
||||
return (control as IControlParameterTarget) ?? new DataBoundControlParameterTarget(control);
|
||||
}
|
||||
}
|
||||
}
|
200
external/referencesource/System.Web.DynamicData/DynamicData/DynamicDataRoute.cs
vendored
Normal file
200
external/referencesource/System.Web.DynamicData/DynamicData/DynamicDataRoute.cs
vendored
Normal file
@ -0,0 +1,200 @@
|
||||
using System.Web.Routing;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace System.Web.DynamicData {
|
||||
/// <summary>
|
||||
/// Route used by Dynamic Data
|
||||
/// </summary>
|
||||
public class DynamicDataRoute : Route {
|
||||
internal const string ActionToken = "Action";
|
||||
internal const string TableToken = "Table";
|
||||
internal const string ModelToken = "__Model";
|
||||
|
||||
private MetaModel _model;
|
||||
private volatile bool _initialized;
|
||||
private object _initializationLock = new object();
|
||||
|
||||
/// <summary>
|
||||
/// Construct a DynamicDataRoute
|
||||
/// </summary>
|
||||
/// <param name="url">url passed to the base ctor</param>
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings",
|
||||
Justification = "This is a URL template with special characters, not just a regular valid URL.")]
|
||||
public DynamicDataRoute(string url)
|
||||
: base(url, new DynamicDataRouteHandler()) {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Name of the table that this route applies to. Can be omitted.
|
||||
/// </summary>
|
||||
public string Table { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Action that this route applies to. Can be omitted.
|
||||
/// </summary>
|
||||
public string Action { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The ViewName is the name of the page used to handle the request. If omitted, it defaults to the Action name.
|
||||
/// </summary>
|
||||
public string ViewName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The MetaModel that this route applies to
|
||||
/// </summary>
|
||||
public MetaModel Model {
|
||||
get { return _model ?? MetaModel.Default; }
|
||||
set { _model = value; }
|
||||
}
|
||||
|
||||
// Make sure that if the Table or Action properties were used, they get added to
|
||||
// the Defaults dictionary
|
||||
private void EnsureRouteInitialize() {
|
||||
if (!_initialized) {
|
||||
lock (_initializationLock) {
|
||||
if (!_initialized) {
|
||||
// Give the model to the handler
|
||||
Debug.Assert(Model != null);
|
||||
RouteHandler.Model = Model;
|
||||
|
||||
// If neither was specified, we don't need to do anything
|
||||
if (Table == null && Action == null)
|
||||
return;
|
||||
|
||||
// If we don't already have a Defaults dictionary, create one
|
||||
if (Defaults == null)
|
||||
Defaults = new RouteValueDictionary();
|
||||
|
||||
if (Table != null) {
|
||||
// Try to get the table just to cause a failure if it doesn't exist
|
||||
var metaTable = Model.GetTable(Table);
|
||||
|
||||
Defaults[TableToken] = Table;
|
||||
}
|
||||
|
||||
if (Action != null)
|
||||
Defaults[ActionToken] = Action;
|
||||
|
||||
_initialized = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See base class documentation
|
||||
/// </summary>
|
||||
public override RouteData GetRouteData(HttpContextBase httpContext) {
|
||||
EnsureRouteInitialize();
|
||||
|
||||
// Try to get the route data for this route
|
||||
RouteData routeData = base.GetRouteData(httpContext);
|
||||
|
||||
// If not, we're done
|
||||
if (routeData == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Add all the query string values to the RouteData
|
||||
//
|
||||
AddQueryStringParamsToRouteData(httpContext, routeData);
|
||||
|
||||
// Check if the route values match an existing table and if they can be served by a scaffolded or custom page
|
||||
if (!VerifyRouteValues(routeData.Values))
|
||||
return null;
|
||||
|
||||
return routeData;
|
||||
}
|
||||
|
||||
internal static void AddQueryStringParamsToRouteData(HttpContextBase httpContext, RouteData routeData) {
|
||||
foreach (string key in httpContext.Request.QueryString) {
|
||||
// Don't overwrite existing items
|
||||
if (!routeData.Values.ContainsKey(key)) {
|
||||
routeData.Values[key] = httpContext.Request.QueryString[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See base class documentation
|
||||
/// </summary>
|
||||
public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values) {
|
||||
EnsureRouteInitialize();
|
||||
|
||||
// Check if the route values include a MetaModel
|
||||
object modelObject;
|
||||
if (values.TryGetValue(ModelToken, out modelObject)) {
|
||||
var model = modelObject as MetaModel;
|
||||
if (model != null) {
|
||||
// If it's different from the one for this route, fail the route matching
|
||||
if (modelObject != Model)
|
||||
return null;
|
||||
|
||||
// It has the right model, so we want to continue. But we first need to
|
||||
// remove this token so it doesn't affect the path
|
||||
values.Remove(ModelToken);
|
||||
}
|
||||
}
|
||||
|
||||
// Call the base to try to generate a path from this route
|
||||
VirtualPathData virtualPathData = base.GetVirtualPath(requestContext, values);
|
||||
|
||||
// If not, we're done
|
||||
if (virtualPathData == null)
|
||||
return null;
|
||||
|
||||
// Check if the route values match an existing table and if they can be served by a scaffolded or custom page
|
||||
if (VerifyRouteValues(values)) {
|
||||
return virtualPathData;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private bool VerifyRouteValues(RouteValueDictionary values) {
|
||||
// Get the MetaTable and action. If either is missing, return false to skip this route
|
||||
object tableNameObject, actionObject;
|
||||
if (!values.TryGetValue(TableToken, out tableNameObject) || !values.TryGetValue(ActionToken, out actionObject)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
MetaTable table;
|
||||
// If no table by such name is available, return false to move on to next route.
|
||||
if (!Model.TryGetTable((string)tableNameObject, out table)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if n Page can be accessed for the table/action (either scaffold or custom).
|
||||
// If not, return false so that this route is not used and the search goes on.
|
||||
return RouteHandler.CreateHandler(this, table, (string)actionObject) != null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extract the MetaTable from the RouteData. Fails if it can't find it
|
||||
/// </summary>
|
||||
/// <param name="routeData">The route data</param>
|
||||
/// <returns>The found MetaTable</returns>
|
||||
public MetaTable GetTableFromRouteData(RouteData routeData) {
|
||||
string tableName = routeData.GetRequiredString(TableToken);
|
||||
return Model.GetTable(tableName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extract the Action from the RouteData. Fails if it can't find it
|
||||
/// </summary>
|
||||
/// <param name="routeData">The route data</param>
|
||||
/// <returns>The found Action</returns>
|
||||
public string GetActionFromRouteData(RouteData routeData) {
|
||||
return routeData.GetRequiredString(ActionToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Strongly typed version of Route.RouteHandler for convenience
|
||||
/// </summary>
|
||||
public new DynamicDataRouteHandler RouteHandler {
|
||||
get { return (DynamicDataRouteHandler)base.RouteHandler; }
|
||||
set { base.RouteHandler = value; }
|
||||
}
|
||||
}
|
||||
}
|
226
external/referencesource/System.Web.DynamicData/DynamicData/DynamicDataRouteHandler.cs
vendored
Normal file
226
external/referencesource/System.Web.DynamicData/DynamicData/DynamicDataRouteHandler.cs
vendored
Normal file
@ -0,0 +1,226 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Web.Compilation;
|
||||
using System.Web.Hosting;
|
||||
using System.Web.Routing;
|
||||
using System.Web.UI;
|
||||
|
||||
namespace System.Web.DynamicData {
|
||||
/// <summary>
|
||||
/// Route handler used for Dynamic Data
|
||||
/// </summary>
|
||||
public class DynamicDataRouteHandler : IRouteHandler {
|
||||
|
||||
private static object s_requestContextKey = new object();
|
||||
private static object s_metaTableKey = new object();
|
||||
|
||||
private object _requestItemsKey = new object();
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
public DynamicDataRouteHandler() {
|
||||
VirtualPathProvider = HostingEnvironment.VirtualPathProvider;
|
||||
CreateHandlerCallback = delegate(string s) {
|
||||
return (Page)BuildManager.CreateInstanceFromVirtualPath(s, typeof(Page));
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The MetaModel that the handler is associated with
|
||||
/// </summary>
|
||||
public MetaModel Model { get; internal set; }
|
||||
|
||||
// the following properties are for mocking purposes
|
||||
internal VirtualPathProvider VirtualPathProvider { get; set; }
|
||||
private HttpContextBase _context;
|
||||
internal HttpContextBase HttpContext {
|
||||
get {
|
||||
return _context ?? new HttpContextWrapper(System.Web.HttpContext.Current);
|
||||
}
|
||||
set { _context = value; }
|
||||
}
|
||||
internal Func<string, IHttpHandler> CreateHandlerCallback { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Create a handler to process a Dynamic Data request
|
||||
/// </summary>
|
||||
/// <param name="route">The Route that was matched</param>
|
||||
/// <param name="table">The MetaTable found in the route</param>
|
||||
/// <param name="action">The Action found in the route</param>
|
||||
/// <returns></returns>
|
||||
public virtual IHttpHandler CreateHandler(DynamicDataRoute route, MetaTable table, string action) {
|
||||
// First, get the path to the page (could be custom, shared, or null)
|
||||
string virtualPath = GetPageVirtualPath(route, table, action);
|
||||
|
||||
if (virtualPath != null) {
|
||||
// Gets called only for custom pages that we know exist or templates that may or may not
|
||||
// exist. This method will throw if virtualPath does not exist, which is fine for templates
|
||||
// but is not fine for custom pages.
|
||||
return CreateHandlerCallback(virtualPath);
|
||||
} else {
|
||||
// This should only occur in the event that scaffolding is disabled and the custom page
|
||||
// virtual path does not exist.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private string GetPageVirtualPath(DynamicDataRoute route, MetaTable table, string action) {
|
||||
long cacheKey = Misc.CombineHashCodes(table, route.ViewName ?? action);
|
||||
|
||||
Dictionary<long, string> virtualPathCache = GetVirtualPathCache();
|
||||
|
||||
string virtualPath;
|
||||
if (!virtualPathCache.TryGetValue(cacheKey, out virtualPath)) {
|
||||
virtualPath = GetPageVirtualPathNoCache(route, table, action);
|
||||
lock (virtualPathCache) {
|
||||
virtualPathCache[cacheKey] = virtualPath;
|
||||
}
|
||||
}
|
||||
return virtualPath;
|
||||
}
|
||||
|
||||
private Dictionary<long, string> GetVirtualPathCache() {
|
||||
var httpContext = HttpContext;
|
||||
Dictionary<long, string> virtualPathCache = (Dictionary<long, string>)httpContext.Items[_requestItemsKey];
|
||||
if (virtualPathCache == null) {
|
||||
virtualPathCache = new Dictionary<long, string>();
|
||||
httpContext.Items[_requestItemsKey] = virtualPathCache;
|
||||
}
|
||||
return virtualPathCache;
|
||||
}
|
||||
|
||||
private string GetPageVirtualPathNoCache(DynamicDataRoute route, MetaTable table, string action) {
|
||||
// The view name defaults to the action
|
||||
string viewName = route.ViewName ?? action;
|
||||
|
||||
// First, get the path to the custom page
|
||||
string customPageVirtualPath = GetCustomPageVirtualPath(table, viewName);
|
||||
|
||||
if (VirtualPathProvider.FileExists(customPageVirtualPath)) {
|
||||
return customPageVirtualPath;
|
||||
} else {
|
||||
if (table.Scaffold) {
|
||||
// If it doesn't exist, try the scaffolded page, but only if scaffolding is enabled on this table
|
||||
return GetScaffoldPageVirtualPath(table, viewName);
|
||||
} else {
|
||||
// If scaffolding is disabled, null the path so BuildManager doesn't get called.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Build the path to a custom page. By default, it looks like ~/DynamicData/CustomPages/[tablename]/[viewname].aspx
|
||||
/// </summary>
|
||||
/// <param name="table">The MetaTable that the page is for</param>
|
||||
/// <param name="viewName">The view name</param>
|
||||
/// <returns></returns>
|
||||
protected virtual string GetCustomPageVirtualPath(MetaTable table, string viewName) {
|
||||
string pathPattern = "{0}CustomPages/{1}/{2}.aspx";
|
||||
return String.Format(CultureInfo.InvariantCulture, pathPattern, Model.DynamicDataFolderVirtualPath, table.Name, viewName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Build the path to a page template. By default, it looks like ~/DynamicData/PageTemplates/[tablename]/[viewname].aspx
|
||||
/// </summary>
|
||||
/// <param name="table">The MetaTable that the page is for</param>
|
||||
/// <param name="viewName">The view name</param>
|
||||
/// <returns></returns>
|
||||
protected virtual string GetScaffoldPageVirtualPath(MetaTable table, string viewName) {
|
||||
string pathPattern = "{0}PageTemplates/{1}.aspx";
|
||||
return String.Format(CultureInfo.InvariantCulture, pathPattern, Model.DynamicDataFolderVirtualPath, viewName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the RequestContext for this request. A new one is created if needed (can happen if the current request
|
||||
/// is not a Dynamic Data request)
|
||||
/// </summary>
|
||||
/// <param name="httpContext">The current HttpContext</param>
|
||||
/// <returns>The RequestContext</returns>
|
||||
public static RequestContext GetRequestContext(HttpContext httpContext) {
|
||||
if (httpContext == null) {
|
||||
throw new ArgumentNullException("httpContext");
|
||||
}
|
||||
|
||||
return GetRequestContext(new HttpContextWrapper(httpContext));
|
||||
}
|
||||
|
||||
internal static RequestContext GetRequestContext(HttpContextBase httpContext) {
|
||||
Debug.Assert(httpContext != null);
|
||||
|
||||
// Look for the RequestContext in the HttpContext
|
||||
var requestContext = httpContext.Items[s_requestContextKey] as RequestContext;
|
||||
|
||||
// If the current request didn't go through the routing engine (e.g. normal page),
|
||||
// there won't be a RequestContext. If so, create a new one and save it
|
||||
if (requestContext == null) {
|
||||
var routeData = new RouteData();
|
||||
requestContext = new RequestContext(httpContext, routeData);
|
||||
|
||||
// Add the query string params to the route data. This allows non routed pages to support filtering.
|
||||
DynamicDataRoute.AddQueryStringParamsToRouteData(httpContext, routeData);
|
||||
|
||||
httpContext.Items[s_requestContextKey] = requestContext;
|
||||
}
|
||||
|
||||
return requestContext;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The MetaTable associated with the current HttpRequest. Can be null for non-Dynamic Data requests.
|
||||
/// </summary>
|
||||
/// <param name="httpContext">The current HttpContext</param>
|
||||
public static MetaTable GetRequestMetaTable(HttpContext httpContext) {
|
||||
if (httpContext == null) {
|
||||
throw new ArgumentNullException("httpContext");
|
||||
}
|
||||
|
||||
return GetRequestMetaTable(new HttpContextWrapper(httpContext));
|
||||
}
|
||||
|
||||
internal static MetaTable GetRequestMetaTable(HttpContextBase httpContext) {
|
||||
Debug.Assert(httpContext != null);
|
||||
|
||||
return (MetaTable)httpContext.Items[s_metaTableKey];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the MetaTable associated with the current HttpRequest. Normally, this is set automatically from the
|
||||
/// route, but this method is useful to set the table when used outside of routing.
|
||||
/// </summary>
|
||||
public static void SetRequestMetaTable(HttpContext httpContext, MetaTable table) {
|
||||
SetRequestMetaTable(new HttpContextWrapper(httpContext), table);
|
||||
}
|
||||
|
||||
internal static void SetRequestMetaTable(HttpContextBase httpContext, MetaTable table) {
|
||||
Debug.Assert(httpContext != null);
|
||||
|
||||
httpContext.Items[s_metaTableKey] = table;
|
||||
}
|
||||
|
||||
#region IRouteHandler Members
|
||||
IHttpHandler IRouteHandler.GetHttpHandler(RequestContext requestContext) {
|
||||
// Save the RequestContext
|
||||
Debug.Assert(requestContext.HttpContext.Items[s_requestContextKey] == null);
|
||||
requestContext.HttpContext.Items[s_requestContextKey] = requestContext;
|
||||
|
||||
// Get the dynamic route
|
||||
var route = (DynamicDataRoute)requestContext.RouteData.Route;
|
||||
|
||||
// Get the Model from the route
|
||||
MetaModel model = route.Model;
|
||||
|
||||
// Get the MetaTable and save it in the HttpContext
|
||||
MetaTable table = route.GetTableFromRouteData(requestContext.RouteData);
|
||||
requestContext.HttpContext.Items[s_metaTableKey] = table;
|
||||
|
||||
// Get the action from the request context
|
||||
string action = route.GetActionFromRouteData(requestContext.RouteData);
|
||||
|
||||
return CreateHandler(route, table, action);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
113
external/referencesource/System.Web.DynamicData/DynamicData/DynamicEntity.cs
vendored
Normal file
113
external/referencesource/System.Web.DynamicData/DynamicData/DynamicEntity.cs
vendored
Normal file
@ -0,0 +1,113 @@
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Drawing;
|
||||
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 {
|
||||
[ToolboxBitmap(typeof(DynamicEntity), "DynamicEntity.bmp")]
|
||||
public class DynamicEntity : Control {
|
||||
private HttpContextBase _context;
|
||||
|
||||
[
|
||||
DefaultValue(DataBoundControlMode.ReadOnly),
|
||||
Category("Behavior"),
|
||||
ResourceDescription("DynamicEntity_Mode")
|
||||
]
|
||||
public DataBoundControlMode Mode {
|
||||
get {
|
||||
var value = ViewState["Mode"];
|
||||
return value != null ? (DataBoundControlMode)value : DataBoundControlMode.ReadOnly;
|
||||
}
|
||||
set {
|
||||
ViewState["Mode"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[
|
||||
DefaultValue(""),
|
||||
Category("Behavior"),
|
||||
ResourceDescription("DynamicControlFieldCommon_UIHint")
|
||||
]
|
||||
public string UIHint {
|
||||
get {
|
||||
return (string)ViewState["UIHint"] ?? String.Empty;
|
||||
}
|
||||
set {
|
||||
ViewState["UIHint"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[
|
||||
Category("Behavior"),
|
||||
DefaultValue(""),
|
||||
Themeable(false),
|
||||
ResourceDescription("DynamicControlFieldCommon_ValidationGroup")
|
||||
]
|
||||
public string ValidationGroup {
|
||||
get {
|
||||
return (string)ViewState["ValidationGroup"] ?? String.Empty;
|
||||
}
|
||||
set {
|
||||
ViewState["ValidationGroup"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
private new HttpContextBase Context {
|
||||
get {
|
||||
return _context ?? new HttpContextWrapper(HttpContext.Current);
|
||||
}
|
||||
}
|
||||
|
||||
public DynamicEntity() {
|
||||
}
|
||||
|
||||
// for unit testing
|
||||
internal DynamicEntity(HttpContextBase context)
|
||||
: this() {
|
||||
_context = context;
|
||||
}
|
||||
|
||||
[SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")]
|
||||
protected override void OnLoad(EventArgs e) {
|
||||
base.OnLoad(e);
|
||||
|
||||
if (DesignMode) {
|
||||
return;
|
||||
}
|
||||
|
||||
MetaTable table = MetaTableHelper.FindMetaTable(this, Context);
|
||||
if (table == null) {
|
||||
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture,
|
||||
DynamicDataResources.DynamicEntity_ControlNeedsToExistInAContextSupportingDynamicData,
|
||||
this.ID));
|
||||
}
|
||||
|
||||
EntityTemplateFactory entityTemplateFactory = table.Model.EntityTemplateFactory;
|
||||
EntityTemplateUserControl entityTemplateControl = entityTemplateFactory.CreateEntityTemplate(table, Mode, UIHint);
|
||||
if (entityTemplateControl == null) {
|
||||
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture,
|
||||
DynamicDataResources.DynamicEntity_CantFindTemplate,
|
||||
table.Name,
|
||||
entityTemplateFactory.TemplateFolderVirtualPath));
|
||||
}
|
||||
|
||||
entityTemplateControl.Mode = Mode;
|
||||
entityTemplateControl.ValidationGroup = ValidationGroup;
|
||||
entityTemplateControl.Table = table;
|
||||
Controls.Add(entityTemplateControl);
|
||||
}
|
||||
|
||||
protected override void Render(HtmlTextWriter writer) {
|
||||
if (DesignMode) {
|
||||
writer.Write("[" + GetType().Name + "]");
|
||||
}
|
||||
else {
|
||||
base.Render(writer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
412
external/referencesource/System.Web.DynamicData/DynamicData/DynamicField.cs
vendored
Normal file
412
external/referencesource/System.Web.DynamicData/DynamicData/DynamicField.cs
vendored
Normal file
@ -0,0 +1,412 @@
|
||||
namespace System.Web.DynamicData {
|
||||
using System;
|
||||
using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Web.UI;
|
||||
using System.Web.UI.WebControls;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Web.Resources;
|
||||
using System.Diagnostics;
|
||||
|
||||
/// <summary>
|
||||
/// Field type that can display DynamicData UI
|
||||
/// </summary>
|
||||
[Designer("System.Web.DynamicData.Design.DynamicFieldDesigner, " + AssemblyRef.SystemWebDynamicDataDesign)]
|
||||
public class DynamicField : DataControlField, IAttributeAccessor, IFieldFormattingOptions {
|
||||
|
||||
private bool _customConvertEmptyStringToNullSet;
|
||||
private bool _customApplyFormatInEditModeSet;
|
||||
private MetaColumn _column;
|
||||
private IDictionary<string, string> _attributes;
|
||||
|
||||
/// <summary>
|
||||
/// same as base. uses column's display name if possible
|
||||
/// </summary>
|
||||
public override string HeaderText {
|
||||
get {
|
||||
object o = ViewState["HeaderText"];
|
||||
if (o != null)
|
||||
return (string)o;
|
||||
|
||||
// Default to the Column's DisplayName
|
||||
if (Column != null)
|
||||
return Column.DisplayName;
|
||||
|
||||
// If we couldn't get it, use the name if the data field
|
||||
return DataField;
|
||||
}
|
||||
set {
|
||||
base.HeaderText = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// same as base. uses column's SortExpression property, if possible.
|
||||
/// </summary>
|
||||
public override string SortExpression {
|
||||
get {
|
||||
object o = ViewState["SortExpression"];
|
||||
if (o != null)
|
||||
return (string)o;
|
||||
|
||||
// Default to the Column's SortExpression
|
||||
if (Column != null)
|
||||
return Column.SortExpression;
|
||||
|
||||
return String.Empty;
|
||||
}
|
||||
set {
|
||||
base.SortExpression = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the control validates client input or not, defaults to inherit from parent.
|
||||
/// </summary>
|
||||
[
|
||||
Category("Behavior"),
|
||||
ResourceDescription("DynamicField_ValidateRequestMode"),
|
||||
DefaultValue(ValidateRequestMode.Inherit)
|
||||
]
|
||||
public new ValidateRequestMode ValidateRequestMode {
|
||||
get {
|
||||
return base.ValidateRequestMode;
|
||||
}
|
||||
set {
|
||||
base.ValidateRequestMode = value;
|
||||
}
|
||||
}
|
||||
|
||||
[
|
||||
SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", MessageId = "ReadOnly", Justification="Matches DataBoundControlMode value"),
|
||||
DefaultValue(false),
|
||||
Category("Behavior"),
|
||||
ResourceDescription("DynamicField_ReadOnly"),
|
||||
]
|
||||
/// <summary>
|
||||
/// Forces this DynamicField to always load a ReadOnly template
|
||||
/// </summary>
|
||||
public virtual bool ReadOnly {
|
||||
get {
|
||||
object o = ViewState["ReadOnly"];
|
||||
return (o == null ? false : (bool)o);
|
||||
}
|
||||
set {
|
||||
ViewState["ReadOnly"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The name of the column that this field handles
|
||||
/// </summary>
|
||||
[
|
||||
Category("Data"),
|
||||
DefaultValue(""),
|
||||
ResourceDescription("DynamicControlFieldCommon_DataField")
|
||||
]
|
||||
public virtual string DataField {
|
||||
get {
|
||||
object o = ViewState["DataField"];
|
||||
return ((o == null) ? String.Empty : (string)o);
|
||||
}
|
||||
set {
|
||||
if (!String.Equals(value, ViewState["DataField"])) {
|
||||
ViewState["DataField"] = value;
|
||||
OnFieldChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The MetaColumn that this fiedl is working with
|
||||
/// </summary>
|
||||
protected MetaColumn Column {
|
||||
get {
|
||||
// Don't do anything in Design mode. In some cases in the Designer (in the Edit field dialog),
|
||||
// DesignMode actually returns true, so checking for a null Control provides an additional check.
|
||||
if (DesignMode || Control == null)
|
||||
return null;
|
||||
|
||||
if (_column == null) {
|
||||
MetaTable table = Control.FindMetaTable();
|
||||
if (table == null) {
|
||||
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, DynamicDataResources.DynamicControl_ControlNeedsToExistInADataControlUsingDynamicDataSource));
|
||||
}
|
||||
_column = table.GetColumn(DataField);
|
||||
}
|
||||
return _column;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An optional UIHint specified on the field
|
||||
/// </summary>
|
||||
[
|
||||
Category("Behavior"),
|
||||
DefaultValue(""),
|
||||
ResourceDescription("DynamicControlFieldCommon_UIHint")
|
||||
]
|
||||
public virtual string UIHint {
|
||||
get {
|
||||
object o = ViewState["UIHint"];
|
||||
return ((o == null) ? String.Empty : (string)o);
|
||||
}
|
||||
set {
|
||||
if (!String.Equals(value, ViewState["UIHint"])) {
|
||||
ViewState["UIHint"] = value;
|
||||
OnFieldChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The validation group that the field template needs to be in
|
||||
/// </summary>
|
||||
[
|
||||
Category("Behavior"),
|
||||
DefaultValue(""),
|
||||
ResourceDescription("DynamicControlFieldCommon_ValidationGroup")
|
||||
]
|
||||
public virtual string ValidationGroup {
|
||||
get {
|
||||
object o = ViewState["ValidationGroup"];
|
||||
return ((o == null) ? String.Empty : (string)o);
|
||||
}
|
||||
set {
|
||||
if (!String.Equals(value, ViewState["ValidationGroup"])) {
|
||||
ViewState["ValidationGroup"] = value;
|
||||
OnFieldChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See base class documentation
|
||||
/// </summary>
|
||||
protected override DataControlField CreateField() {
|
||||
return new DynamicField();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See base class documentation
|
||||
/// </summary>
|
||||
public override void InitializeCell(DataControlFieldCell cell, DataControlCellType cellType,
|
||||
DataControlRowState rowState, int rowIndex) {
|
||||
|
||||
base.InitializeCell(cell, cellType, rowState, rowIndex);
|
||||
|
||||
if (cellType == DataControlCellType.DataCell) {
|
||||
DynamicControl control = CreateDynamicControl();
|
||||
control.DataField = DataField;
|
||||
control.Mode = DetermineControlMode(rowState);
|
||||
|
||||
// Copy various properties into the control
|
||||
if (_customApplyFormatInEditModeSet) {
|
||||
control.ApplyFormatInEditMode = ApplyFormatInEditMode;
|
||||
}
|
||||
if (_customConvertEmptyStringToNullSet) {
|
||||
control.ConvertEmptyStringToNull = ConvertEmptyStringToNull;
|
||||
}
|
||||
control.DataFormatString = DataFormatString;
|
||||
if (ViewState["HtmlEncode"] == null) {
|
||||
// There is no Column in Design Mode
|
||||
if (!DesignMode) {
|
||||
control.HtmlEncode = Column.HtmlEncode;
|
||||
}
|
||||
}
|
||||
else {
|
||||
control.HtmlEncode = HtmlEncode;
|
||||
}
|
||||
control.NullDisplayText = NullDisplayText;
|
||||
control.UIHint = UIHint;
|
||||
control.ValidationGroup = ValidationGroup;
|
||||
|
||||
// Pass it all the extra declarative attributes that we got
|
||||
control.SetAttributes(_attributes);
|
||||
|
||||
ConfigureDynamicControl(control);
|
||||
|
||||
cell.Controls.Add(control);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Provides a way for classes deriving from DynamicField to override how DynamicControl gets created.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected virtual DynamicControl CreateDynamicControl() {
|
||||
return new DynamicControl();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Provides a hook to further modify a DynamicControl that was created by the InitializeCell method
|
||||
/// </summary>
|
||||
/// <param name="control"></param>
|
||||
protected virtual void ConfigureDynamicControl(DynamicControl control) {
|
||||
Debug.Assert(control != null);
|
||||
}
|
||||
|
||||
private DataBoundControlMode DetermineControlMode(DataControlRowState rowState) {
|
||||
if (ReadOnly) {
|
||||
return DataBoundControlMode.ReadOnly;
|
||||
}
|
||||
|
||||
bool edit = (rowState & DataControlRowState.Edit) != 0;
|
||||
bool insert = (rowState & DataControlRowState.Insert) != 0;
|
||||
|
||||
if (edit) {
|
||||
return DataBoundControlMode.Edit;
|
||||
} else if (insert) {
|
||||
return DataBoundControlMode.Insert;
|
||||
} else {
|
||||
return DataBoundControlMode.ReadOnly;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See base class documentation
|
||||
/// </summary>
|
||||
public override void ExtractValuesFromCell(IOrderedDictionary dictionary, DataControlFieldCell cell,
|
||||
DataControlRowState rowState, bool includeReadOnly) {
|
||||
Misc.ExtractValuesFromBindableControls(dictionary, cell);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See base class documentation
|
||||
/// </summary>
|
||||
protected override void CopyProperties(DataControlField newField) {
|
||||
base.CopyProperties(newField);
|
||||
DynamicField field = ((DynamicField)newField);
|
||||
field.DataField = DataField;
|
||||
field.ApplyFormatInEditMode = ApplyFormatInEditMode;
|
||||
field.ConvertEmptyStringToNull = ConvertEmptyStringToNull;
|
||||
field.HtmlEncode = HtmlEncode;
|
||||
field.ReadOnly = ReadOnly;
|
||||
field.NullDisplayText = NullDisplayText;
|
||||
field.UIHint = UIHint;
|
||||
field.ValidationGroup = ValidationGroup;
|
||||
field.DataFormatString = DataFormatString;
|
||||
}
|
||||
|
||||
#region IAttributeAccessor Members
|
||||
|
||||
/// <summary>
|
||||
/// See IAttributeAccessor
|
||||
/// </summary>
|
||||
public string GetAttribute(string key) {
|
||||
if (_attributes == null)
|
||||
return String.Empty;
|
||||
return _attributes[key];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See IAttributeAccessor
|
||||
/// </summary>
|
||||
public void SetAttribute(string key, string value) {
|
||||
if (_attributes == null) {
|
||||
_attributes = new Dictionary<string, string>();
|
||||
}
|
||||
_attributes[key] = value;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IFieldFormattingOptions Members
|
||||
|
||||
/// <summary>
|
||||
/// See IFieldFormattingOptions
|
||||
/// </summary>
|
||||
[
|
||||
Category("Behavior"),
|
||||
DefaultValue(false),
|
||||
ResourceDescription("DynamicControlFieldCommon_ConvertEmptyStringToNull")
|
||||
]
|
||||
public bool ConvertEmptyStringToNull {
|
||||
get {
|
||||
object o = ViewState["ConvertEmptyStringToNull"];
|
||||
return (o == null ? false : (bool)o);
|
||||
}
|
||||
set {
|
||||
_customConvertEmptyStringToNullSet = true;
|
||||
ViewState["ConvertEmptyStringToNull"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See IFieldFormattingOptions
|
||||
/// </summary>
|
||||
[
|
||||
Category("Behavior"),
|
||||
DefaultValue(false),
|
||||
ResourceDescription("DynamicControlFieldCommon_ApplyFormatInEditMode")
|
||||
]
|
||||
public bool ApplyFormatInEditMode {
|
||||
get {
|
||||
object o = ViewState["ApplyFormatInEditMode"];
|
||||
return (o == null ? false : (bool)o);
|
||||
}
|
||||
set {
|
||||
_customApplyFormatInEditModeSet = true;
|
||||
ViewState["ApplyFormatInEditMode"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See IFieldFormattingOptions
|
||||
/// </summary>
|
||||
[
|
||||
Category("Data"),
|
||||
DefaultValue(""),
|
||||
ResourceDescription("DynamicControlFieldCommon_DataFormatString")
|
||||
]
|
||||
public string DataFormatString {
|
||||
get {
|
||||
object o = ViewState["DataFormatString"];
|
||||
return (o == null ? String.Empty : (string)o);
|
||||
}
|
||||
set {
|
||||
ViewState["DataFormatString"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See IFieldFormattingOptions
|
||||
/// </summary>
|
||||
[
|
||||
Category("Behavior"),
|
||||
DefaultValue(true),
|
||||
ResourceDescription("DynamicControlFieldCommon_HtmlEncode")
|
||||
]
|
||||
public bool HtmlEncode {
|
||||
get {
|
||||
object o = ViewState["HtmlEncode"];
|
||||
return (o == null ? true : (bool)o);
|
||||
}
|
||||
set {
|
||||
ViewState["HtmlEncode"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See IFieldFormattingOptions
|
||||
/// </summary>
|
||||
[
|
||||
Category("Behavior"),
|
||||
DefaultValue(""),
|
||||
ResourceDescription("DynamicControlFieldCommon_NullDisplayText")
|
||||
]
|
||||
public string NullDisplayText {
|
||||
get {
|
||||
object o = ViewState["NullDisplayText"];
|
||||
return (o == null ? String.Empty : (string)o);
|
||||
}
|
||||
set {
|
||||
ViewState["NullDisplayText"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
152
external/referencesource/System.Web.DynamicData/DynamicData/DynamicFilter.cs
vendored
Normal file
152
external/referencesource/System.Web.DynamicData/DynamicData/DynamicFilter.cs
vendored
Normal file
@ -0,0 +1,152 @@
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Web.Compilation;
|
||||
using System.Web.UI;
|
||||
using System.Web.UI.WebControls;
|
||||
using System.Web.UI.WebControls.Expressions;
|
||||
using System.Web.Resources;
|
||||
|
||||
namespace System.Web.DynamicData {
|
||||
public class DynamicFilter : Control, IFilterExpressionProvider {
|
||||
private HttpContextBase _context;
|
||||
private IQueryableDataSource _dataSource;
|
||||
private Func<MetaColumn, string, QueryableFilterUserControl> _filterLoader;
|
||||
private QueryableFilterUserControl _filterUserControl;
|
||||
|
||||
protected internal MetaColumn Column {
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The name of the column that this control handles
|
||||
/// </summary>
|
||||
[
|
||||
Category("Data"),
|
||||
DefaultValue(""),
|
||||
ResourceDescription("DynamicFilter_DataField")
|
||||
]
|
||||
public string DataField {
|
||||
get {
|
||||
object o = ViewState["DataField"];
|
||||
return (o == null) ? String.Empty : (string)o;
|
||||
}
|
||||
set {
|
||||
ViewState["DataField"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An optional property that can be used to override the column's default default filter UI hint.
|
||||
/// </summary>
|
||||
[
|
||||
Category("Behavior"),
|
||||
DefaultValue(""),
|
||||
ResourceDescription("DynamicFilter_FilterUIHint")
|
||||
]
|
||||
public string FilterUIHint {
|
||||
get {
|
||||
object o = ViewState["FilterUIHint"];
|
||||
return (o == null) ? String.Empty : (string)o;
|
||||
}
|
||||
set {
|
||||
ViewState["FilterUIHint"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public DynamicFilter()
|
||||
: this(CreateUserControl) {
|
||||
}
|
||||
|
||||
// internal for unit testing
|
||||
internal DynamicFilter(Func<MetaColumn, string, QueryableFilterUserControl> filterLoader) {
|
||||
_filterLoader = filterLoader;
|
||||
}
|
||||
|
||||
// internal for unit testing
|
||||
internal static QueryableFilterUserControl CreateUserControl(MetaColumn column, string filterUiHint) {
|
||||
return column.Model.FilterFactory.CreateFilterControl(column, filterUiHint);
|
||||
}
|
||||
|
||||
internal new HttpContextBase Context {
|
||||
get {
|
||||
return _context ?? new HttpContextWrapper(HttpContext.Current);
|
||||
}
|
||||
set {
|
||||
_context = value;
|
||||
}
|
||||
}
|
||||
|
||||
public event EventHandler FilterChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Returns the filter template that was created for this control.
|
||||
/// </summary>
|
||||
[Browsable(false)]
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
public Control FilterTemplate {
|
||||
get {
|
||||
return _filterUserControl;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Render(HtmlTextWriter writer) {
|
||||
if (DesignMode) {
|
||||
writer.Write("[" + GetType().Name + "]");
|
||||
}
|
||||
else {
|
||||
base.Render(writer);
|
||||
}
|
||||
}
|
||||
|
||||
private void EnsureInit(IQueryableDataSource dataSource) {
|
||||
if (_filterUserControl == null) {
|
||||
MetaTable table = DynamicDataExtensions.GetMetaTable(dataSource, Context);
|
||||
Column = table.GetColumn(DataField);
|
||||
_filterUserControl = _filterLoader(Column, FilterUIHint);
|
||||
_filterUserControl.Initialize(Column, dataSource, Context);
|
||||
|
||||
_filterUserControl.FilterChanged += new EventHandler(Child_FilterChanged);
|
||||
|
||||
Controls.Add(_filterUserControl);
|
||||
}
|
||||
}
|
||||
|
||||
private void Child_FilterChanged(object sender, EventArgs e) {
|
||||
EventHandler eventHandler = FilterChanged;
|
||||
if (eventHandler != null) {
|
||||
eventHandler(sender, e);
|
||||
}
|
||||
}
|
||||
|
||||
internal void Initialize(IQueryableDataSource dataSource) {
|
||||
Debug.Assert(dataSource != null);
|
||||
EnsureInit(dataSource);
|
||||
}
|
||||
|
||||
#region IFilterExpressionProvider Members
|
||||
|
||||
void IFilterExpressionProvider.Initialize(IQueryableDataSource dataSource) {
|
||||
if (dataSource == null) {
|
||||
throw new ArgumentNullException("dataSource");
|
||||
}
|
||||
|
||||
_dataSource = dataSource;
|
||||
|
||||
Page.InitComplete += new EventHandler(Page_InitComplete);
|
||||
}
|
||||
|
||||
void Page_InitComplete(object sender, EventArgs e) {
|
||||
Debug.Assert(_dataSource != null);
|
||||
EnsureInit(_dataSource);
|
||||
}
|
||||
|
||||
IQueryable IFilterExpressionProvider.GetQueryable(IQueryable source) {
|
||||
return _filterUserControl.GetQueryable(source);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
47
external/referencesource/System.Web.DynamicData/DynamicData/DynamicFilterExpression.cs
vendored
Normal file
47
external/referencesource/System.Web.DynamicData/DynamicData/DynamicFilterExpression.cs
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
using System.Linq.Expressions;
|
||||
using System.Web.UI;
|
||||
using System.Globalization;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Web.UI.WebControls.Expressions;
|
||||
using System.Web.UI.WebControls;
|
||||
|
||||
namespace System.Web.DynamicData {
|
||||
/// <summary>
|
||||
/// This is a Dynamic Data-specific extension of DataSourceExpression that works by forwarding the processing of an IQueryable to
|
||||
/// a specialized control such as QueryableFilterRepeater or DynamicFilter.
|
||||
/// </summary>
|
||||
public class DynamicFilterExpression : DataSourceExpression {
|
||||
/// <summary>
|
||||
/// References the ID of a QueryableFilterRepeater or DynamicFilter control on the page.
|
||||
/// </summary>
|
||||
[SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "ID", Justification = "This refers to a Control ID")]
|
||||
public string ControlID { get; set; }
|
||||
private IFilterExpressionProvider FilterExpressionProvider { get; set; }
|
||||
|
||||
public override void SetContext(Control owner, HttpContext context, IQueryableDataSource dataSource) {
|
||||
base.SetContext(owner, context, dataSource);
|
||||
|
||||
FilterExpressionProvider = FindControl(Owner);
|
||||
FilterExpressionProvider.Initialize(dataSource);
|
||||
}
|
||||
|
||||
private IFilterExpressionProvider FindControl(Control control) {
|
||||
var result = Misc.FindControl(control, ControlID) as IFilterExpressionProvider;
|
||||
if (result == null) {
|
||||
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, "The control '{0}' could not be found.", ControlID));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Delegates the processing of the source queryable to the control referenced by ControlID.
|
||||
/// </summary>
|
||||
/// <param name="source"></param>
|
||||
/// <returns></returns>
|
||||
public override IQueryable GetQueryable(IQueryable source) {
|
||||
IQueryable result = FilterExpressionProvider.GetQueryable(source);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
282
external/referencesource/System.Web.DynamicData/DynamicData/DynamicHyperLink.cs
vendored
Normal file
282
external/referencesource/System.Web.DynamicData/DynamicData/DynamicHyperLink.cs
vendored
Normal file
@ -0,0 +1,282 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Drawing;
|
||||
using System.Globalization;
|
||||
using System.Security.Permissions;
|
||||
using System.Web.Compilation;
|
||||
using System.Web.Resources;
|
||||
using System.Web.Routing;
|
||||
using System.Web.UI;
|
||||
using System.Web.UI.WebControls;
|
||||
using System.Web.DynamicData.Util;
|
||||
|
||||
namespace System.Web.DynamicData {
|
||||
/// <summary>
|
||||
/// <para>A control that displays links to table actions based on routing rules. It will not generate links for actions that are not
|
||||
/// allowed by the routing rules. It can work in 3 modes: explicit, databinding to MetaTable, or databinding to a data row.</para>
|
||||
/// <para>Databinding to MetaTable allows for creating links to actions for a collection of MetaTable objects (such as in the Default.aspx
|
||||
/// page in the project templates)</para>
|
||||
/// <para>Databinding to a data row allows for creating links to actions for data rows retrieved from a database. These are usually used with
|
||||
/// Edit and Details actions.</para>
|
||||
/// <para>Explicit mode allows for links to non-item-specific actions (like List and Insert) and is achieved by properly setting
|
||||
/// ContextTypeName, Table, and Action properties. This is done in the PreRender phase if the NavigateUrl property is null (i.e. it has not
|
||||
/// been set explicitly or did not get set in one of the databinding scenarios.)</para>
|
||||
/// <para>Extra route parameters can be provided by declaring expando attributes on the controls markup.</para>
|
||||
/// </summary>
|
||||
[SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "HyperLink", Justification="It's an extension of the HyperLink class")]
|
||||
[DefaultProperty("Action")]
|
||||
[ToolboxBitmap(typeof(DynamicHyperLink), "DynamicHyperLink.bmp")]
|
||||
public class DynamicHyperLink : HyperLink, IAttributeAccessor {
|
||||
private HttpContextBase _context;
|
||||
private bool _dataBound;
|
||||
private object _dataItem;
|
||||
private Dictionary<string, string> _extraRouteParams = new Dictionary<string, string>();
|
||||
|
||||
/// <summary>
|
||||
/// The name of the action
|
||||
/// </summary>
|
||||
[TypeConverter(typeof(ActionConverter))]
|
||||
[DefaultValue("")]
|
||||
[Category("Navigation")]
|
||||
[ResourceDescription("DynamicHyperLink_Action")]
|
||||
public string Action {
|
||||
get {
|
||||
object o = ViewState["Action"];
|
||||
return (o == null ? String.Empty: (string)o);
|
||||
}
|
||||
set {
|
||||
ViewState["Action"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal new HttpContextBase Context {
|
||||
get {
|
||||
return _context ?? new HttpContextWrapper(base.Context);
|
||||
}
|
||||
set {
|
||||
_context = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The name of the context type
|
||||
/// </summary>
|
||||
[DefaultValue("")]
|
||||
[Category("Navigation")]
|
||||
[ResourceDescription("DynamicHyperLink_ContextTypeName")]
|
||||
public string ContextTypeName {
|
||||
get {
|
||||
object o = ViewState["ContextTypeName"];
|
||||
return ((o == null) ? String.Empty : (string)o);
|
||||
}
|
||||
set {
|
||||
ViewState["ContextTypeName"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The name of the column whose value will be used to populate the Text
|
||||
/// property if it is not already set in data binding scenarios.
|
||||
/// </summary>
|
||||
[DefaultValue("")]
|
||||
[Category("Navigation")]
|
||||
[ResourceDescription("DynamicHyperLink_DataField")]
|
||||
public string DataField {
|
||||
get {
|
||||
object o = ViewState["DataField"];
|
||||
return ((o == null) ? String.Empty : (string)o);
|
||||
}
|
||||
set {
|
||||
ViewState["DataField"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
// for unit testing purposes
|
||||
internal object Page_DataItem {
|
||||
get {
|
||||
return _dataItem ?? Page.GetDataItem();
|
||||
}
|
||||
set {
|
||||
_dataItem = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The name of the table
|
||||
/// </summary>
|
||||
[DefaultValue("")]
|
||||
[Category("Navigation")]
|
||||
[ResourceDescription("DynamicHyperLink_TableName")]
|
||||
public string TableName {
|
||||
get {
|
||||
object o = ViewState["TableName"];
|
||||
return ((o == null) ? String.Empty : (string)o);
|
||||
}
|
||||
set {
|
||||
ViewState["TableName"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")]
|
||||
protected override void OnDataBinding(EventArgs e) {
|
||||
base.OnDataBinding(e);
|
||||
|
||||
if (DesignMode) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!String.IsNullOrEmpty(NavigateUrl)) {
|
||||
// stop processing if there already is a URL
|
||||
return;
|
||||
}
|
||||
|
||||
if (!String.IsNullOrEmpty(TableName) || !String.IsNullOrEmpty(ContextTypeName)) {
|
||||
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture,
|
||||
DynamicDataResources.DynamicHyperLink_CannotSetTableAndContextWhenDatabinding, this.ID));
|
||||
}
|
||||
|
||||
object dataItem = Page_DataItem;
|
||||
if (dataItem == null) {
|
||||
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture,
|
||||
DynamicDataResources.DynamicHyperLink_CannotBindToNull, this.ID));
|
||||
}
|
||||
|
||||
MetaTable table = dataItem as MetaTable;
|
||||
if (table != null) {
|
||||
BindToMetaTable(table);
|
||||
} else {
|
||||
BindToDataItem(dataItem);
|
||||
}
|
||||
|
||||
_dataBound = true;
|
||||
}
|
||||
|
||||
private void BindToMetaTable(MetaTable table) {
|
||||
string action = GetActionOrDefaultTo(PageAction.List);
|
||||
NavigateUrl = table.GetActionPath(action, GetRouteValues());
|
||||
if (String.IsNullOrEmpty(Text)) {
|
||||
Text = table.DisplayName;
|
||||
}
|
||||
}
|
||||
|
||||
private void BindToDataItem(object dataItem) {
|
||||
dataItem = Misc.GetRealDataItem(dataItem);
|
||||
Debug.Assert(dataItem != null, "DataItem is null");
|
||||
// Try to get the MetaTable from the type and if we can't find it then ---- up.
|
||||
MetaTable table = Misc.GetTableFromTypeHierarchy(dataItem.GetType());
|
||||
if (table == null) {
|
||||
throw new InvalidOperationException(String.Format(
|
||||
CultureInfo.CurrentCulture,
|
||||
DynamicDataResources.MetaModel_EntityTypeDoesNotBelongToModel,
|
||||
dataItem.GetType().FullName));
|
||||
}
|
||||
|
||||
string action = GetActionOrDefaultTo(PageAction.Details);
|
||||
NavigateUrl = table.GetActionPath(action, GetRouteValues(table, dataItem));
|
||||
|
||||
if (String.IsNullOrEmpty(Text)) {
|
||||
if (!String.IsNullOrEmpty(DataField)) {
|
||||
Text = DataBinder.GetPropertyValue(dataItem, DataField).ToString();
|
||||
} else {
|
||||
Text = table.GetDisplayString(dataItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")]
|
||||
protected override void OnPreRender(EventArgs e) {
|
||||
base.OnPreRender(e);
|
||||
|
||||
if (DesignMode) {
|
||||
if (!String.IsNullOrEmpty(NavigateUrl)) {
|
||||
NavigateUrl = "DesignTimeUrl";
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// check both _dataBound and NavigateUrl cause NavigateUrl might be empty if routing/scaffolding
|
||||
// does not allow a particular action
|
||||
if (!_dataBound && String.IsNullOrEmpty(NavigateUrl)) {
|
||||
MetaTable table;
|
||||
try {
|
||||
table = GetTable();
|
||||
} catch (Exception exception) {
|
||||
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, DynamicDataResources.DynamicHyperLink_CannotDetermineTable, this.ID), exception);
|
||||
}
|
||||
|
||||
if (table == null) {
|
||||
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, DynamicDataResources.DynamicHyperLink_CannotDetermineTable, this.ID));
|
||||
}
|
||||
|
||||
var action = GetActionOrDefaultTo(PageAction.List);
|
||||
NavigateUrl = table.GetActionPath(action, GetRouteValues());
|
||||
}
|
||||
}
|
||||
|
||||
private RouteValueDictionary GetRouteValues() {
|
||||
var routeValues = new RouteValueDictionary();
|
||||
foreach (var entry in _extraRouteParams) {
|
||||
string key = entry.Key;
|
||||
routeValues[key] = entry.Value;
|
||||
}
|
||||
return routeValues;
|
||||
}
|
||||
|
||||
private RouteValueDictionary GetRouteValues(MetaTable table, object row) {
|
||||
RouteValueDictionary routeValues = GetRouteValues();
|
||||
foreach (var pk in table.GetPrimaryKeyDictionary(row)) {
|
||||
routeValues[pk.Key] = pk.Value;
|
||||
}
|
||||
return routeValues;
|
||||
}
|
||||
|
||||
private string GetActionOrDefaultTo(string defaultAction) {
|
||||
return String.IsNullOrEmpty(Action) ? defaultAction : Action;
|
||||
}
|
||||
|
||||
// internal for unit testing
|
||||
internal virtual MetaTable GetTable() {
|
||||
MetaTable table;
|
||||
if (!String.IsNullOrEmpty(TableName)) {
|
||||
table = GetTableFromTableName();
|
||||
} else {
|
||||
table = DynamicDataRouteHandler.GetRequestMetaTable(Context);
|
||||
}
|
||||
return table;
|
||||
}
|
||||
|
||||
private MetaTable GetTableFromTableName() {
|
||||
var tableName = TableName;
|
||||
var contextTypeName = ContextTypeName;
|
||||
Debug.Assert(!String.IsNullOrEmpty(tableName));
|
||||
|
||||
if (!String.IsNullOrEmpty(contextTypeName)) {
|
||||
// context type allows to disambiguate table names
|
||||
Type contextType = BuildManager.GetType(contextTypeName, /* throwOnError */ true, /* ignoreCase */ true);
|
||||
MetaModel model = MetaModel.GetModel(contextType);
|
||||
MetaTable table = model.GetTable(tableName, contextType);
|
||||
return table;
|
||||
} else {
|
||||
var table = DynamicDataRouteHandler.GetRequestMetaTable(Context);
|
||||
if (table == null) {
|
||||
return null;
|
||||
}
|
||||
return table.Model.GetTable(tableName);
|
||||
}
|
||||
}
|
||||
|
||||
#region IAttributeAccessor Members
|
||||
|
||||
string IAttributeAccessor.GetAttribute(string key) {
|
||||
return (string)_extraRouteParams[key];
|
||||
}
|
||||
|
||||
void IAttributeAccessor.SetAttribute(string key, string value) {
|
||||
_extraRouteParams[key] = value;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
42
external/referencesource/System.Web.DynamicData/DynamicData/DynamicQueryStringParameter.cs
vendored
Normal file
42
external/referencesource/System.Web.DynamicData/DynamicData/DynamicQueryStringParameter.cs
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
using System.Collections.Generic;
|
||||
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>
|
||||
/// DynamicQueryStringParameter allows a datasource to have its primary key easily fed from the query string.
|
||||
/// It does not require any attributes, and works even for multi-part primary keys.
|
||||
/// </summary>
|
||||
public class DynamicQueryStringParameter : Parameter, IWhereParametersProvider {
|
||||
/// <summary>
|
||||
/// See IWhereParametersProvider.GetWhereParameters
|
||||
/// </summary>
|
||||
public virtual IEnumerable<Parameter> GetWhereParameters(IDynamicDataSource dataSource) {
|
||||
var table = MetaTableHelper.GetTableWithFullFallback(dataSource, HttpContext.Current.ToWrapper());
|
||||
|
||||
// check makes no sense as the above call will throw
|
||||
//if (table == null) {
|
||||
// return new Parameter[0];
|
||||
//}
|
||||
|
||||
return RouteParametersHelper.GetColumnParameters(table, Name);
|
||||
}
|
||||
|
||||
/// <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(DynamicQueryStringParameter).Name));
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user