1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
|
//------------------------------------------------------------------------------
// <copyright file="DataBoundControlHelper.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
namespace System.Web.UI.WebControls {
using System;
using System.Collections.Specialized;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Reflection;
using System.Web.Compilation;
using System.Web.Util;
/// <devdoc>
/// Helper class for DataBoundControls and v1 data controls.
/// This is also used by ControlParameter to find its associated
/// control.
/// </devdoc>
internal static class DataBoundControlHelper {
private static MethodInfo s_enableDynamicDataMethod;
/// <devdoc>
/// Walks up the stack of NamingContainers starting at 'control' to find a control with the ID 'controlID'.
/// Important : Note that the search is never done on the 'control' itself by this method.
/// </devdoc>
public static Control FindControl(Control control, string controlID) {
Debug.Assert(control != null, "control should not be null");
Debug.Assert(!String.IsNullOrEmpty(controlID), "controlID should not be empty");
Control currentContainer = control;
Control foundControl = null;
if (control == control.Page) {
// If we get to the Page itself while we're walking up the
// hierarchy, just return whatever item we find (if anything)
// since we can't walk any higher.
return control.FindControl(controlID);
}
while (foundControl == null && currentContainer != control.Page) {
currentContainer = currentContainer.NamingContainer;
if (currentContainer == null) {
throw new HttpException(SR.GetString(SR.DataBoundControlHelper_NoNamingContainer, control.GetType().Name, control.ID));
}
foundControl = currentContainer.FindControl(controlID);
}
return foundControl;
}
/// <devdoc>
// return true if the two string arrays have the same members
/// </devdoc>
public static bool CompareStringArrays(string[] stringA, string[] stringB) {
if (stringA == null && stringB == null) {
return true;
}
if (stringA == null || stringB == null) {
return false;
}
if (stringA.Length != stringB.Length) {
return false;
}
for (int i = 0; i < stringA.Length; i++) {
if (!String.Equals(stringA[i], stringB[i], StringComparison.Ordinal)) {
return false;
}
}
return true;
}
//The enableEnums parameter is introduced for backward comapatibility (false for compatible with older versions).
internal static bool IsBindableType(Type type, bool enableEnums) {
if (type == null) {
return false;
}
Type underlyingType = Nullable.GetUnderlyingType(type);
if (underlyingType != null) {
// If the type is Nullable then it has an underlying type, in which case
// we want to check the underlying type for bindability.
type = underlyingType;
}
if (type.IsPrimitive ||
(type == typeof(string)) ||
(type == typeof(DateTime)) ||
(type == typeof(Decimal)) ||
(type == typeof(Guid)) ||
// support for new SqlServer 2008 types:
(type == typeof(DateTimeOffset)) ||
(type == typeof(TimeSpan))) {
return true;
}
else {
BindableTypeAttribute bindableTypeAttribute = (BindableTypeAttribute)TypeDescriptor.GetAttributes(type)[typeof(BindableTypeAttribute)];
if (bindableTypeAttribute != null) {
return bindableTypeAttribute.IsBindable;
}
else {
//We consider enums as Bindable types by default but provide an opt-out mechanism using BindableTypeAttribute. (Ex : EntityState)
//So the order of above if-else block is important.
return (enableEnums && type.IsEnum);
}
}
}
internal static void ExtractValuesFromBindableControls(IOrderedDictionary dictionary, Control container) {
IBindableControl bindableControl = container as IBindableControl;
if (bindableControl != null) {
bindableControl.ExtractValues(dictionary);
}
foreach (Control childControl in container.Controls) {
ExtractValuesFromBindableControls(dictionary, childControl);
}
}
internal static void EnableDynamicData(INamingContainer control, string entityTypeName) {
if (control == null) {
throw new ArgumentNullException("control");
}
if (s_enableDynamicDataMethod == null) {
Type dataControlExtensionsType = Assembly.Load(AssemblyRef.SystemWebDynamicData).GetType("System.Web.UI.DataControlExtensions");
s_enableDynamicDataMethod = dataControlExtensionsType.GetMethod("EnableDynamicData",
BindingFlags.Public | BindingFlags.Static,
binder: null,
types: new Type[] { typeof(INamingContainer), typeof(Type) },
modifiers: null);
}
Debug.Assert(s_enableDynamicDataMethod != null);
Type entityType = BuildManager.GetType(entityTypeName, throwOnError: false);
if (entityType != null) {
s_enableDynamicDataMethod.Invoke(obj: null,
parameters: new object[] { control, entityType });
}
}
}
}
|