|
//------------------------------------------------------------------------------
// <copyright file="MobileControlPersister.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
namespace System.Web.UI.Design.MobileControls
{
using System;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.MobileControls;
using System.Web.UI.WebControls;
using System.Collections;
using System.Collections.Specialized;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Text;
using AttributeCollection = System.Web.UI.AttributeCollection;
using System.Globalization;
/// <summary>
/// <para>
/// Provides helper functions used in persisting Controls.
/// </para>
/// </summary>
[
System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand,
Flags=System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode)
]
[Obsolete("The System.Web.Mobile.dll assembly has been deprecated and should no longer be used. For information about how to develop ASP.NET mobile applications, see http://go.microsoft.com/fwlink/?LinkId=157231.")]
internal sealed class MobileControlPersister
{
/// <summary>
/// We don't want instances of this class to be created, so mark
/// the constructor as private.
/// </summary>
private MobileControlPersister() {
}
/// <summary>
/// <para>
/// Gets the delarative type for the
/// specified type.
/// </para>
/// </summary>
/// <param name='type'>
/// The type of the declarator.
/// </param>
/// <param name='host'>
/// The services interface exposed by the webforms designer.
/// </param>
private static string GetDeclarativeType(Type type, IDesignerHost host) {
Debug.Assert(host != null, "Need an IDesignerHost to create declarative type names");
string declarativeType = null;
if (host != null) {
IWebFormReferenceManager refMgr =
(IWebFormReferenceManager)host.GetService(typeof(IWebFormReferenceManager));
Debug.Assert(refMgr != null, "Did not get back IWebFormReferenceManager service from host.");
if (refMgr != null) {
string tagPrefix = refMgr.GetTagPrefix(type);
if ((tagPrefix != null) && (tagPrefix.Length != 0)) {
declarativeType = tagPrefix + ":" + type.Name;
}
}
}
if (declarativeType == null)
{
/* Begin AUI 7201 */
/* Original declarativeType = type.FullName; */
if (type == typeof(System.Web.UI.MobileControls.Style))
{
declarativeType = type.Name;
}
else
{
declarativeType = type.FullName;
}
/* End AUI 7201 */
}
return declarativeType;
}
/// <summary>
/// <para>
/// Persists a collection property.
/// </para>
/// </summary>
/// <param name='persistMode'>
/// The persistance mode to use.
/// </param>
/// <param name=' sw'>
/// The string writer to use.
/// </param>
/// <param name=' component'>
/// The component to persist.
/// </param>
/// <param name=' propDesc'>
/// A property descriptor for the collection property.
/// </param>
/// <param name='host'>
/// The services interface exposed by the webforms designer.
/// </param>
private static void PersistCollectionProperty(TextWriter sw, object component, PropertyDescriptor propDesc, PersistenceMode persistMode, IDesignerHost host) {
Debug.Assert(typeof(ICollection).IsAssignableFrom(propDesc.PropertyType),
"Invalid collection property : " + propDesc.Name);
ICollection propValue = (ICollection)propDesc.GetValue(component);
if ((propValue == null) || (propValue.Count == 0))
return;
// Begin AUI Change #3785
// Original: sw.WriteLine();
if (!(component is DeviceSpecific))
{
sw.WriteLine();
}
// End of Change #3785
if (persistMode == PersistenceMode.InnerProperty) {
sw.Write('<');
sw.Write(propDesc.Name);
sw.WriteLine('>');
}
IEnumerator e = propValue.GetEnumerator();
while (e.MoveNext()) {
object collItem = e.Current;
// Begin of AUI Change
//string itemTypeName = GetDeclarativeType(collItem.GetType(), host);
string itemTypeName;
// AUI : To fix Hashtable objects used in Mobile Controls, only persist the value part
if (collItem is DictionaryEntry)
{
collItem = ((DictionaryEntry)collItem).Value;
}
// AUI : First check if the control already has a Default Persist Name,
// if not, use the Type as its name
PersistNameAttribute pna =
(PersistNameAttribute)TypeDescriptor.GetAttributes(collItem.GetType())[typeof(PersistNameAttribute)];
// attribute should returns default value if it's null.
// this is unlikely to happen, but just to be on the safe side.
Debug.Assert (pna != null, "PersistNameAttribute returns null!");
string persistName = (string)pna.Name;
if (persistName != null && persistName.Length > 0)
{
itemTypeName = persistName;
}
/* AUI Change #3911 */
/* Original : else if (collItem is Control) */
else if (collItem is Control || collItem.GetType() == typeof(System.Web.UI.MobileControls.Style))
{
itemTypeName = GetDeclarativeType(collItem.GetType(), host);
}
else
{
itemTypeName = collItem.GetType().Name;
}
// End of AUI Change
sw.Write("<");
sw.Write(itemTypeName);
PersistAttributes(sw, collItem, String.Empty, null);
sw.Write(">");
if (collItem is Control) {
PersistChildrenAttribute pca =
(PersistChildrenAttribute)TypeDescriptor.GetAttributes(collItem.GetType())[typeof(PersistChildrenAttribute)];
if (pca.Persist == true) {
// asurt 106696: ensure the parent control's visibility is set to true.
Control parentControl = (Control)collItem;
if (parentControl.HasControls())
{
bool oldVisible = parentControl.Visible;
try
{
parentControl.Visible = true;
PersistChildControls(sw, parentControl.Controls, host);
}
finally
{
parentControl.Visible = oldVisible;
}
}
}
else {
PersistInnerProperties(sw, collItem, host);
}
}
else {
PersistInnerProperties(sw, collItem, host);
}
sw.Write("</");
sw.Write(itemTypeName);
sw.WriteLine(">");
}
if (persistMode == PersistenceMode.InnerProperty) {
sw.Write("</");
sw.Write(propDesc.Name);
sw.WriteLine('>');
}
}
/// <summary>
/// <para>
/// Persists a complex property.
/// </para>
/// </summary>
/// <param name='persistMode'>
/// The persistance mode to use.
/// </param>
/// <param name=' sw'>
/// The string writer to use.
/// </param>
/// <param name=' component'>
/// The component to persist.
/// </param>
/// <param name=' propDesc'>
/// A property descriptor for the complex property.
/// </param>
/// <param name='host'>
/// The services interface exposed by the webforms designer.
/// </param>
private static void PersistComplexProperty(TextWriter sw, object component, PropertyDescriptor propDesc, IDesignerHost host) {
object propValue = propDesc.GetValue(component);
if (propValue == null) {
return;
}
StringWriter tagProps = new StringWriter(CultureInfo.InvariantCulture);
StringWriter innerProps = new StringWriter(CultureInfo.InvariantCulture);
PersistAttributes(tagProps, propValue, String.Empty, null);
PersistInnerProperties(innerProps, propValue, host);
// the rule here is that if a complex property has all its subproperties
// in the default state, then it itself is in the default state.
// When this is the case, there shouldn't be any tag properties or inner properties
if ((tagProps.GetStringBuilder().Length != 0) ||
(innerProps.GetStringBuilder().Length != 0)) {
sw.WriteLine();
sw.Write('<');
sw.Write(propDesc.Name);
sw.Write(tagProps.ToString());
sw.WriteLine(">");
string innerPropsString = innerProps.ToString();
sw.Write(innerPropsString);
if (innerPropsString.Length != 0) {
// Begin AUI Change #3785
// Original: sw.WriteLine();
if (!propDesc.Name.Equals("DeviceSpecific"))
{
sw.WriteLine();
}
// End AUI Change #3785
}
sw.Write("</");
sw.Write(propDesc.Name);
sw.WriteLine('>');
}
}
/// <summary>
/// <para>
/// Persists the data bindings of the specified control using the specified
/// string writer.
/// </para>
/// </summary>
/// <param name='sw'>
/// The string writer to use.
/// </param>
/// <param name=' control'>
/// The control to use.
/// </param>
private static void PersistDataBindings(TextWriter sw, Control control) {
DataBindingCollection bindings = ((IDataBindingsAccessor)control).DataBindings;
IEnumerator bindingEnum = bindings.GetEnumerator();
while (bindingEnum.MoveNext()) {
DataBinding db = (DataBinding)bindingEnum.Current;
string persistPropName = db.PropertyName.Replace('.', '-');
sw.Write(" ");
sw.Write(persistPropName);
sw.Write("='<%# ");
sw.Write(HttpUtility.HtmlEncode(db.Expression));
sw.Write(" %>'");
}
}
/// <overload>
/// <para>
/// Gets a string that can persist the inner properties of a control.
/// </para>
/// </overload>
/// <summary>
/// <para>
/// Gets a string that can persist the inner properties of a control.
/// </para>
/// </summary>
/// <param name='component'>
/// The component to persist.
/// </param>
/// <param name='host'>
/// The services interface exposed by the webforms designer.
/// </param>
/// <returns>
/// <para>
/// A string that contains the persistable information about
/// the inner properties
/// of the control.
/// </para>
/// </returns>
internal static string PersistInnerProperties(object component, IDesignerHost host) {
StringWriter sw = new StringWriter(CultureInfo.InvariantCulture);
PersistInnerProperties(sw, component, host);
return sw.ToString();
}
/// <summary>
/// <para>
/// Persists the inner properties of the control.
/// </para>
/// </summary>
/// <param name='sw'>
/// The string writer to use.
/// </param>
/// <param name=' component'>
/// The component to persist.
/// </param>
/// <param name='host'>
/// The services interface exposed by the webforms designer.
/// </param>
internal static void PersistInnerProperties(TextWriter sw, object component, IDesignerHost host) {
PropertyDescriptorCollection propDescs = TypeDescriptor.GetProperties(component);
for (int i = 0; i < propDescs.Count; i++) {
// Only deal with inner attributes that need to be persisted
if (propDescs[i].SerializationVisibility == DesignerSerializationVisibility.Hidden)
continue;
PersistenceModeAttribute persistenceMode = (PersistenceModeAttribute)propDescs[i].Attributes[typeof(PersistenceModeAttribute)];
if (persistenceMode.Mode == PersistenceMode.Attribute) {
continue;
}
if (propDescs[i].PropertyType == typeof(string)) {
// String based property...
DataBindingCollection dataBindings = null;
if (component is IDataBindingsAccessor) {
dataBindings = ((IDataBindingsAccessor)component).DataBindings;
}
if (dataBindings == null || dataBindings[propDescs[i].Name] == null) {
PersistenceMode mode = persistenceMode.Mode;
if ((mode == PersistenceMode.InnerDefaultProperty) ||
(mode == PersistenceMode.EncodedInnerDefaultProperty)) {
PersistStringProperty(sw, component, propDescs[i], mode);
}
else {
Debug.Fail("Cannot persist inner string property marked with PersistenceMode.InnerProperty");
}
}
}
else if (typeof(ITemplate).IsAssignableFrom(propDescs[i].PropertyType)) {
// Template based property...
if (persistenceMode.Mode == PersistenceMode.InnerProperty) {
PersistTemplateProperty(sw, component, propDescs[i]);
}
else {
Debug.Fail("Cannot persist template property " + propDescs[i].Name + " not marked with PersistenceMode.InnerProperty");
}
}
/* AUI change 03/21/01 */
else if (propDescs[i].DisplayName.Equals("Templates") &&
component is DeviceSpecificChoice &&
typeof(IDictionary).IsAssignableFrom(propDescs[i].PropertyType)) {
IDictionary templateCollection = (IDictionary)propDescs[i].GetValue(component);
foreach (String templateName in templateCollection.Keys) {
ITemplate template = (ITemplate)templateCollection[templateName];
PersistTemplateProperty(sw, templateName, template);
}
}
/* End of AUI change*/
else if (typeof(ICollection).IsAssignableFrom(propDescs[i].PropertyType)) {
// Collection based property...
if ((persistenceMode.Mode == PersistenceMode.InnerProperty) ||
(persistenceMode.Mode == PersistenceMode.InnerDefaultProperty)) {
PersistCollectionProperty(sw, component, propDescs[i], persistenceMode.Mode, host);
}
else {
Debug.Fail("Cannot persist collection property " + propDescs[i].Name + " not marked with PersistenceMode.InnerProperty or PersistenceMode.InnerDefaultProperty");
}
}
else {
// Other complex property...
if (persistenceMode.Mode == PersistenceMode.InnerProperty) {
PersistComplexProperty(sw, component, propDescs[i], host);
}
else {
Debug.Fail("Cannot persist complex property " + propDescs[i].Name + " not marked with PersistenceMode.InnerProperty");
}
}
}
}
/// <summary>
/// <para>
/// Persists the properties of a
/// string.
/// </para>
/// </summary>
/// <param name='persistMode'>
/// The persistance mode to use.
/// </param>
/// <param name=' sw'>
/// The string writer to use.
/// </param>
/// <param name=' component'>
/// The component to persist.
/// </param>
/// <param name=' propDesc'>
/// A property descriptor for the string properties.
/// </param>
private static void PersistStringProperty(TextWriter sw, object component, PropertyDescriptor propDesc, PersistenceMode mode) {
Debug.Assert(propDesc.PropertyType == typeof(string),
"Invalid string property : " + propDesc.Name);
Debug.Assert((mode == PersistenceMode.InnerDefaultProperty) || (mode == PersistenceMode.EncodedInnerDefaultProperty),
"Inner string properties must be marked as either InnerDefaultProperty or EncodedInnerDefaultProperty");
object propValue = propDesc.GetValue(component);
if (propValue == null) {
return;
}
if (mode == PersistenceMode.InnerDefaultProperty) {
sw.Write((string)propValue);
}
else {
HttpUtility.HtmlEncode((string)propValue, sw);
}
}
/// <summary>
/// <para>
/// Persists the properties of a tag.
/// </para>
/// </summary>
/// <param name='sw'>
/// The string writer to use.
/// </param>
/// <param name=' component'>
/// The component to persist.
/// </param>
/// <param name=' prefix'>
/// The prefix to store.
/// </param>
/// <param name=' propDesc'>
/// A property descriptor for the tag properties.
/// </param>
private static void PersistAttributes(TextWriter sw, object component, string prefix, PropertyDescriptor propDesc) {
PropertyDescriptorCollection properties;
string persistPrefix = String.Empty;
object value = component;
if (propDesc != null) {
value = propDesc.GetValue(component);
properties = TypeDescriptor.GetProperties(propDesc.PropertyType,
new Attribute[] {
PersistenceModeAttribute.Attribute
});
}
else {
properties = TypeDescriptor.GetProperties(component,
new Attribute[] {
PersistenceModeAttribute.Attribute
});
}
if (value == null)
return;
if (prefix.Length != 0)
persistPrefix = prefix + "-";
DataBindingCollection dataBindings = null;
bool isControl = (component is Control);
if ((component is IDataBindingsAccessor))
dataBindings = ((IDataBindingsAccessor)component).DataBindings;
if (component is DeviceSpecificChoice)
{
properties = properties.Sort(new String[] {"Filter"});
}
for (int i = 0; i < properties.Count; i++) {
// Skip properties that are hidden to the serializer
if (properties[i].SerializationVisibility == DesignerSerializationVisibility.Hidden) {
continue;
}
// Skip design-time only properties such as DefaultModifiers and Name
DesignOnlyAttribute doAttr = (DesignOnlyAttribute)properties[i].Attributes[typeof(DesignOnlyAttribute)];
if ((doAttr != null) && doAttr.IsDesignOnly) {
continue;
}
string propName = properties[i].Name;
Type propType = properties[i].PropertyType;
object obj = properties[i].GetValue(value);
if (obj == null)
continue;
DefaultValueAttribute defValAttr =
(DefaultValueAttribute)properties[i].Attributes[typeof(DefaultValueAttribute)];
if ((defValAttr != null) && (obj.Equals(defValAttr.Value)))
continue;
string persistName = propName;
/* AUI Change 3876 -- Change is taken out because of 4347
if (component is DeviceSpecificChoice && persistName.Equals("Xmlns"))
{
persistName = "xmlns";
}
End of Change */
if (prefix.Length != 0)
persistName = persistPrefix + persistName;
PropertyDescriptorCollection subProps = null;
if (properties[i].SerializationVisibility == DesignerSerializationVisibility.Content) {
subProps = TypeDescriptor.GetProperties(propType);
}
if ((subProps == null) || (subProps.Count == 0)) {
string persistValue = null;
//
DataBinding db = null;
if (dataBindings != null)
db = dataBindings[persistName.Replace('.', '-')];
if (db == null) {
if (propType.IsEnum) {
persistValue = Enum.Format(propType, obj, "G");
}
else if (propType == typeof(string)) {
persistValue = HttpUtility.HtmlEncode(obj.ToString());
}
else {
TypeConverter converter = properties[i].Converter;
if (converter != null) {
persistValue = converter.ConvertToInvariantString(null, obj);
}
else {
persistValue = obj.ToString();
}
persistValue = HttpUtility.HtmlEncode(persistValue);
}
if ((persistValue == null) ||
(persistValue.Equals("NotSet")) ||
(propType.IsArray && (persistValue.Length == 0)))
continue;
sw.Write(" ");
sw.Write(persistName);
sw.Write("=\"");
sw.Write(persistValue);
sw.Write("\"");
}
}
else {
/*
* This will force all ListDictionary properties with DesignerSerializationVisibility.Content atttribute be
* persisted as a series of attributes eg. <PropertyFoo Key1="Value1" Key2="Value2" ... />. The
* WebControlPersistor is not able to handle this case and will return undesired results.
*/
// AUI Change to handle DeviceSpecificChoice.Contents
if (obj is ListDictionary)
{
IDictionaryEnumerator enumerator = ((ListDictionary)obj).GetEnumerator ();
String persistValue = null;
while (enumerator.MoveNext ())
{
propName = enumerator.Key as String;
persistValue = enumerator.Value as String;
Debug.Assert (propName != null,
"Non-string key in DeviceSpecificChoice Contents.");
if ((propName.Length == 0) ||
(persistValue == null))
continue;
sw.Write(" ");
sw.Write(propName);
sw.Write("=\"");
HttpUtility.HtmlEncode((String)persistValue, sw);
sw.Write("\"");
}
}
else
{
// End of AUI Change
// there are sub properties, don't persist this object, but
// recursively persist the subproperties.
PersistAttributes(sw, obj, persistName, null);
}
}
}
// Persist all the databindings on this control
if (isControl) {
PersistDataBindings(sw, (Control)component);
AttributeCollection expandos = null;
if (component is WebControl) {
expandos = ((WebControl)component).Attributes;
}
else if (component is HtmlControl) {
expandos = ((HtmlControl)component).Attributes;
}
else if (component is UserControl)
{
expandos = ((UserControl)component).Attributes;
}
if (expandos != null) {
foreach (string key in expandos.Keys) {
sw.Write(" ");
sw.Write(key);
sw.Write("=\"");
sw.Write(expandos[key]);
sw.Write("\"");
}
}
}
}
/// <summary>
/// <para>
/// Persists a template property including the specified persistance mode,
/// string writer and property descriptor.
/// </para>
/// </summary>
/// <param name='persistMode'>
/// The persistence mode to use.
/// </param>
/// <param name=' sw'>
/// The string writer to use.
/// </param>
/// <param name=' component'>
/// The component to persist.
/// </param>
/// <param name=' propDesc'>
/// A property descriptor for the property.
/// </param>
/* AUI change 03/21/01 added support for persisting Template collection */
private static void PersistTemplateProperty(TextWriter sw, object component, PropertyDescriptor propDesc)
{
Debug.Assert(typeof(ITemplate).IsAssignableFrom(propDesc.PropertyType),
"Invalid template property : " + propDesc.Name);
ITemplate template = (ITemplate)propDesc.GetValue(component);
String templateName = propDesc.Name;
PersistTemplateProperty(sw, templateName, template);
}
/* AUI change 03/21/01 made the following code a seperate method */
private static void PersistTemplateProperty(TextWriter sw, String templateName, ITemplate template)
{
if (template == null) {
return;
}
//string templateContent = ((TemplateBuilder)template).Text;
string templateContent;
Debug.Assert(template is TemplateBuilder, "Unexpected ITemplate implementation.");
if (template is TemplateBuilder) {
templateContent = ((TemplateBuilder)template).Text;
}
else {
templateContent = String.Empty;
}
sw.WriteLine();
sw.Write('<');
// changed propDesc.Name to templateName
sw.Write(templateName);
sw.Write('>');
if (!templateContent.StartsWith("\r\n", StringComparison.Ordinal)) {
sw.WriteLine();
}
sw.Write(templateContent);
if (!templateContent.EndsWith("\r\n", StringComparison.Ordinal)) {
sw.WriteLine();
}
sw.Write("</");
// changed propDesc.Name to templateName
sw.Write(templateName);
sw.WriteLine('>');
}
/// <overload>
/// <para>
/// Gets a string that can
/// persist a control.
/// </para>
/// </overload>
/// <summary>
/// <para>
/// Gets a string that can
/// persist a control.
/// </para>
/// </summary>
/// <param name='control'>
/// The control to persist.
/// </param>
/// <returns>
/// <para>
/// A string that contains the persistable information about
/// the control.
/// </para>
/// </returns>
internal static string PersistControl(Control control) {
StringWriter sw = new StringWriter(CultureInfo.InvariantCulture);
PersistControl(sw, control);
return sw.ToString();
}
/// <overload>
/// <para>
/// Returns a string that can
/// persist a control.
/// </para>
/// </overload>
/// <summary>
/// <para>
/// Returns a string that can
/// persist a control.
/// </para>
/// </summary>
/// <param name='control'>
/// The control to persist.
/// </param>
/// <param name='host'>
/// The services interface exposed by the webforms designer.
/// </param>
/// <returns>
/// <para>
/// A string that contains the persistable information about
/// the control.
/// </para>
/// </returns>
internal static string PersistControl(Control control, IDesignerHost host) {
StringWriter sw = new StringWriter(CultureInfo.InvariantCulture);
PersistControl(sw, control, host);
return sw.ToString();
}
/// <summary>
/// <para>
/// Persists a control using the
/// specified string writer.
/// </para>
/// </summary>
/// <param name='sw'>
/// The string writer to use.
/// </param>
/// <param name=' control'>
/// The control to persist.
/// </param>
internal static void PersistControl(TextWriter sw, Control control) {
if (control is LiteralControl) {
PersistLiteralControl(sw, (LiteralControl)control);
return;
}
if (control is DesignerDataBoundLiteralControl) {
PersistDataBoundLiteralControl(sw, (DesignerDataBoundLiteralControl)control);
return;
}
ISite site = control.Site;
if (site == null) {
IComponent baseComponent = (IComponent)control.Page;
Debug.Assert(baseComponent != null, "Control does not have its Page set!");
if (baseComponent != null) {
site = baseComponent.Site;
}
}
IDesignerHost host = null;
if (site != null) {
host = (IDesignerHost)site.GetService(typeof(IDesignerHost));
}
Debug.Assert(host != null, "Did not get a valid IDesignerHost reference. Expect persistence problems!");
PersistControl(sw, control, host);
}
/// <summary>
/// <para>
/// Persists a control using the
/// specified string writer.
/// </para>
/// </summary>
/// <param name='sw'>
/// The string writer to use.
/// </param>
/// <param name=' control'>
/// The control to persist.
/// </param>
/// <param name='host'>
/// The services interface exposed by the webforms designer.
/// </param>
internal static void PersistControl(TextWriter sw, Control control, IDesignerHost host) {
// Literals and DataBoundLiterals must be handled specially, since they
// don't have a tag around them
if (control is LiteralControl) {
PersistLiteralControl(sw, (LiteralControl)control);
return;
}
if (control is DesignerDataBoundLiteralControl) {
PersistDataBoundLiteralControl(sw, (DesignerDataBoundLiteralControl)control);
return;
}
Debug.Assert(host != null, "Did not get a valid IDesignerHost reference. Expect persistence problems!");
string tagName = null;
bool isUserControl = false;
if (control is HtmlControl) {
tagName = ((HtmlControl)control).TagName;
}
else if (control is UserControl)
{
tagName = ((IUserControlDesignerAccessor)control).TagName;
Debug.Assert((tagName != null) && (tagName.Length != 0));
if (tagName.Length == 0)
{
// not enough information to go any further... no options, other than to throw this control out
return;
}
isUserControl = true;
}
else {
tagName = GetDeclarativeType(control.GetType(), host);
}
sw.Write('<');
sw.Write(tagName);
sw.Write(" runat=\"server\"");
PersistAttributes(sw, control, String.Empty, null);
sw.Write('>');
if (isUserControl == false)
{
PersistChildrenAttribute pca =
(PersistChildrenAttribute)TypeDescriptor.GetAttributes(control.GetType())[typeof(PersistChildrenAttribute)];
if (pca.Persist == true)
{
if (control.HasControls())
{
// asurt 106696: Ensure parent control's visibility is true.
bool oldVisible = control.Visible;
try
{
control.Visible = true;
PersistChildControls(sw, control.Controls, host);
}
finally
{
control.Visible = oldVisible;
}
}
}
else
{
// controls marked with LiteralContent == true shouldn't have
// children in their persisted form. They only build children
// collections at runtime.
PersistInnerProperties(sw, control, host);
}
}
else
{
string innerText = ((IUserControlDesignerAccessor)control).InnerText;
if ((innerText != null) && (innerText.Length != 0))
{
sw.Write(innerText);
}
}
sw.Write("</");
sw.Write(tagName);
sw.WriteLine('>');
}
/// <summary>
/// <para>
/// Persists the child controls of
/// the control using the specified string writer.
/// </para>
/// </summary>
/// <param name='sw'>
/// The string writer to use.
/// </param>
/// <param name=' controls'>
/// The control collection to persist.
/// </param>
/// <param name='host'>
/// The services interface exposed by the webforms designer.
/// </param>
private static void PersistChildControls(TextWriter sw, ControlCollection controls, IDesignerHost host) {
int children = controls.Count;
for (int i = 0; i < children; i++) {
PersistControl(sw, controls[i], host);
}
}
private static void PersistDataBoundLiteralControl(TextWriter sw, DesignerDataBoundLiteralControl control) {
Debug.Assert(((IDataBindingsAccessor)control).HasDataBindings == true);
DataBindingCollection bindings = ((IDataBindingsAccessor)control).DataBindings;
DataBinding textBinding = bindings["Text"];
Debug.Assert(textBinding != null, "Did not get a Text databinding from DesignerDataBoundLiteralControl");
if (textBinding != null) {
sw.Write("<%# ");
sw.Write(textBinding.Expression);
sw.Write(" %>");
}
}
private static void PersistLiteralControl(TextWriter sw, LiteralControl control) {
Debug.Assert(control.Text != null);
sw.Write(control.Text);
}
}
}
|