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);
        }
Пример #2
0
        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);
        }