public void AddInheritedControl(Control c, InheritanceLevel level) { string str; if (this.tooltip == null) { this.tooltip = new ToolTip(); this.tooltip.ShowAlways = true; } if (level == InheritanceLevel.InheritedReadOnly) { str = System.Design.SR.GetString("DesignerInheritedReadOnly"); } else { str = System.Design.SR.GetString("DesignerInherited"); } this.tooltip.SetToolTip(c, str); foreach (Control control in c.Controls) { if (control.Site == null) { this.tooltip.SetToolTip(control, str); } } }
/// <devdoc> /// <para>Initializes a new instance of the System.ComponentModel.Design.InheritanceAttribute class /// with the specified inheritance /// level.</para> /// </devdoc> public InheritanceAttribute(InheritanceLevel inheritanceLevel) { this.inheritanceLevel = inheritanceLevel; }
/// <devdoc> /// <para>Initializes a new instance of the System.ComponentModel.Design.InheritanceAttribute /// class.</para> /// </devdoc> public InheritanceAttribute() { inheritanceLevel = Default.inheritanceLevel; }
// Constructors. public InheritanceAttribute() { level = InheritanceLevel.NotInherited; }
public InheritanceAttribute(InheritanceLevel inheritanceLevel) {}
/// <summary> /// Serializes the given object into a CodeDom object. /// </summary> public override object Serialize(IDesignerSerializationManager manager, object value) { if (manager == null || value == null) { throw new ArgumentNullException(manager == null ? "manager" : "value"); } // Find our base class's serializer. CodeDomSerializer serializer = (CodeDomSerializer)manager.GetSerializer(typeof(Component), typeof(CodeDomSerializer)); if (serializer == null) { Debug.Fail("Unable to find a CodeDom serializer for 'Component'. Has someone tampered with the serialization providers?"); return(null); } // Now ask it to serializer object retVal = serializer.Serialize(manager, value); InheritanceAttribute inheritanceAttribute = (InheritanceAttribute)TypeDescriptor.GetAttributes(value)[typeof(InheritanceAttribute)]; InheritanceLevel inheritanceLevel = InheritanceLevel.NotInherited; if (inheritanceAttribute != null) { inheritanceLevel = inheritanceAttribute.InheritanceLevel; } if (inheritanceLevel != InheritanceLevel.InheritedReadOnly) { // Next, see if we are in localization mode. If we are, and if we can get // to a ResourceManager through the service provider, then emit the hierarchy information for // this object. There is a small fragile assumption here: The resource manager is demand // created, so if all of the properties of this control had default values it is possible // there will be no resource manager for us. I'm letting that slip a bit, however, because // for Control classes, we always emit at least the location / size information for the // control. IDesignerHost host = (IDesignerHost)manager.GetService(typeof(IDesignerHost)); if (host != null) { PropertyDescriptor prop = TypeDescriptor.GetProperties(host.RootComponent)["Localizable"]; if (prop != null && prop.PropertyType == typeof(bool) && ((bool)prop.GetValue(host.RootComponent))) { SerializeControlHierarchy(manager, host, value); } } CodeStatementCollection csCollection = retVal as CodeStatementCollection; if (csCollection != null) { Control control = (Control)value; // Serialize a suspend / resume pair. We always serialize this // for the root component if ((host != null && control == host.RootComponent) || HasSitedNonReadonlyChildren(control)) { SerializeSuspendLayout(manager, csCollection, value); SerializeResumeLayout(manager, csCollection, value); ControlDesigner controlDesigner = host.GetDesigner(control) as ControlDesigner; if (HasAutoSizedChildren(control) || (controlDesigner != null && controlDesigner.SerializePerformLayout)) { SerializePerformLayout(manager, csCollection, value); } } // And now serialize the correct z-order relationships for the controls. We only need to // do this if there are controls in the collection that are inherited. if (HasMixedInheritedChildren(control)) { SerializeZOrder(manager, csCollection, control); } } } return(retVal); }
/// <summary> /// Serializes the given object into a CodeDom object. /// </summary> public override object Serialize(IDesignerSerializationManager manager, object value) { CodeStatementCollection statements = null; PropertyDescriptorCollection props = TypeDescriptor.GetProperties(value); using (TraceScope("ComponentCodeDomSerializer::Serialize")) { if (manager == null || value == null) { throw new ArgumentNullException(manager == null ? "manager" : "value"); } if (IsSerialized(manager, value)) { Debug.Fail("Serialize is being called twice for the same component"); return(GetExpression(manager, value)); } // If the object is being inherited, we will will not emit a variable declaration. Also, we won't // do any serialization at all if the object is privately inherited. InheritanceLevel inheritanceLevel = InheritanceLevel.NotInherited; InheritanceAttribute inheritanceAttribute = (InheritanceAttribute)TypeDescriptor.GetAttributes(value)[typeof(InheritanceAttribute)]; if (inheritanceAttribute != null) { inheritanceLevel = inheritanceAttribute.InheritanceLevel; } // First, skip everything if we're privately inherited. We cannot write any code that would affect this // component. TraceIf(inheritanceLevel == InheritanceLevel.InheritedReadOnly, "Skipping read only inherited component"); if (inheritanceLevel != InheritanceLevel.InheritedReadOnly) { // Things we need to know: // // 1. What expression should we use for the left hand side // a) already given to us via GetExpression? // b) a local variable? // c) a member variable? // // 2. Should we generate an init expression for this // object? // a) Inherited or existing expression: no // b) otherwise, yes. statements = new CodeStatementCollection(); CodeTypeDeclaration typeDecl = manager.Context[typeof(CodeTypeDeclaration)] as CodeTypeDeclaration; RootContext rootCxt = manager.Context[typeof(RootContext)] as RootContext; CodeExpression assignLhs = null; CodeExpression assignRhs; // Defaults for components bool generateLocal = false; bool generateField = true; bool generateObject = true; bool isComplete = false; assignLhs = GetExpression(manager, value); if (assignLhs != null) { Trace("Existing expression for LHS of value"); generateLocal = false; generateField = false; generateObject = false; // if we have an existing expression and this is not // a sited component, do not serialize it. We need this for Everett / 1.0 // backwards compat (even though it's wrong). if (value is IComponent comp && comp.Site == null) { // We were in a serialize content // property and would still serialize it. This code reverses what the // outer if block does for this specific case. We also need this // for Everett / 1.0 backwards compat. if (!(manager.Context[typeof(ExpressionContext)] is ExpressionContext expCxt) || expCxt.PresetValue != value) { isComplete = true; } } } else { Trace("Creating LHS expression"); if (inheritanceLevel == InheritanceLevel.NotInherited) { // See if there is a "GenerateMember" property. If so, // we might want to generate a local variable. Otherwise, // we want to generate a field. PropertyDescriptor generateProp = props["GenerateMember"]; if (generateProp != null && generateProp.PropertyType == typeof(bool) && !(bool)generateProp.GetValue(value)) { Trace("Object GenerateMember property wants a local variable"); generateLocal = true; generateField = false; } } else { generateObject = false; } if (rootCxt == null) { generateLocal = true; generateField = false; } } // Push the component being serialized onto the stack. It may be handy to // be able to discover this. manager.Context.Push(value); manager.Context.Push(statements); try { string name = manager.GetName(value); string typeName = TypeDescriptor.GetClassName(value); // Output variable / field declarations if we need to if ((generateField || generateLocal) && name != null) { if (generateField) { if (inheritanceLevel == InheritanceLevel.NotInherited) { // We need to generate the field declaration. See if there is a modifiers property on // the object. If not, look for a DefaultModifies, and finally assume it's private. CodeMemberField field = new CodeMemberField(typeName, name); PropertyDescriptor modifersProp = props["Modifiers"]; MemberAttributes fieldAttrs; if (modifersProp == null) { modifersProp = props["DefaultModifiers"]; } if (modifersProp != null && modifersProp.PropertyType == typeof(MemberAttributes)) { fieldAttrs = (MemberAttributes)modifersProp.GetValue(value); } else { TraceWarning("No Modifiers or DefaultModifiers property on component {0}. We must assume private.", name); fieldAttrs = MemberAttributes.Private; } field.Attributes = fieldAttrs; typeDecl.Members.Add(field); Trace("Field {0} {1} {2} created.", fieldAttrs, typeName, name); } // Next, create a nice LHS for our pending assign statement, when we hook up the variable. assignLhs = new CodeFieldReferenceExpression(rootCxt.Expression, name); } else { if (inheritanceLevel == InheritanceLevel.NotInherited) { CodeVariableDeclarationStatement local = new CodeVariableDeclarationStatement(typeName, name); statements.Add(local); Trace("Local {0} {1} created.", typeName, name); } assignLhs = new CodeVariableReferenceExpression(name); } } // Now output an object create if we need to. We always see if there is a // type converter that can provide us guidance if (generateObject) { // Ok, now that we've decided if we have a local or a member variable, its now time to serialize the rest of the code. // The first step is to create an assign statement to "new" the object. For that, we need to know if // the component wants a special IContainer constructor or not. For that to be valid we must also know // that we can get to an actual IContainer. IContainer container = manager.GetService(typeof(IContainer)) as IContainer; ConstructorInfo ctor = null; if (container != null) { ctor = GetReflectionTypeHelper(manager, value).GetConstructor(BindingFlags.ExactBinding | BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly, null, GetContainerConstructor(manager), null); } if (ctor != null) { Trace("Component has IContainer constructor."); assignRhs = new CodeObjectCreateExpression(typeName, new CodeExpression[] { SerializeToExpression(manager, container) }); } else { // For compat reasons we ignore the isCompleteOld value here. assignRhs = SerializeCreationExpression(manager, value, out bool isCompleteOld); Debug.Assert(isCompleteOld == isComplete, "CCDS Differing"); } TraceErrorIf(assignRhs == null, "No RHS code assign for object {0}", value); if (assignRhs != null) { if (assignLhs == null) { // We cannot do much more for this object. If isComplete is true, // then the RHS now becomes our LHS. Otherwise, I'm afraid we have // just failed to serialize this object. if (isComplete) { assignLhs = assignRhs; } else { TraceError("Incomplete serialization of object, abandoning serialization."); } } else { CodeAssignStatement assign = new CodeAssignStatement(assignLhs, assignRhs); statements.Add(assign); } } } if (assignLhs != null) { SetExpression(manager, value, assignLhs); } // It should practically be an assert that isComplete is false, but someone may // have an unusual component. if (assignLhs != null && !isComplete) { // .NET CF needs us to verify that the ISupportInitialize interface exists // (they do not support this interface and will modify their DSM to resolve the type to null). bool supportInitialize = (value is ISupportInitialize); if (supportInitialize) { string fullName = typeof(ISupportInitialize).FullName; supportInitialize = manager.GetType(fullName) != null; } Type reflectionType = null; if (supportInitialize) { // Now verify that this control implements ISupportInitialize in the project target framework // Don't use operator "is" but rather use IsAssignableFrom on the reflection types. // We have other places where we use operator "is", for example "is IComponent" to generate // specific CodeDOM objects, however we don't have cases of objects which were not an IComponent // in a downlevel framework and became an IComponent in a newer framework, so I'm not replacing // all instances of operator "is" by IsAssignableFrom. reflectionType = GetReflectionTypeHelper(manager, value); supportInitialize = GetReflectionTypeFromTypeHelper(manager, typeof(ISupportInitialize)).IsAssignableFrom(reflectionType); } bool persistSettings = (value is IPersistComponentSettings) && ((IPersistComponentSettings)value).SaveSettings; if (persistSettings) { string fullName = typeof(IPersistComponentSettings).FullName; persistSettings = manager.GetType(fullName) != null; } if (persistSettings) { reflectionType = reflectionType ?? GetReflectionTypeHelper(manager, value); persistSettings = GetReflectionTypeFromTypeHelper(manager, typeof(IPersistComponentSettings)).IsAssignableFrom(reflectionType); } // We implement statement caching only for the main code generation phase. We don't implement it for other // serialization managers. How do we tell the difference? The main serialization manager exists as a service. IDesignerSerializationManager mainManager = manager.GetService(typeof(IDesignerSerializationManager)) as IDesignerSerializationManager; if (supportInitialize) { Trace("Object implements ISupportInitialize."); SerializeSupportInitialize(manager, statements, assignLhs, value, "BeginInit"); } SerializePropertiesToResources(manager, statements, value, _designTimeFilter); // Writing out properties is expensive. But, we're very smart and we cache the results // in ComponentCache. See if we have cached results. If so, use 'em. If not, generate // code and then see if we can cache the results for later. ComponentCache cache = manager.GetService(typeof(ComponentCache)) as ComponentCache; ComponentCache.Entry entry = null; if (cache == null) { if (manager.GetService(typeof(IServiceContainer)) is ServiceContainer sc) { cache = new ComponentCache(manager); sc.AddService(typeof(ComponentCache), cache); } } else { if (manager == mainManager && cache.Enabled) { entry = cache[value]; } } if (entry == null || entry.Tracking) { // Pushing the entry here allows it to be found by the resource code dom serializer, // which will add data to the ResourceBlob property on the entry. if (entry == null) { entry = new ComponentCache.Entry(cache); // We cache components even if they're not valid so dependencies are // still tracked correctly (see comment below). The problem is, we will create a // new entry object even if there is still an existing one that is just invalid, and it // might have dependencies that will be lost. // we need to make sure we copy over any dependencies that are also tracked. ComponentCache.Entry oldEntry = cache?.GetEntryAll(value); if (oldEntry != null && oldEntry.Dependencies != null && oldEntry.Dependencies.Count > 0) { foreach (object dependency in oldEntry.Dependencies) { entry.AddDependency(dependency); } } } entry.Component = value; // we need to link the cached entry with its corresponding component right away, before it's put in the context // see CodeDomSerializerBase.cs::GetExpression for usage // This entry will only be used if the valid bit is set. // This is useful because we still need to setup depedency relationships // between components even if they are not cached. See VSWhidbey 263053. bool correctManager = manager == mainManager; entry.Valid = correctManager && CanCacheComponent(manager, value, props); if (correctManager && cache != null && cache.Enabled) { manager.Context.Push(cache); manager.Context.Push(entry); } try { entry.Statements = new CodeStatementCollection(); SerializeProperties(manager, entry.Statements, value, _runTimeFilter); SerializeEvents(manager, entry.Statements, value, null); foreach (CodeStatement statement in entry.Statements) { if (statement is CodeVariableDeclarationStatement local) { entry.Tracking = true; break; } } if (entry.Statements.Count > 0) { // if we added some statements, insert the comments // entry.Statements.Insert(0, new CodeCommentStatement(string.Empty)); entry.Statements.Insert(0, new CodeCommentStatement(name)); entry.Statements.Insert(0, new CodeCommentStatement(string.Empty)); // // cache the statements for future usage if possible. We only do this for the main serialization manager, not // for any other seriallization managers that may be calling us for undo or clipboard functions. if (correctManager && cache != null && cache.Enabled) { cache[value] = entry; } } } finally { if (correctManager && cache != null && cache.Enabled) { Debug.Assert(manager.Context.Current == entry, "Context stack corrupted"); manager.Context.Pop(); manager.Context.Pop(); } } } else { // If we got a cache entry, we will need to take all the resources out of // it and apply them too. if ((entry.Resources != null || entry.Metadata != null) && cache != null && cache.Enabled) { ResourceCodeDomSerializer res = ResourceCodeDomSerializer.Default; res.ApplyCacheEntry(manager, entry); } } // Regarless, apply statements. Either we created them or we got them // out of the cache. statements.AddRange(entry.Statements); if (persistSettings) { SerializeLoadComponentSettings(manager, statements, assignLhs, value); } if (supportInitialize) { SerializeSupportInitialize(manager, statements, assignLhs, value, "EndInit"); } } } catch (CheckoutException) { throw; } catch (Exception ex) { manager.ReportError(ex); } finally { Debug.Assert(manager.Context.Current == statements, "Context stack corrupted"); manager.Context.Pop(); manager.Context.Pop(); } } } return(statements); }
/// <devdoc> /// <para>Initializes a new instance of the System.ComponentModel.Design.InheritanceAttribute class /// with the specified inheritance /// level.</para> /// </devdoc> public InheritanceAttribute(InheritanceLevel inheritanceLevel) { this.inheritanceLevel = inheritanceLevel; }
/// <devdoc> /// <para>Initializes a new instance of the System.ComponentModel.Design.InheritanceAttribute /// class.</para> /// </devdoc> public InheritanceAttribute() { inheritanceLevel = Default.inheritanceLevel; }
/// <include file='doc\ComponentCodeDomSerializer.uex' path='docs/doc[@for="ComponentCodeDomSerializer.Serialize"]/*' /> /// <devdoc> /// Serializes the given object into a CodeDom object. /// </devdoc> public override object Serialize(IDesignerSerializationManager manager, object value) { Debug.WriteLineIf(traceSerialization.TraceVerbose, "ComponentCodeDomSerializer::Serialize"); Debug.Indent(); try { Debug.WriteLineIf(traceSerialization.TraceVerbose, "Value: " + value.ToString()); } catch { // in case the ToString throws... } if (manager == null || value == null) { throw new ArgumentNullException(manager == null ? "manager" : "value"); } CodeStatementCollection statements = new CodeStatementCollection(); CodeExpression instanceDescrExpr = null; InheritanceAttribute inheritanceAttribute = (InheritanceAttribute)TypeDescriptor.GetAttributes(value)[typeof(InheritanceAttribute)]; InheritanceLevel inheritanceLevel = InheritanceLevel.NotInherited; if (inheritanceAttribute != null) { inheritanceLevel = inheritanceAttribute.InheritanceLevel; } // Get the name for this object. Components can only be serialized if they have // a name. // string name = manager.GetName(value); bool generateDeclaration = (name != null); if (name == null) { IReferenceService referenceService = (IReferenceService)manager.GetService(typeof(IReferenceService)); if (referenceService != null) { name = referenceService.GetName(value); } } Debug.WriteLineIf(traceSerialization.TraceWarning && name == null, "WARNING: object has no name so we cannot serialize."); if (name != null) { Debug.WriteLineIf(traceSerialization.TraceVerbose, "Name: " + name); // Push the component being serialized onto the stack. It may be handy to // be able to discover this. // manager.Context.Push(value); try { try { // If the object is not inherited ensure that is has a component declaration. // if (generateDeclaration && inheritanceLevel == InheritanceLevel.NotInherited) { // Check to make sure this isn't our base component. If it is, there is // no need to serialize its declaration. // IDesignerHost host = (IDesignerHost)manager.GetService(typeof(IDesignerHost)); if ((host == null || host.RootComponent != value)) { SerializeDeclaration(manager, statements, value); } } else { Debug.WriteLineIf(traceSerialization.TraceVerbose, "Skipping declaration of inherited or namespace component."); } // Next, if the object is not being privately inherited, serialize the // rest of its state. // if (inheritanceLevel != InheritanceLevel.InheritedReadOnly) { bool supportInitialize = (value is ISupportInitialize); if (supportInitialize) { Debug.WriteLineIf(traceSerialization.TraceVerbose, "Object implements ISupportInitialize."); SerializeSupportInitialize(manager, statements, value, "BeginInit"); } // Add a nice comment that declares we're about to serialize this component // int insertLoc = statements.Count; SerializePropertiesToResources(manager, statements, value, designTimeProperties); SerializeProperties(manager, statements, value, runTimeProperties); SerializeEvents(manager, statements, value, null); // if we added some statements, insert the comments // if (statements.Count > insertLoc) { statements.Insert(insertLoc, new CodeCommentStatement(string.Empty)); statements.Insert(insertLoc, new CodeCommentStatement(name)); statements.Insert(insertLoc, new CodeCommentStatement(string.Empty)); } if (supportInitialize) { SerializeSupportInitialize(manager, statements, value, "EndInit"); } } else { Debug.WriteLineIf(traceSerialization.TraceVerbose, "Skipping serialization of read-only inherited component"); } } catch (Exception ex) { manager.ReportError(ex); } } finally { Debug.Assert(manager.Context.Current == value, "Context stack corrupted"); manager.Context.Pop(); } } else { Debug.WriteLineIf(traceSerialization.TraceWarning, "Attempting instance descriptor serialization."); Debug.Indent(); // Last resort, lets see if if can serialize itself to an instance descriptor. // if (TypeDescriptor.GetConverter(value).CanConvertTo(typeof(InstanceDescriptor))) { Debug.WriteLineIf(traceSerialization.TraceWarning, "Type supports instance descriptor."); // Got an instance descriptor. Ask it to serialize // object o = InstanceDescriptorCodeDomSerializer.Default.Serialize(manager, value); if (o is CodeExpression) { Debug.WriteLineIf(traceSerialization.TraceWarning, "Serialized successfully."); instanceDescrExpr = (CodeExpression)o; } } Debug.Unindent(); } if (instanceDescrExpr != null) { Debug.WriteLineIf(traceSerialization.TraceVerbose, "Object serialized into a single InstanceDescriptor expression."); Debug.Unindent(); return(instanceDescrExpr); } else { Debug.WriteLineIf(traceSerialization.TraceVerbose, "Object serialized into " + statements.Count.ToString() + " statements."); Debug.Unindent(); return(statements); } }
// Constructors. public InheritanceAttribute() { level = InheritanceLevel.NotInherited; }
public InheritanceAttribute(InheritanceLevel inheritanceLevel) { }