ControlDesigner.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ DotNET / DotNET / 8.0 / untmp / whidbey / REDBITS / ndp / fx / src / Designer / WebForms / System / Web / UI / Design / ControlDesigner.cs / 2 / ControlDesigner.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

namespace System.Web.UI.Design { 
 
    using Microsoft.Win32;
    using System; 
    using System.Collections;
    using System.Collections.Specialized;
    using System.ComponentModel;
    using System.ComponentModel.Design; 
    using System.Configuration;
    using System.Data; 
    using System.Design; 
    using System.Diagnostics;
    using System.Globalization; 
    using System.IO;
    using System.Drawing;
    using System.Reflection;
    using System.Runtime.InteropServices; 
    using System.Text;
    using System.Web.Configuration; 
    using System.Web.Compilation; 
    using System.Web.UI;
    using System.Web.UI.Design; 
    using System.Web.UI.Design.Util;
    using System.Web.UI.Design.WebControls;
    using System.Web.UI.WebControls;
    using System.Windows.Forms; 
    using System.Xml;
 
    using WebUIControl = System.Web.UI.Control; 

    ///  
    /// 
    ///    
    ///       Provides the base class for all namespaced or custom server control designers.
    ///     
    /// 
    [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, Flags=System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode)] 
    public class ControlDesigner : HtmlControlDesigner { 

        internal static readonly string ErrorDesignTimeHtmlTemplate = 
            @"
{0} - {1}
{2}
"; private static readonly string PlaceHolderDesignTimeHtmlTemplate = @"
{0} - {1}
{2}
"; private bool isWebControl; // true if the associated component is a WebControl private bool readOnly = true; // read-only/read-write state of the control design surface. private bool fDirty = false; // indicates the dirty state of the control (used during inner content saving). private int _ignoreComponentChangesCount; private bool _inTemplateMode; private WebUIControl _viewControl; private bool _viewControlCreated = false; private IControlDesignerTag _tag; private IControlDesignerView _view; private ControlDesignerState _designerState; private bool _expressionsChanged; // Contains localized inner contents of the control after Localize() is called. private string _localizedInnerContent; /// public override DesignerActionListCollection ActionLists { get { DesignerActionListCollection actionLists = new DesignerActionListCollection(); actionLists.AddRange(base.ActionLists); actionLists.Add(new ControlDesignerActionList(this)); return actionLists; } } /// /// /// /// Gets or sets a value indicating /// whether or not the control can be resized. /// /// public virtual bool AllowResize { get { return IsWebControl; } } /// public virtual DesignerAutoFormatCollection AutoFormats { get { return new DesignerAutoFormatCollection(); } } /// protected virtual bool DataBindingsEnabled { get { IControlDesignerView view = View; while (view != null) { EditableDesignerRegion region = (EditableDesignerRegion)view.ContainingRegion; if (region != null) { if (region.SupportsDataBinding) { return true; } else { ControlDesigner containingControlDesigner = region.Designer; if (containingControlDesigner != null) { view = containingControlDesigner.View; } else { return false; } } } else { return false; } } return false; } } /// protected ControlDesignerState DesignerState { get { if (_designerState == null) { _designerState = new ControlDesignerState(Component); } return _designerState; } } /// [Obsolete("The recommended alternative is SetViewFlags(ViewFlags.DesignTimeHtmlRequiresLoadComplete, true). http://go.microsoft.com/fwlink/?linkid=14202")] public virtual bool DesignTimeHtmlRequiresLoadComplete { get { return false; } } /// /// /// Whether or not the properties of the control will be hidden when the control /// is placed into template editing mode. The 'ID' property is never hidden. /// The default implementation returns 'true.' /// /// protected internal virtual bool HidePropertiesInTemplateMode { get { return true; } } /// /// /// /// public virtual string ID { get { return ((WebUIControl)Component).ID; } set { if (RootDesigner != null) { RootDesigner.SetControlID((WebUIControl) Component, value); } } } /// protected bool InTemplateMode { get { return _inTemplateMode; } } /// /// /// /// Gets or sets a value indicating /// whether or not the boolean dirty state of the web control is currently set. /// /// [Obsolete("The recommended alternative is to use Tag.SetDirty() and Tag.IsDirty. http://go.microsoft.com/fwlink/?linkid=14202")] public bool IsDirty { get { return IsDirtyInternal; } set { IsDirtyInternal = value; } } internal bool IsDirtyInternal { get { if (Tag != null) { return Tag.IsDirty; } return fDirty; } set { if (Tag != null) { Tag.SetDirty(value); } else { fDirty = value; } } } internal bool IsIgnoringComponentChanges { get { return _ignoreComponentChangesCount > 0; } } internal bool IsWebControl { get { return isWebControl; } } // This is internal so that ContainerControlDesigner can have access to it // because of its overridden implementation of GetPersistenceContent(). internal string LocalizedInnerContent { get { return _localizedInnerContent; } } public virtual bool ViewControlCreated { get { return _viewControlCreated; } set { _viewControlCreated = value; } } /// /// /// /// Gets or sets a value indicating /// whether or not the control's associated design surface is set to read-only or not. /// /// [Obsolete("The recommended alternative is to inherit from ContainerControlDesigner instead and to use an EditableDesignerRegion. Regions allow for better control of the content in the designer. http://go.microsoft.com/fwlink/?linkid=14202")] public bool ReadOnly { get { return ReadOnlyInternal; } set { ReadOnlyInternal = value; } } internal bool ReadOnlyInternal { get { return readOnly; } set { readOnly = value; } } /// protected WebFormsRootDesigner RootDesigner { get { WebFormsRootDesigner rootDesigner = null; ISite site = Component.Site; if (site != null) { IDesignerHost designerHost = (IDesignerHost)site.GetService(typeof(IDesignerHost)); if ((designerHost != null) && (designerHost.RootComponent != null)) { rootDesigner = designerHost.GetDesigner(designerHost.RootComponent) as WebFormsRootDesigner; } } return rootDesigner; } } private bool SupportsDataBindings { get { BindableAttribute ba = (BindableAttribute)TypeDescriptor.GetAttributes(Component)[typeof(BindableAttribute)]; return ((ba != null) && ba.Bindable); } } /// /// /// protected IControlDesignerTag Tag { get { return _tag; } } /// public virtual TemplateGroupCollection TemplateGroups { get { return new TemplateGroupCollection(); } } // protected virtual bool UsePreviewControl { get { object[] attrs = this.GetType().GetCustomAttributes(typeof(SupportsPreviewControlAttribute), false); if (attrs.Length > 0) { SupportsPreviewControlAttribute spca = (SupportsPreviewControlAttribute)attrs[0]; return spca.SupportsPreviewControl; } return false; } } /// /// /// internal IControlDesignerView View { get { return _view; } } public WebUIControl ViewControl { get { if (!ViewControlCreated) { _viewControl = UsePreviewControl ? CreateViewControlInternal() : (WebUIControl)Component; ViewControlCreated = true; } return _viewControl; } set { _viewControl = value; ViewControlCreated = true; } } /// /// /// protected virtual bool Visible { get { return true; } } /// /// /// /// The object on the design surface used to display the visual representation of the control associated with this designer. /// [Obsolete("Error: This property can no longer be referenced, and is included to support existing compiled applications. The design-time element view architecture is no longer used. http://go.microsoft.com/fwlink/?linkid=14202", true)] protected object DesignTimeElementView { get { IHtmlControlDesignerBehavior behavior = BehaviorInternal; if (behavior != null) { Debug.Assert(behavior is IControlDesignerBehavior, "Wrong type of behavior"); return ((IControlDesignerBehavior)behavior).DesignTimeElementView; } return null; } } internal static DesignerAutoFormatCollection CreateAutoFormats(string schemes, CreateAutoFormatDelegate createAutoFormatDelegate) { DesignerAutoFormatCollection autoFormats = new DesignerAutoFormatCollection(); try { DataSet ds = new DataSet(); ds.Locale = CultureInfo.InvariantCulture; ds.ReadXml(new XmlTextReader(new StringReader(schemes))); Debug.Assert((ds.Tables.Count == 1) && (ds.Tables[0].TableName.Equals("Scheme")), "Unexpected tables in schemes dataset"); DataTable schemesTable = ds.Tables[0]; schemesTable.PrimaryKey = new DataColumn[] {schemesTable.Columns["SchemeName"]}; for (int i = 0; i < schemesTable.Rows.Count; i++) { autoFormats.Add(createAutoFormatDelegate(schemesTable.Rows[i])); } } catch (Exception e) { Debug.Fail(e.ToString()); } return autoFormats; } /// /// Creates a clone of a control based on its persistence. It either gets the outer /// content persistence straight from the tool (best bet), or it tries to simply /// serialize the control itself (not always reliable). /// internal WebUIControl CreateClonedControl(IDesignerHost parseTimeDesignerHost, bool applyTheme) { string persisted = null; if (Tag != null) { // As a perf optimization we ask the tag for the outer content persisted = Tag.GetOuterContent(); } // If we didn't get back outer content, we fall back to the ControlSerializer if (String.IsNullOrEmpty(persisted)) { persisted = ControlPersister.PersistControl((WebUIControl)Component); } WebUIControl clonedControl = ControlParser.ParseControl(parseTimeDesignerHost, persisted, applyTheme); return clonedControl; } /// protected string CreatePlaceHolderDesignTimeHtml() { return CreatePlaceHolderDesignTimeHtml(null); } /// protected string CreatePlaceHolderDesignTimeHtml(string instruction) { string typeName = Component.GetType().Name; string name = Component.Site.Name; if (instruction == null) { instruction = String.Empty; } return String.Format(CultureInfo.InvariantCulture, PlaceHolderDesignTimeHtmlTemplate, typeName, name, instruction); } /// /// /// protected string CreateErrorDesignTimeHtml(string errorMessage) { return CreateErrorDesignTimeHtml(errorMessage, null); } /// /// /// protected string CreateErrorDesignTimeHtml(string errorMessage, Exception e) { return CreateErrorDesignTimeHtml(errorMessage, e, Component); } internal static string CreateErrorDesignTimeHtml(string errorMessage, Exception e, IComponent component) { Debug.Assert(component != null); string name = component.Site.Name; if (errorMessage == null) { errorMessage = String.Empty; } else { errorMessage = HttpUtility.HtmlEncode(errorMessage); } if (e != null) { errorMessage += "
" + HttpUtility.HtmlEncode(e.Message); } return String.Format(CultureInfo.InvariantCulture, ErrorDesignTimeHtmlTemplate, SR.GetString(SR.ControlDesigner_DesignTimeHtmlError), HttpUtility.HtmlEncode(name), errorMessage); } internal string CreateInvalidParentDesignTimeHtml(Type controlType, Type requiredParentType) { return CreateErrorDesignTimeHtml(SR.GetString(SR.Control_CanOnlyBePlacedInside, controlType.Name, requiredParentType.Name)); } private WebUIControl CreateViewControlInternal() { Debug.Assert(Component is WebUIControl); WebUIControl originalControl = (WebUIControl)Component; WebUIControl viewControl = CreateViewControl(); ((IControlDesignerAccessor)viewControl).SetOwnerControl(originalControl); UpdateExpressionValues(viewControl); return viewControl; } protected virtual WebUIControl CreateViewControl() { return CreateClonedControl((IDesignerHost)GetService(typeof(IDesignerHost)), true); } /// /// Ensures that an expression is fully parsed. In some cases expression data is left /// in its original form, but the contract with ExpressionEditors is that they only get /// parsed data. /// private object EnsureParsedExpression(TemplateControl templateControl, ExpressionBinding eb, object parsedData) { if (parsedData == null) { // No parsed data, try to re-parse if (templateControl != null) { string trueExpressionPrefix; Type expressionBuilderType = ExpressionEditor.GetExpressionBuilderType(eb.ExpressionPrefix, Component.Site, out trueExpressionPrefix); if (expressionBuilderType != null) { try { System.Web.Compilation.ExpressionBuilder expressionBuilder = (System.Web.Compilation.ExpressionBuilder)Activator.CreateInstance(expressionBuilderType); ExpressionBuilderContext ec = new ExpressionBuilderContext(templateControl); parsedData = expressionBuilder.ParseExpression(eb.Expression, eb.PropertyType, ec); } catch (Exception ex) { // We basically ignore exceptions coming from the ExpressionBuilder // since the page developer is not likely going to be able to do // anything about it. Debug.Fail(String.Format(CultureInfo.InvariantCulture, "Exception when instantiating ExpressionBuilder or parsing expression\r\n\r\n{0}", ex.ToString())); IComponentDesignerDebugService debugService = (IComponentDesignerDebugService)GetService(typeof(IComponentDesignerDebugService)); if (debugService != null) { debugService.Fail(SR.GetString(SR.ControlDesigner_CouldNotGetExpressionBuilder, eb.ExpressionPrefix, ex.Message)); } } } } } return parsedData; } /// public Rectangle GetBounds() { if (View != null) { return View.GetBounds(null); } return Rectangle.Empty; } /// /// Parses a complex property expression and retrieves the correct PropertyDescriptor /// and also returns the object that the PropertyDescriptor appears on. /// internal static PropertyDescriptor GetComplexProperty(object target, string propName, out object realTarget) { realTarget = null; string[] propNameParts = propName.Split('.'); PropertyDescriptor currentPropDesc = null; foreach (string part in propNameParts) { if (String.IsNullOrEmpty(part)) { return null; } currentPropDesc = TypeDescriptor.GetProperties(target)[part]; if (currentPropDesc == null) { return null; } realTarget = target; target = currentPropDesc.GetValue(target); } return currentPropDesc; } /// /// /// /// Gets the HTML to be used for the design time representation of the control runtime. /// /// public virtual string GetDesignTimeHtml() { StringWriter strWriter = new StringWriter(CultureInfo.InvariantCulture); DesignTimeHtmlTextWriter htmlWriter = new DesignTimeHtmlTextWriter(strWriter); string designTimeHTML = null; bool restoreVisible = false; bool oldVisible = true; WebUIControl control = null; try { control = ViewControl; oldVisible = control.Visible; if (oldVisible == false) { control.Visible = true; restoreVisible = !UsePreviewControl; } control.RenderControl(htmlWriter); designTimeHTML = strWriter.ToString(); } catch (Exception ex) { designTimeHTML = GetErrorDesignTimeHtml(ex); } finally { if (restoreVisible) { control.Visible = oldVisible; } } if ((designTimeHTML == null) || (designTimeHTML.Length == 0)) { designTimeHTML = GetEmptyDesignTimeHtml(); } return designTimeHTML; } public virtual string GetDesignTimeHtml(DesignerRegionCollection regions) { return GetDesignTimeHtml(); } /// /// Gets a factory for creating design-time resource providers and writers. /// This looks in config for the runtime factory type, and from that gets /// the design time factory type. If none is found, a service is used to get /// the tool's design time resource provider. /// public static DesignTimeResourceProviderFactory GetDesignTimeResourceProviderFactory(IServiceProvider serviceProvider) { const string GlobalizationSectionName = "system.web/globalization"; DesignTimeResourceProviderFactory resourceProviderFactory = null; IWebApplication webApp = (IWebApplication)serviceProvider.GetService(typeof(IWebApplication)); Configuration config = null; if (webApp != null) { config = webApp.OpenWebConfiguration(true); if (config != null) { GlobalizationSection globConfig = config.GetSection(GlobalizationSectionName) as GlobalizationSection; if (globConfig != null) { string providerTypeName = globConfig.ResourceProviderFactoryType; if (!String.IsNullOrEmpty(providerTypeName)) { ITypeResolutionService typeResolver = (ITypeResolutionService)serviceProvider.GetService(typeof(ITypeResolutionService)); if (typeResolver != null) { Type providerType = typeResolver.GetType(providerTypeName, true, true); if (providerType != null) { object[] attrs = providerType.GetCustomAttributes(typeof(DesignTimeResourceProviderFactoryAttribute), true); if (attrs != null && attrs.Length > 0) { DesignTimeResourceProviderFactoryAttribute factoryAttr = attrs[0] as DesignTimeResourceProviderFactoryAttribute; string designTimeProviderTypeName = factoryAttr.FactoryTypeName; if (!String.IsNullOrEmpty(designTimeProviderTypeName)) { Type designTimeProviderType = typeResolver.GetType(designTimeProviderTypeName, true, true); if (designTimeProviderType != null && typeof(DesignTimeResourceProviderFactory).IsAssignableFrom(designTimeProviderType)) { try { resourceProviderFactory = (DesignTimeResourceProviderFactory)Activator.CreateInstance(designTimeProviderType); } catch (Exception ex) { // We basically ignore exceptions coming from the DesignTimeResourceProviderFactory // since the page developer is not likely going to be able to do anything about it. Debug.Fail(String.Format(CultureInfo.InvariantCulture, "Exception when instantiating DesignTimeResourceProviderFactory\r\n\r\n{0}", ex.ToString())); if (serviceProvider != null) { IComponentDesignerDebugService debugService = (IComponentDesignerDebugService)serviceProvider.GetService(typeof(IComponentDesignerDebugService)); if (debugService != null) { debugService.Fail(SR.GetString(SR.ControlDesigner_CouldNotGetDesignTimeResourceProviderFactory, designTimeProviderTypeName, ex.Message)); } } } } } } } } } } } } if (resourceProviderFactory == null) { IDesignTimeResourceProviderFactoryService resService = (IDesignTimeResourceProviderFactoryService)serviceProvider.GetService(typeof(IDesignTimeResourceProviderFactoryService)); if (resService != null) { resourceProviderFactory = resService.GetFactory(); } } return resourceProviderFactory; } public virtual string GetEditableDesignerRegionContent(EditableDesignerRegion region) { return String.Empty; } /// /// /// /// Gets the HTML to be used at design time as the representation of the /// control when the control runtime does not return any rendered /// HTML. The default behavior is to return a string containing the name of the /// component. /// /// protected virtual string GetEmptyDesignTimeHtml() { string typeName = Component.GetType().Name; string name = Component.Site.Name; if ((name != null) && (name.Length > 0)) { return "[ " + typeName + " \"" + name + "\" ]"; } else { return "[ " + typeName + " ]"; } } /// /// /// protected virtual string GetErrorDesignTimeHtml(Exception e) { return CreateErrorDesignTimeHtml(SR.GetString(SR.ControlDesigner_UnhandledException), e); } /// /// /// /// Gets the persistable inner HTML. /// /// [Obsolete("The recommended alternative is GetPersistenceContent(). http://go.microsoft.com/fwlink/?linkid=14202")] public virtual string GetPersistInnerHtml() { return GetPersistInnerHtmlInternal(); } internal virtual string GetPersistInnerHtmlInternal() { if (_localizedInnerContent != null) { return _localizedInnerContent; } if (!IsDirtyInternal) { // NOTE: Returning a null string will prevent the actual save. return null; } IDesignerHost host = (IDesignerHost)GetService(typeof(IDesignerHost)); Debug.Assert(host != null, "Did not get a valid IDesignerHost reference"); IsDirtyInternal = false; return ControlSerializer.SerializeInnerContents((WebUIControl)Component, host); } /// /// /// public virtual string GetPersistenceContent() { #pragma warning disable 618 return GetPersistInnerHtml(); #pragma warning restore 618 } internal void HideAllPropertiesExceptID(IDictionary properties) { ICollection coll = properties.Values; if (coll != null) { object[] values = new object[coll.Count]; coll.CopyTo(values, 0); for (int i = 0; i < values.Length; i++) { PropertyDescriptor prop = (PropertyDescriptor)values[i]; if (prop != null) { if (!String.Equals(prop.Name, "ID", StringComparison.OrdinalIgnoreCase)) { properties[prop.Name] = TypeDescriptor.CreateProperty(prop.ComponentType, prop, BrowsableAttribute.No); } } } } } public void Localize(IDesignTimeResourceWriter resourceWriter) { OnComponentChanging(Component, new ComponentChangingEventArgs(Component, null)); string newInnerContent; string resourceKey = ControlLocalizer.LocalizeControl((WebUIControl)Component, resourceWriter, out newInnerContent); if (!String.IsNullOrEmpty(resourceKey)) { // Add the resource key attribute to the top-level object, if present SetTagAttribute("meta:resourcekey", resourceKey, true); } if (!String.IsNullOrEmpty(newInnerContent)) { // Regardless of whether we had a resource key for the top-level object, we // might still have new inner content. For example, a MultiView doesn't have // any localizable properties, so it doesn't get a meta:resourcekey tag. // However, controls inside it may have been localized, so we need to get // new inner content for them. _localizedInnerContent = newInnerContent; } OnComponentChanged(Component, new ComponentChangedEventArgs(Component, null, null, null)); } /// public static ViewRendering GetViewRendering(System.Web.UI.Control control) { ControlDesigner designer = null; ISite site = control.Site; if (site != null) { IDesignerHost host = (IDesignerHost)site.GetService(typeof(IDesignerHost)); Debug.Assert(host != null, "Did not get a valid IDesignerHost reference"); designer = host.GetDesigner(control) as ControlDesigner; } return GetViewRendering(designer); } /// public static ViewRendering GetViewRendering(ControlDesigner designer) { string designTimeHtml = String.Empty; DesignerRegionCollection regions = new DesignerRegionCollection(); bool visible = true; if (designer != null) { bool supportsRegions = false; if (designer.View != null) { supportsRegions = designer.View.SupportsRegions; } try { // clear the preview control so it will be current when we call GetDesignTimeHtml designer.ViewControlCreated = false; // Otherwise, just get the view rendering for this control if (supportsRegions) { designTimeHtml = designer.GetDesignTimeHtml(regions); } else { designTimeHtml = designer.GetDesignTimeHtml(); } // Get Visible property after calling GetDesignTimeHtml(), so visible will still be true // if GetDesignTimeHtml() throws an exception. visible = designer.Visible; } catch (Exception ex) { // If an exception was thrown, create an error block for it regions.Clear(); try { designTimeHtml = designer.GetErrorDesignTimeHtml(ex); } catch (Exception ex2) { // If generating the designer's custom error block threw, // create a default error block designTimeHtml = designer.CreateErrorDesignTimeHtml(ex2.Message); } // Ensure View is always visible if there was an error. visible = true; } } return new ViewRendering(designTimeHtml, regions, visible); } /// public ViewRendering GetViewRendering() { ViewRendering viewRendering = null; EditableDesignerRegion containingRegion = null; if (View != null) { containingRegion = View.ContainingRegion as EditableDesignerRegion; } if (containingRegion != null) { // Call the containing editable region to get the view rendering viewRendering = ((EditableDesignerRegion)containingRegion).GetChildViewRendering((WebUIControl)this.Component); } else { viewRendering = ControlDesigner.GetViewRendering(this); } return viewRendering; } private void IgnoreComponentChanges(bool ignore) { _ignoreComponentChangesCount += (ignore ? 1 : -1); Debug.Assert(_ignoreComponentChangesCount >= 0, "Ignore count should always be non-negative"); } /// /// /// /// Initializes the designer using /// the specified component. /// /// public override void Initialize(IComponent component) { VerifyInitializeArgument(component, typeof(WebUIControl)); base.Initialize(component); if (RootDesigner != null) { RootDesigner.GetControlViewAndTag((WebUIControl)Component, out _view, out _tag); if (_view != null) { _view.ViewEvent += new ViewEventHandler(OnViewEvent); } } Expressions.Changed += new EventHandler(OnExpressionsChanged); isWebControl = (component is WebControl); UpdateExpressionValues(component); } /// public void Invalidate() { if (View != null) { Invalidate(View.GetBounds(null)); } } /// public void Invalidate(Rectangle rectangle) { if (View != null) { View.Invalidate(rectangle); } } /// public static void InvokeTransactedChange(IComponent component, TransactedChangeCallback callback, object context, string description) { InvokeTransactedChange(component, callback, context, description, null); } public static void InvokeTransactedChange(IComponent component, TransactedChangeCallback callback, object context, string description, MemberDescriptor member) { if (component == null) { throw new ArgumentNullException("component"); } InvokeTransactedChange(component.Site, component, callback, context, description, member); } /// /// /// public static void InvokeTransactedChange(IServiceProvider serviceProvider, IComponent component, TransactedChangeCallback callback, object context, string description, MemberDescriptor member) { if (component == null) { throw new ArgumentNullException("component"); } if (callback == null) { throw new ArgumentNullException("callback"); } if (serviceProvider == null) { throw new ArgumentException(SR.GetString(SR.ControlDesigner_TransactedChangeRequiresServiceProvider), "serviceProvider"); } IDesignerHost designerHost = (IDesignerHost)serviceProvider.GetService(typeof(IDesignerHost)); Debug.Assert(designerHost != null); using (DesignerTransaction transaction = designerHost.CreateTransaction(description)) { IComponentChangeService changeService = (IComponentChangeService)serviceProvider.GetService(typeof(IComponentChangeService)); if (changeService != null) { try { changeService.OnComponentChanging(component, member); } catch (CheckoutException ce) { if (ce == CheckoutException.Canceled) { // This will exit the "using" statement and the transaction will be cancelled return; } throw ce; } } ControlDesigner controlDesigner = designerHost.GetDesigner(component) as ControlDesigner; bool unIgnored = false; // This makes sure we unignore only once try { if (controlDesigner != null) { controlDesigner.IgnoreComponentChanges(true); } if (callback(context)) { if (controlDesigner != null) { unIgnored = true; controlDesigner.IgnoreComponentChanges(false); } if (changeService != null) { changeService.OnComponentChanged(component, member, null, null); } TypeDescriptor.Refresh(component); transaction.Commit(); } } finally { if (controlDesigner != null && !unIgnored) { controlDesigner.IgnoreComponentChanges(false); } } } } /// /// /// /// Gets a value indicating whether a particular property (identified by its name) is data bound. /// /// [Obsolete("The recommended alternative is DataBindings.Contains(string). The DataBindings collection allows more control of the databindings associated with the control. http://go.microsoft.com/fwlink/?linkid=14202")] public bool IsPropertyBound(string propName) { return (DataBindings[propName] != null); } /// /// /// Called when an autoformat has been applied to the control. /// A designer may override this to inspect the control's properties, or /// to take further action. /// public virtual void OnAutoFormatApplied(DesignerAutoFormat appliedAutoFormat) { } private static readonly Attribute[] emptyAttrs = new Attribute[0]; private static readonly Attribute[] nonBrowsableAttrs = new Attribute[] { BrowsableAttribute.No }; /// /// /// protected override void PreFilterProperties(IDictionary properties) { base.PreFilterProperties(properties); PropertyDescriptor prop; // Handle shadowed properties prop = (PropertyDescriptor)properties["ID"]; if (prop != null) { properties["ID"] = TypeDescriptor.CreateProperty(GetType(), prop, emptyAttrs); } prop = (PropertyDescriptor)properties["SkinID"]; if (prop != null) { properties["SkinID"] = TypeDescriptor.CreateProperty(prop.ComponentType, prop, new TypeConverterAttribute(typeof(SkinIDTypeConverter))); } if (InTemplateMode) { // If we are in template editing mode, we optionally hide all // properties except for the ID property. We always make the ID // property readonly in template editing mode. if (HidePropertiesInTemplateMode) { HideAllPropertiesExceptID(properties); } prop = (PropertyDescriptor)properties["ID"]; if (prop != null) { properties[prop.Name] = TypeDescriptor.CreateProperty(prop.ComponentType, prop, ReadOnlyAttribute.Yes); } } #if ORCAS IFilterResolutionService filterResolutionService = (IFilterResolutionService)Component.Site.GetService(typeof(IFilterResolutionService)); bool filterSet = false; if (filterResolutionService != null) { filterSet = (filterResolutionService.CurrentFilter.Length > 0) && !String.Equals(filterResolutionService.CurrentFilter, "default", StringComparison.InvariantCultureIgnoreCase); } IDictionary replaceDictionary = new HybridDictionary(true); // Hide some properties and unfilterable properties if a filter is set if (filterSet) { foreach (PropertyDescriptor pd in properties.Values) { if (!FilterableAttribute.IsPropertyFilterable(pd) || String.Equals(pd.Name, "DynamicProperties", StringComparison.InvariantCultureIgnoreCase)) { replaceDictionary[pd.Name] = TypeDescriptor.CreateProperty(pd.ComponentType, pd, nonBrowsableAttrs); } } } foreach (DictionaryEntry entry in replaceDictionary) { properties[entry.Key] = entry.Value; } #endif } /// /// /// /// Delegate to /// handle bindings collection changed event. /// /// [Obsolete("The recommended alternative is to handle the Changed event on the DataBindings collection. The DataBindings collection allows more control of the databindings associated with the control. http://go.microsoft.com/fwlink/?linkid=14202")] protected override void OnBindingsCollectionChanged(string propName) { // NOTE: This code is here strictly for backwards compatibility. // Some control designers did some funky things by adding and // removing DataBindings from within property setters. On top of // this, those properties were marked with DesignerSerializationVisibility // set to Hidden. This code is from v1.x and just does the right thing // for this rare and obscure case. if (Tag == null) return; DataBindingCollection bindings = DataBindings; if (propName != null) { DataBinding db = bindings[propName]; string persistPropName = propName.Replace('.', '-'); if (db == null) { Tag.RemoveAttribute(persistPropName); } else { string bindingExpr = "<%# " + db.Expression + " %>"; Tag.SetAttribute(persistPropName, bindingExpr); if (persistPropName.IndexOf('-') < 0) { // We only reset top-level properties to be consistent with // what we do the other way around, i.e., when a databound // property value is set to some value ResetPropertyValue(persistPropName, false); } } } else { string[] removedBindings = bindings.RemovedBindings; foreach (string s in removedBindings) { string persistPropName = s.Replace('.', '-'); Tag.RemoveAttribute(persistPropName); } foreach (DataBinding db in bindings) { string bindingExpr = "<%# " + db.Expression + " %>"; string persistPropName = db.PropertyName.Replace('.', '-'); Tag.SetAttribute(persistPropName, bindingExpr); if (persistPropName.IndexOf('-') < 0) { // We only reset top-level properties to be consistent with // what we do the other way around, i.e., when a databound // property value is set to some value ResetPropertyValue(persistPropName, false); } } } } /// /// /// protected virtual void OnClick(DesignerRegionMouseEventArgs e) { } /// /// /// /// Delegate to handle component changed event. /// /// public virtual void OnComponentChanged(object sender, ComponentChangedEventArgs ce) { if (IsIgnoringComponentChanges) { return; } IComponent component = Component; Debug.Assert(ce.Component == component, "ControlDesigner::OnComponentChanged - Called from an unknown/invalid source object"); if (DesignTimeElementInternal == null) { return; } MemberDescriptor member = ce.Member; if (member != null) { // Type t = Type.GetType("System.ComponentModel.ReflectPropertyDescriptor, " + AssemblyRef.System); if ((member.GetType() != t) || (ce.NewValue != null && ce.NewValue == ce.OldValue)) { // HACK: ideally, we would prevent the property descriptor from firing this change. // This would tear large holes in the WFC architecture. Instead, we do the // filtering ourselves in this evil fashion. Debug.WriteLineIf(CompModSwitches.UserControlDesigner.TraceInfo, " ...ignoring property descriptor of type: " + member.GetType().Name); return; } if (((PropertyDescriptor)member).SerializationVisibility != DesignerSerializationVisibility.Hidden) { // Set the dirty state upon changing persistable properties. IsDirtyInternal = true; PersistenceModeAttribute persistenceType = (PersistenceModeAttribute)member.Attributes[typeof(PersistenceModeAttribute)]; PersistenceMode mode = persistenceType.Mode; if ((mode == PersistenceMode.Attribute) || (mode == PersistenceMode.InnerDefaultProperty) || (mode == PersistenceMode.EncodedInnerDefaultProperty)) { string propName = member.Name; // Check to see whether the property that was changed is data bound. // If it is we need to remove it... // For this rev, we're only doing this for the properties on the Component itself // as we can't distinguish which subproperty of a complex type changed. if (ce.Component == Component) { if (DataBindings.Contains(propName)) { DataBindings.Remove(propName, false); RemoveTagAttribute(propName, true); } if (Expressions.Contains(propName)) { ExpressionBinding eb = Expressions[propName]; if (!eb.Generated) { Expressions.Remove(propName, false); RemoveTagAttribute(propName, true); } // Always mark expressions as changed so that UpdateExpressionValues will be called. // This is necessary because when a property's value is set, it gets set on // the component itself, and that overwrites the expression's design-time value, // and we need to restore the expression's design-time value. _expressionsChanged = true; } } // For tag level properties ... WebUIControl control = (WebUIControl)ce.Component; IDesignerHost host = null; if (control.Site != null) { host = (IDesignerHost)control.Site.GetService(typeof(IDesignerHost)); } Debug.Assert(host != null, "Need an IDesignerHost to persist properties"); if (host != null) { ArrayList attribs = ControlSerializer.GetControlPersistedAttribute(control, (PropertyDescriptor)member, host); PersistAttributes(attribs); } } } } else { // member is null, meaning that the whole component // could have changed and not just a single member. // This happens when a component is edited through a ComponentEditor. // Set the dirty state if more than one property is changed. IsDirtyInternal = true; WebUIControl control = (WebUIControl)ce.Component; IDesignerHost host = null; if (control.Site != null) { host = (IDesignerHost)control.Site.GetService(typeof(IDesignerHost)); } // Reset all properties which used to have expression, but don't anymore // Do this before persisting attributes so the old expression-evaluated values // don't get into the persistence foreach (string propName in Expressions.RemovedBindings) { object realTarget; PropertyDescriptor propDesc = GetComplexProperty(Component, propName, out realTarget); if (propDesc != null) { IgnoreComponentChanges(true); try { propDesc.ResetValue(realTarget); } finally { IgnoreComponentChanges(false); } } } Debug.Assert(host != null, "Need an IDesignerHost to persist properties"); if (host != null) { ArrayList attribs = ControlSerializer.GetControlPersistedAttributes(control, host); PersistAttributes(attribs); } foreach (DataBinding db in DataBindings) { if (db.PropertyName.IndexOf('.') < 0) { // We only reset top-level properties to be consistent with // what we do the other way around, i.e., when a databound // property value is set to some value ResetPropertyValue(db.PropertyName, false); } } OnBindingsCollectionChangedInternal(null); // Since we don't know which property changed, we force re-evaluation of all expressions. // This is necessary because when a property's value is set, it gets set on // the component itself, and that overwrites the expression's design-time value, // and we need to restore the expression's design-time value. _expressionsChanged = true; } if (_expressionsChanged) { UpdateExpressionValues(Component); } // Update the HTML and verbs. UpdateDesignTimeHtml(); } /// /// /// public virtual void OnComponentChanging(object sender, ComponentChangingEventArgs ce) { } /// /// /// Notification from the identity behavior upon resizing the control in the designer. /// This is only called when a user action causes the control to be resized. /// Note that this method may be called several times during a resize process so as /// to enable live-resize of the contents of the control. /// [Obsolete("The recommended alternative is OnComponentChanged(). OnComponentChanged is called when any property of the control is changed. http://go.microsoft.com/fwlink/?linkid=14202")] protected virtual void OnControlResize() { } private void OnExpressionsChanged(object sender, EventArgs e) { // Remember that the collection as changed so we can re-persist in OnComponentChanged _expressionsChanged = true; } /// /// /// /// protected virtual void OnPaint(PaintEventArgs e) { } private void OnViewEvent(object sender, ViewEventArgs e) { if (e.EventType == ViewEvent.Click) { OnClick((DesignerRegionMouseEventArgs)e.EventArgs); } else if (e.EventType == ViewEvent.Paint) { OnPaint((PaintEventArgs)e.EventArgs); } else if (e.EventType == ViewEvent.TemplateModeChanged) { TemplateModeChangedEventArgs tmea = (TemplateModeChangedEventArgs)e.EventArgs; _inTemplateMode = (tmea.NewTemplateGroup != null); // Invalidate the type descriptor so that proper filtering of properties // is done when entering and exiting template mode. TypeDescriptor.Refresh(Component); } } private void PersistAttributes(ArrayList attributes) { foreach (Triplet triplet in attributes) { string attribName = Convert.ToString(triplet.Second, CultureInfo.InvariantCulture); string filter = triplet.First.ToString(); if ((filter == null) || (filter.Length > 0)) { attribName = filter + ':' + attribName; } if (triplet.Third == null) { RemoveTagAttribute(attribName, true); } else { string persistValue = Convert.ToString(triplet.Third, CultureInfo.InvariantCulture); SetTagAttribute(attribName, persistValue, true); } } } /// /// /// [Obsolete("Use of this method is not recommended because resizing is handled by the OnComponentChanged() method. http://go.microsoft.com/fwlink/?linkid=14202")] public void RaiseResizeEvent() { OnControlResize(); } /// /// Registers internal data in a cloned item. Whenever an item that is to be /// persisted is cloned, there are some internal data structures that have to /// be cloned as well. This can only be done by the ControlDesigner. /// public void RegisterClone(object original, object clone) { if (original == null) { throw new ArgumentNullException("original"); } if (clone == null) { throw new ArgumentNullException("clone"); } ControlBuilder cb = ((IControlBuilderAccessor)Component).ControlBuilder; if (cb != null) { ObjectPersistData persistData = cb.GetObjectPersistData(); persistData.BuiltObjects[clone] = persistData.BuiltObjects[original]; } } private void ResetPropertyValue(string property, bool useInstance) { PropertyDescriptor propDesc = null; if (useInstance) { propDesc = TypeDescriptor.GetProperties(Component)[property]; } else { propDesc = TypeDescriptor.GetProperties(Component.GetType())[property]; } if (propDesc != null) { IgnoreComponentChanges(true); try { propDesc.ResetValue(Component); } finally { IgnoreComponentChanges(false); } } } private void RemoveTagAttribute(string name, bool ignoreCase) { if (Tag != null) { Tag.RemoveAttribute(name); } else { BehaviorInternal.RemoveAttribute(name, ignoreCase); } } public virtual void SetEditableDesignerRegionContent(EditableDesignerRegion region, string content) { } protected void SetRegionContent(EditableDesignerRegion region, string content) { if (View != null) { View.SetRegionContent(region, content); } } private void SetTagAttribute(string name, object value, bool ignoreCase) { if (Tag != null) { Tag.SetAttribute(name, value.ToString()); } else { BehaviorInternal.SetAttribute(name, value, ignoreCase); } } /// protected void SetViewFlags(ViewFlags viewFlags, bool setFlag) { if (View != null) { View.SetFlags(viewFlags, setFlag); } } /// /// /// /// Updates the design time HTML. /// /// public virtual void UpdateDesignTimeHtml() { if (View != null) { View.Update(); } else { if (ReadOnlyInternal) { #pragma warning disable 618 IHtmlControlDesignerBehavior behavior = BehaviorInternal; if (behavior != null) { Debug.Assert(behavior is IControlDesignerBehavior, "Unexpected type of behavior for custom control"); ((IControlDesignerBehavior)behavior).DesignTimeHtml = GetDesignTimeHtml(); } #pragma warning restore 618 } } } private void UpdateExpressionValues(IComponent target) { IExpressionsAccessor expressionsAccessor = target as IExpressionsAccessor; TemplateControl templateControl = null; IDesignerHost host = (IDesignerHost)GetService(typeof(IDesignerHost)); if (host != null) { templateControl = host.RootComponent as TemplateControl; Debug.Assert(host.RootComponent == null || templateControl != null, "Expected IDesignerHost.RootComponent to be either null or a valid TemplateControl"); } // Evaulate all expressions that are currently set foreach (ExpressionBinding eb in expressionsAccessor.Expressions) { if (!eb.Generated) { string propName = eb.PropertyName; object realTarget; PropertyDescriptor propDesc = GetComplexProperty(target, propName, out realTarget); if (propDesc != null) { IgnoreComponentChanges(true); try { ExpressionEditor editor = ExpressionEditor.GetExpressionEditor(eb.ExpressionPrefix, target.Site); if (editor != null) { // Ensure that parsed expression data is available to the ExpressionEditor object parsedData = EnsureParsedExpression(templateControl, eb, eb.ParsedExpressionData); object value = editor.EvaluateExpression(eb.Expression, parsedData, propDesc.PropertyType, target.Site); if (value != null) { if (value is string) { TypeConverter converter = propDesc.Converter; if (converter != null && converter.CanConvertFrom(typeof(string))) { value = converter.ConvertFromInvariantString((string)value); } } // If we actually got a value from the expression editor, try to apply it to the property propDesc.SetValue(realTarget, value); } else { // If we didn't get a value for the expression, just show the expression propDesc.SetValue(realTarget, SR.GetString(SR.ExpressionEditor_ExpressionBound, eb.Expression)); } } else { // If we couldn't even find an expression editor, also just show the expression propDesc.SetValue(realTarget, SR.GetString(SR.ExpressionEditor_ExpressionBound, eb.Expression)); } } catch { // There are some legitimate cases where an expression failed to evaluate at design time, or // is otherwise invalid for the property type, so we don't want to blow up when that happens. } finally { IgnoreComponentChanges(false); } } } } _expressionsChanged = false; } // Called by controls that only show an editable region when the template on the Component // is non-null. internal bool UseRegions(DesignerRegionCollection regions, ITemplate componentTemplate) { bool useRegions = UseRegionsCore(regions) && (componentTemplate != null); return useRegions; } // Called by controls that always show an editable region, even in the template on the Component // is null. internal bool UseRegions(DesignerRegionCollection regions, ITemplate componentTemplate, ITemplate viewControlTemplate) { // If the template on the Component is null, but the template on the ViewControl is // not null, then the template must be coming from the skin. bool templateDefinedInSkin = (componentTemplate == null && viewControlTemplate != null); // Do not use an editable region if the template is defined in the skin (VSWhidbey 468562) bool useRegions = UseRegionsCore(regions) && !templateDefinedInSkin; return useRegions; } private bool UseRegionsCore(DesignerRegionCollection regions) { bool useRegionsCore = (regions != null && View != null && View.SupportsRegions); return useRegionsCore; } internal static void VerifyInitializeArgument(IComponent component, Type expectedType) { if (!expectedType.IsInstanceOfType(component)) { throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, SR.GetString(SR.ControlDesigner_ArgumentMustBeOfType), expectedType.FullName), "component"); } } internal class ControlDesignerActionList : DesignerActionList { private ControlDesigner _parent; public ControlDesignerActionList(ControlDesigner parent) : base(parent.Component) { _parent = parent; } public override bool AutoShow { get { return true; } set { } } /// /// Transacted change callback to invoke the DataBindings dialog. /// private bool DataBindingsCallback(object context) { WebUIControl control = (WebUIControl)_parent.Component; ISite site = control.Site; DataBindingsDialog dlg = new DataBindingsDialog(site, control); DialogResult result = UIServiceHelper.ShowDialog(site, dlg); return (result == DialogResult.OK); } public void EditDataBindings() { InvokeTransactedChange(_parent.Component, new TransactedChangeCallback(DataBindingsCallback), null, SR.GetString(SR.Designer_DataBindingsVerb)); _parent.UpdateDesignTimeHtml(); } public override DesignerActionItemCollection GetSortedActionItems() { DesignerActionItemCollection items = new DesignerActionItemCollection(); if (_parent.SupportsDataBindings && _parent.DataBindingsEnabled) { items.Add(new DesignerActionMethodItem(this, "EditDataBindings", SR.GetString(SR.Designer_DataBindingsVerb), String.Empty, SR.GetString(SR.Designer_DataBindingsVerbDesc), true)); } return items; } } internal delegate DesignerAutoFormat CreateAutoFormatDelegate(DataRow schemeData); } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK