1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
|
//------------------------------------------------------------------------------
// <copyright file="BindableTemplateBuilder.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
/*
* Classes related to templated control support
*
* Copyright (c) 1999 Microsoft Corporation
*/
namespace System.Web.UI {
using System;
using System.Collections;
using System.Collections.Specialized;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Globalization;
using System.Reflection;
using System.Security.Permissions;
using System.Web.Util;
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public sealed class BindableTemplateBuilder : TemplateBuilder, IBindableTemplate {
private ExtractTemplateValuesMethod _extractTemplateValuesMethod;
/*
* No-compile delegate handler for ExtractValues.
*/
private IOrderedDictionary ExtractTemplateValuesMethod(Control container) {
/*System.Web.UI.OrderedDictionary @__table;
System.Web.UI.WebControls.DropDownList ddl2;
@__table = new System.Web.UI.OrderedDictionary();
ddl2 = ((System.Web.UI.WebControls.DropDownList)(@__container.FindControl("ddl2")));
if ((ddl2 != null)) {
@__table["FavVegetable"] = ddl2.SelectedValue;
}
return @__table;*/
BindableTemplateBuilder bindableTemplateBuilder = this as BindableTemplateBuilder;
Debug.Assert(bindableTemplateBuilder != null, "ExtractTemplateValuesMethod called on non-BindableTemplateBuilder.");
OrderedDictionary table = new OrderedDictionary();
if (bindableTemplateBuilder != null) {
ExtractTemplateValuesRecursive(bindableTemplateBuilder.SubBuilders, table, container);
}
return table;
}
private void ExtractTemplateValuesRecursive(ArrayList subBuilders, OrderedDictionary table, Control container) {
foreach (object subBuilderObject in subBuilders) {
ControlBuilder subBuilderControlBuilder = subBuilderObject as ControlBuilder;
if (subBuilderControlBuilder != null) {
ICollection entries;
// filter out device filtered bound entries that don't apply to this device
if (!subBuilderControlBuilder.HasFilteredBoundEntries) {
entries = subBuilderControlBuilder.BoundPropertyEntries;
}
else {
Debug.Assert(subBuilderControlBuilder.ServiceProvider == null);
Debug.Assert(subBuilderControlBuilder.TemplateControl != null, "TemplateControl should not be null in no-compile pages. We need it for the FilterResolutionService.");
ServiceContainer serviceContainer = new ServiceContainer();
serviceContainer.AddService(typeof(IFilterResolutionService), subBuilderControlBuilder.TemplateControl);
try {
subBuilderControlBuilder.SetServiceProvider(serviceContainer);
entries = subBuilderControlBuilder.GetFilteredPropertyEntrySet(subBuilderControlBuilder.BoundPropertyEntries);
}
finally {
subBuilderControlBuilder.SetServiceProvider(null);
}
}
string previousControlName = null;
bool newControl = true;
Control control = null;
foreach (BoundPropertyEntry entry in entries) {
// Skip all entries that are not two-way
if (!entry.TwoWayBound)
continue;
// Reset the "previous" Property Entry if we're not looking at the same control.
// If we don't do this, Two controls that have conditionals on the same named property will have
// their conditionals incorrectly merged.
if (String.Compare(previousControlName, entry.ControlID, StringComparison.Ordinal) != 0) {
newControl = true;
}
else {
newControl = false;
}
previousControlName = entry.ControlID;
if (newControl) {
control = container.FindControl(entry.ControlID);
if (control == null || !entry.ControlType.IsInstanceOfType(control)) {
Debug.Assert(false, "BoundPropertyEntry is of wrong control type or couldn't be found. Expected " + entry.ControlType.Name);
continue;
}
}
string propertyName;
// map the property in case it's a complex property
object targetObject = PropertyMapper.LocatePropertyObject(control, entry.Name, out propertyName, InDesigner);
// FastPropertyAccessor uses ReflectEmit for lightning speed
table[entry.FieldName] = FastPropertyAccessor.GetProperty(targetObject, propertyName, InDesigner);
}
ExtractTemplateValuesRecursive(subBuilderControlBuilder.SubBuilders, table, container);
}
}
}
/*
* IBindableTemplate implementation
* This implementation of ITemplate is used in the designer and no-compile.
*/
public IOrderedDictionary ExtractValues(Control container) {
if (_extractTemplateValuesMethod != null && !InDesigner) {
return _extractTemplateValuesMethod(container);
}
return new OrderedDictionary();
}
public override void OnAppendToParentBuilder(ControlBuilder parentBuilder) {
base.OnAppendToParentBuilder(parentBuilder);
if (HasTwoWayBoundProperties) {
_extractTemplateValuesMethod = new ExtractTemplateValuesMethod(ExtractTemplateValuesMethod);
}
}
}
// Delegates used for the compiled template and no-compile Bind
/// <internalonly/>
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public delegate IOrderedDictionary ExtractTemplateValuesMethod(Control control);
/*
* This class is the ITemplate implementation that is called from the
* generated page class code. It just passes the Initialize call on to a
* delegate.
*/
/// <internalonly/>
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public sealed class CompiledBindableTemplateBuilder : IBindableTemplate {
private BuildTemplateMethod _buildTemplateMethod;
private ExtractTemplateValuesMethod _extractTemplateValuesMethod;
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public CompiledBindableTemplateBuilder(BuildTemplateMethod buildTemplateMethod, ExtractTemplateValuesMethod extractTemplateValuesMethod) {
_buildTemplateMethod = buildTemplateMethod;
_extractTemplateValuesMethod = extractTemplateValuesMethod;
}
// IBindableTemplate::ExtractValues
/// <devdoc>
/// <para>Calls the ExtractTemplateValuesMethod delegate, which will return a dictionary of values.</para>
/// </devdoc>
public IOrderedDictionary ExtractValues(Control container) {
if (_extractTemplateValuesMethod != null) {
return _extractTemplateValuesMethod(container);
}
return new OrderedDictionary();
}
// ITemplate::InstantiateIn
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public void InstantiateIn(Control container) {
_buildTemplateMethod(container);
}
}
}
|