public override object Serialize(IDesignerSerializationManager manager, object obj) { if (manager == null) { throw new ArgumentNullException("manager"); } if (manager.Context == null) { throw new ArgumentException("manager", SR.GetString("Error_MissingContextProperty")); } if (obj == null) { throw new ArgumentNullException("obj"); } DependencyObject component = obj as DependencyObject; if (component == null) { throw new ArgumentException(SR.GetString("Error_UnexpectedArgumentType", new object[] { typeof(DependencyObject).FullName }), "obj"); } Activity context = obj as Activity; if (context != null) { manager.Context.Push(context); } CodeStatementCollection statements = null; try { if (context != null) { CodeDomSerializer serializer = manager.GetSerializer(typeof(Component), typeof(CodeDomSerializer)) as CodeDomSerializer; if (serializer == null) { throw new InvalidOperationException(SR.GetString("General_MissingService", new object[] { typeof(CodeDomSerializer).FullName })); } statements = serializer.Serialize(manager, context) as CodeStatementCollection; } else { statements = base.Serialize(manager, obj) as CodeStatementCollection; } if (statements == null) { return(statements); } CodeStatementCollection statements2 = new CodeStatementCollection(statements); CodeExpression targetObject = base.SerializeToExpression(manager, obj); if (targetObject == null) { return(statements); } ArrayList list = new ArrayList(); List <DependencyProperty> list2 = new List <DependencyProperty>(component.MetaDependencyProperties); foreach (DependencyProperty property in component.DependencyPropertyValues.Keys) { if (property.IsAttached && ((property.IsEvent && (property.OwnerType.GetField(property.Name + "Event", BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly) != null)) || (!property.IsEvent && (property.OwnerType.GetField(property.Name + "Property", BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly) != null)))) { list2.Add(property); } } foreach (DependencyProperty property2 in list2) { object binding = null; if (component.IsBindingSet(property2)) { binding = component.GetBinding(property2); } else if (!property2.IsEvent) { binding = component.GetValue(property2); } else { binding = component.GetHandler(property2); } if ((binding != null) && (property2.IsAttached || (!property2.DefaultMetadata.IsMetaProperty && (binding is ActivityBind)))) { object[] attributes = property2.DefaultMetadata.GetAttributes(typeof(DesignerSerializationVisibilityAttribute)); if (attributes.Length > 0) { DesignerSerializationVisibilityAttribute attribute = attributes[0] as DesignerSerializationVisibilityAttribute; if (attribute.Visibility == DesignerSerializationVisibility.Hidden) { continue; } } CodeExpression expression2 = null; string name = property2.Name + (property2.IsEvent ? "Event" : "Property"); FieldInfo field = property2.OwnerType.GetField(name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static); if ((field != null) && !field.IsPublic) { expression2 = new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(typeof(DependencyProperty)), "FromName", new CodeExpression[] { new CodePrimitiveExpression(property2.Name), new CodeTypeOfExpression(property2.OwnerType) }); } else { expression2 = new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(property2.OwnerType), name); } CodeExpression expression = base.SerializeToExpression(manager, binding); if ((expression2 != null) && (expression != null)) { CodeMethodInvokeExpression expression4 = null; if (binding is ActivityBind) { expression4 = new CodeMethodInvokeExpression(targetObject, "SetBinding", new CodeExpression[] { expression2, new CodeCastExpression(new CodeTypeReference(typeof(ActivityBind)), expression) }); } else { expression4 = new CodeMethodInvokeExpression(targetObject, property2.IsEvent ? "AddHandler" : "SetValue", new CodeExpression[] { expression2, expression }); } statements.Add(expression4); foreach (CodeStatement statement in statements2) { if ((statement is CodeAssignStatement) && (((CodeAssignStatement)statement).Left is CodePropertyReferenceExpression)) { CodePropertyReferenceExpression left = ((CodeAssignStatement)statement).Left as CodePropertyReferenceExpression; if ((left.PropertyName == property2.Name) && left.TargetObject.Equals(targetObject)) { statements.Remove(statement); } } } } list.Add(property2); } } if (!(manager.GetService(typeof(IEventBindingService)) is IEventBindingService)) { foreach (EventDescriptor descriptor in TypeDescriptor.GetEvents(component)) { string eventHandlerName = WorkflowMarkupSerializationHelpers.GetEventHandlerName(component, descriptor.Name); if (!string.IsNullOrEmpty(eventHandlerName)) { CodeEventReferenceExpression eventRef = new CodeEventReferenceExpression(targetObject, descriptor.Name); CodeDelegateCreateExpression listener = new CodeDelegateCreateExpression(new CodeTypeReference(descriptor.EventType), new CodeThisReferenceExpression(), eventHandlerName); statements.Add(new CodeAttachEventStatement(eventRef, listener)); } } } if (!component.UserData.Contains(UserDataKeys.DesignTimeTypeNames)) { return(statements); } Hashtable hashtable = component.UserData[UserDataKeys.DesignTimeTypeNames] as Hashtable; foreach (object obj4 in hashtable.Keys) { string str3 = null; string fullName = null; string str5 = hashtable[obj4] as string; DependencyProperty item = obj4 as DependencyProperty; if (item != null) { if (list.Contains(item)) { continue; } object[] objArray2 = item.DefaultMetadata.GetAttributes(typeof(DesignerSerializationVisibilityAttribute)); if (objArray2.Length > 0) { DesignerSerializationVisibilityAttribute attribute2 = objArray2[0] as DesignerSerializationVisibilityAttribute; if (attribute2.Visibility == DesignerSerializationVisibility.Hidden) { continue; } } str3 = item.Name; fullName = item.OwnerType.FullName; } else if (obj4 is string) { int length = ((string)obj4).LastIndexOf('.'); if (length != -1) { fullName = ((string)obj4).Substring(0, length); str3 = ((string)obj4).Substring(length + 1); } } if ((!string.IsNullOrEmpty(str5) && !string.IsNullOrEmpty(str3)) && !string.IsNullOrEmpty(fullName)) { if (fullName == obj.GetType().FullName) { CodePropertyReferenceExpression expression8 = new CodePropertyReferenceExpression(targetObject, str3); statements.Add(new CodeAssignStatement(expression8, new CodeTypeOfExpression(str5))); } else { CodeExpression expression9 = new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(fullName), str3 + "Property"); CodeExpression expression10 = new CodeTypeOfExpression(str5); statements.Add(new CodeMethodInvokeExpression(targetObject, "SetValue", new CodeExpression[] { expression9, expression10 })); } } } } finally { if (context != null) { manager.Context.Pop(); } } return(statements); }
public override object Serialize(IDesignerSerializationManager manager, object obj) { if (manager == null) { throw new ArgumentNullException("manager"); } if (manager.Context == null) { throw new ArgumentException("manager", SR.GetString(SR.Error_MissingContextProperty)); } if (obj == null) { throw new ArgumentNullException("obj"); } DependencyObject dependencyObject = obj as DependencyObject; if (dependencyObject == null) { throw new ArgumentException(SR.GetString(SR.Error_UnexpectedArgumentType, typeof(DependencyObject).FullName), "obj"); } Activity activity = obj as Activity; if (activity != null) { manager.Context.Push(activity); } CodeStatementCollection retVal = null; try { if (activity != null) { CodeDomSerializer componentSerializer = manager.GetSerializer(typeof(Component), typeof(CodeDomSerializer)) as CodeDomSerializer; if (componentSerializer == null) { throw new InvalidOperationException(SR.GetString(SR.General_MissingService, typeof(CodeDomSerializer).FullName)); } retVal = componentSerializer.Serialize(manager, activity) as CodeStatementCollection; } else { retVal = base.Serialize(manager, obj) as CodeStatementCollection; } if (retVal != null) { CodeStatementCollection codeStatements = new CodeStatementCollection(retVal); CodeExpression objectExpression = SerializeToExpression(manager, obj); if (objectExpression != null) { ArrayList propertiesSerialized = new ArrayList(); List <DependencyProperty> dependencyProperties = new List <DependencyProperty>(dependencyObject.MetaDependencyProperties); foreach (DependencyProperty dp in dependencyObject.DependencyPropertyValues.Keys) { if (dp.IsAttached) { if ((dp.IsEvent && dp.OwnerType.GetField(dp.Name + "Event", BindingFlags.Static | BindingFlags.Public | BindingFlags.DeclaredOnly) != null) || (!dp.IsEvent && dp.OwnerType.GetField(dp.Name + "Property", BindingFlags.Static | BindingFlags.Public | BindingFlags.DeclaredOnly) != null)) { dependencyProperties.Add(dp); } } } foreach (DependencyProperty dependencyProperty in dependencyProperties) { object value = null; if (dependencyObject.IsBindingSet(dependencyProperty)) { value = dependencyObject.GetBinding(dependencyProperty); } else if (!dependencyProperty.IsEvent) { value = dependencyObject.GetValue(dependencyProperty); } else { value = dependencyObject.GetHandler(dependencyProperty); } // Attached property should always be set through SetValue, no matter if it's a meta property or if there is a data context. // Other meta properties will be directly assigned. // Other instance property will go through SetValue if there is a data context or if it's of type Bind. if (value != null && (dependencyProperty.IsAttached || (!dependencyProperty.DefaultMetadata.IsMetaProperty && value is ActivityBind))) { object[] attributes = dependencyProperty.DefaultMetadata.GetAttributes(typeof(DesignerSerializationVisibilityAttribute)); if (attributes.Length > 0) { DesignerSerializationVisibilityAttribute serializationVisibilityAttribute = attributes[0] as DesignerSerializationVisibilityAttribute; if (serializationVisibilityAttribute.Visibility == DesignerSerializationVisibility.Hidden) { continue; } } // Events of type Bind will go through here. Regular events will go through IEventBindingService. CodeExpression param1 = null; string dependencyPropertyName = dependencyProperty.Name + ((dependencyProperty.IsEvent) ? "Event" : "Property"); FieldInfo fieldInfo = dependencyProperty.OwnerType.GetField(dependencyPropertyName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static); if (fieldInfo != null && !fieldInfo.IsPublic) { param1 = new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(typeof(DependencyProperty)), "FromName", new CodePrimitiveExpression(dependencyProperty.Name), new CodeTypeOfExpression(dependencyProperty.OwnerType)); } else { param1 = new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(dependencyProperty.OwnerType), dependencyPropertyName); } CodeExpression param2 = SerializeToExpression(manager, value); //Fields property fails to serialize to expression due to reference not being created, //the actual code for fields are generated in datacontext code generator so we do nothing here if (param1 != null && param2 != null) { CodeMethodInvokeExpression codeMethodInvokeExpr = null; if (value is ActivityBind) { codeMethodInvokeExpr = new CodeMethodInvokeExpression(objectExpression, "SetBinding", new CodeExpression[] { param1, new CodeCastExpression(new CodeTypeReference(typeof(ActivityBind)), param2) }); } else { codeMethodInvokeExpr = new CodeMethodInvokeExpression(objectExpression, (dependencyProperty.IsEvent) ? "AddHandler" : "SetValue", new CodeExpression[] { param1, param2 }); } retVal.Add(codeMethodInvokeExpr); // Remove the property set statement for the event which is replaced by the SetValue() expression. foreach (CodeStatement statement in codeStatements) { if (statement is CodeAssignStatement && ((CodeAssignStatement)statement).Left is CodePropertyReferenceExpression) { CodePropertyReferenceExpression prop = ((CodeAssignStatement)statement).Left as CodePropertyReferenceExpression; if (prop.PropertyName == dependencyProperty.Name && prop.TargetObject.Equals(objectExpression)) { retVal.Remove(statement); } } } } propertiesSerialized.Add(dependencyProperty); } } IEventBindingService eventBindingService = manager.GetService(typeof(IEventBindingService)) as IEventBindingService; if (eventBindingService == null) { // At compile time, we don't have an event binding service. We need to mannually emit the code to add // event handlers. foreach (EventDescriptor eventDesc in TypeDescriptor.GetEvents(dependencyObject)) { string handler = WorkflowMarkupSerializationHelpers.GetEventHandlerName(dependencyObject, eventDesc.Name); if (!string.IsNullOrEmpty(handler)) { CodeEventReferenceExpression eventRef = new CodeEventReferenceExpression(objectExpression, eventDesc.Name); CodeDelegateCreateExpression listener = new CodeDelegateCreateExpression(new CodeTypeReference(eventDesc.EventType), new CodeThisReferenceExpression(), handler); retVal.Add(new CodeAttachEventStatement(eventRef, listener)); } } } // We also need to handle properties of type System.Type. If the value is a design time type, xomlserializer // is not going to be able to deserialize the type. We then store the type name in the user data and // output a "typeof(xxx)" expression using the type name w/o validating the type. if (dependencyObject.UserData.Contains(UserDataKeys.DesignTimeTypeNames)) { Hashtable typeNames = dependencyObject.UserData[UserDataKeys.DesignTimeTypeNames] as Hashtable; foreach (object key in typeNames.Keys) { string propName = null; string ownerTypeName = null; string typeName = typeNames[key] as string; DependencyProperty dependencyProperty = key as DependencyProperty; if (dependencyProperty != null) { if (propertiesSerialized.Contains(dependencyProperty)) { continue; } object[] attributes = dependencyProperty.DefaultMetadata.GetAttributes(typeof(DesignerSerializationVisibilityAttribute)); if (attributes.Length > 0) { DesignerSerializationVisibilityAttribute serializationVisibilityAttribute = attributes[0] as DesignerSerializationVisibilityAttribute; if (serializationVisibilityAttribute.Visibility == DesignerSerializationVisibility.Hidden) { continue; } } propName = dependencyProperty.Name; ownerTypeName = dependencyProperty.OwnerType.FullName; } else if (key is string) { int indexOfDot = ((string)key).LastIndexOf('.'); Debug.Assert(indexOfDot != -1, "Wrong property name in DesignTimeTypeNames hashtable."); if (indexOfDot != -1) { ownerTypeName = ((string)key).Substring(0, indexOfDot); propName = ((string)key).Substring(indexOfDot + 1); } } if (!string.IsNullOrEmpty(typeName) && !string.IsNullOrEmpty(propName) && !string.IsNullOrEmpty(ownerTypeName)) { if (ownerTypeName == obj.GetType().FullName) { // Property is not an attached property. Serialize using regular property set expression. CodePropertyReferenceExpression propertyRef = new CodePropertyReferenceExpression(objectExpression, propName); retVal.Add(new CodeAssignStatement(propertyRef, new CodeTypeOfExpression(typeName))); } else { // This is an attached property. Serialize using SetValue() expression. CodeExpression param1 = new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(ownerTypeName), propName + "Property"); CodeExpression param2 = new CodeTypeOfExpression(typeName); retVal.Add(new CodeMethodInvokeExpression(objectExpression, "SetValue", new CodeExpression[] { param1, param2 })); } } } } } } } finally { if (activity != null) { object pushedActivity = manager.Context.Pop(); System.Diagnostics.Debug.Assert(pushedActivity == activity); } } return(retVal); }