Represents a property assignable in XAML. This can be a normal .NET property or an attached property.
예제 #1
0
 public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
 {
     if (value == null)
     {
         return(null);
     }
     if (value is string)
     {
         XamlTypeResolverProvider xamlTypeResolver = (XamlTypeResolverProvider)context.GetService(typeof(XamlTypeResolverProvider));
         if (xamlTypeResolver == null)
         {
             throw new XamlLoadException("XamlTypeResolverProvider not found in type descriptor context.");
         }
         XamlPropertyInfo prop = xamlTypeResolver.ResolveProperty((string)value);
         if (prop == null)
         {
             throw new XamlLoadException("Could not find property " + value + ".");
         }
         XamlDependencyPropertyInfo depProp = prop as XamlDependencyPropertyInfo;
         if (depProp != null)
         {
             return(depProp.DependencyProperty);
         }
         FieldInfo field = prop.TargetType.GetField(prop.Name + "Property", BindingFlags.Public | BindingFlags.Static);
         if (field != null && field.FieldType == typeof(DependencyProperty))
         {
             return((DependencyProperty)field.GetValue(null));
         }
         throw new XamlLoadException("Property " + value + " is not a dependency property.");
     }
     else
     {
         return(base.ConvertFrom(context, culture, value));
     }
 }
예제 #2
0
        /// <summary>
        /// Finds the specified property, or creates it if it doesn't exist.
        /// </summary>
        public XamlProperty FindOrCreateAttachedProperty(Type ownerType, string propertyName)
        {
            if (ownerType == null)
            {
                throw new ArgumentNullException("ownerType");
            }
            if (propertyName == null)
            {
                throw new ArgumentNullException("propertyName");
            }

            foreach (XamlProperty p in properties)
            {
                if (p.IsAttached && p.PropertyTargetType == ownerType && p.PropertyName == propertyName)
                {
                    return(p);
                }
            }
            XamlPropertyInfo info = XamlParser.TryFindAttachedProperty(ownerType, propertyName);

            if (info == null)
            {
                throw new ArgumentException("The attached property '" + propertyName + "' doesn't exist on " + ownerType.FullName, "propertyName");
            }
            XamlProperty newProperty = new XamlProperty(this, info);

            properties.Add(newProperty);
            return(newProperty);
        }
예제 #3
0
        internal static object CreateObjectFromAttributeText(string valueText, XamlPropertyInfo targetProperty, XamlObject scope)
        {
            try
            {
                if (targetProperty.ReturnType == typeof(Uri))
                {
                    return(scope.OwnerDocument.TypeFinder.ConvertUriToLocalUri(new Uri(valueText, UriKind.RelativeOrAbsolute)));
                }
                else if (targetProperty.ReturnType == typeof(ImageSource))
                {
                    var uri =
                        scope.OwnerDocument.TypeFinder.ConvertUriToLocalUri(new Uri(valueText, UriKind.RelativeOrAbsolute));
                    return(targetProperty.TypeConverter.ConvertFromString(
                               scope.OwnerDocument.GetTypeDescriptorContext(scope), CultureInfo.InvariantCulture, uri.ToString()));
                }
                if (targetProperty.ReturnType == typeof(Brush))
                {
                    return(new BrushConverter().ConvertFromString(valueText) as SolidColorBrush);
                }

                return(targetProperty.TypeConverter.ConvertFromString(
                           scope.OwnerDocument.GetTypeDescriptorContext(scope),
                           CultureInfo.InvariantCulture, valueText));
            }
            catch (Exception e) {
                IXamlErrorSink sink = (IXamlErrorSink)scope.OwnerDocument.ServiceProvider.GetService(typeof(IXamlErrorSink));
                if (sink != null)
                {
                    sink.ReportError(e.Message + " in property: " + targetProperty.FullyQualifiedName, 0, 0);
                }
            }
            return(null);
        }
예제 #4
0
        internal static XamlPropertyInfo GetPropertyInfo(XamlTypeFinder typeFinder, object elementInstance, Type elementType, string xmlNamespace, string localName, bool tryFindAllProperties = false)
        {
            string typeName, propertyName;

            SplitQualifiedIdentifier(localName, out typeName, out propertyName);
            Type propertyType = FindType(typeFinder, xmlNamespace, typeName);

            //Tries to Find All properties, even if they are not attached (For Setters, Bindings, ...)
            if (tryFindAllProperties)
            {
                XamlPropertyInfo propertyInfo = null;
                try
                {
                    propertyInfo = FindProperty(elementInstance, propertyType, propertyName);
                }
                catch (Exception)
                { }
                if (propertyInfo != null)
                {
                    return(propertyInfo);
                }
            }

            if (elementType.IsAssignableFrom(propertyType) || propertyType.IsAssignableFrom(elementType))
            {
                return(FindProperty(elementInstance, propertyType, propertyName));
            }
            else
            {
                // This is an attached property
                return(FindAttachedProperty(propertyType, propertyName));
            }
        }
예제 #5
0
        internal static void ParseObjectAttribute(XamlObject obj, XmlAttribute attribute, bool real)
        {
            XamlPropertyInfo  propertyInfo = GetPropertyInfo(obj.Instance, obj.ElementType, attribute, obj.OwnerDocument.TypeFinder);
            XamlPropertyValue value        = null;

            var valueText = attribute.Value;

            if (valueText.StartsWith("{", StringComparison.Ordinal) && !valueText.StartsWith("{}", StringComparison.Ordinal))
            {
                var xamlObject = MarkupExtensionParser.Parse(valueText, obj, real ? attribute : null);
                value = xamlObject;
            }
            else
            {
                if (real)
                {
                    value = new XamlTextValue(obj.OwnerDocument, attribute);
                }
                else
                {
                    value = new XamlTextValue(obj.OwnerDocument, valueText);
                }
            }

            var property = new XamlProperty(obj, propertyInfo, value);

            obj.AddProperty(property);
        }
예제 #6
0
        void ParseObjectContent(XamlObject obj, XmlElement element, XamlPropertyInfo defaultProperty, XamlTextValue initializeFromTextValueInsteadOfConstructor)
        {
            bool         isDefaultValueSet         = false;
            object       defaultPropertyValue      = null;
            XamlProperty defaultCollectionProperty = null;

            if (defaultProperty != null && defaultProperty.IsCollection && !element.IsEmpty)
            {
                defaultPropertyValue = defaultProperty.GetValue(obj.Instance);
                obj.AddProperty(defaultCollectionProperty = new XamlProperty(obj, defaultProperty));
            }

            foreach (XmlNode childNode in GetNormalizedChildNodes(element))
            {
                XmlElement childElement = childNode as XmlElement;
                if (childElement != null)
                {
                    if (childElement.NamespaceURI == XamlConstants.XamlNamespace)
                    {
                        continue;
                    }

                    if (ObjectChildElementIsPropertyElement(childElement))
                    {
                        ParseObjectChildElementAsPropertyElement(obj, childElement, defaultProperty, defaultPropertyValue);
                        continue;
                    }
                }
                if (initializeFromTextValueInsteadOfConstructor != null)
                {
                    continue;
                }
                XamlPropertyValue childValue = ParseValue(childNode);
                if (childValue != null)
                {
                    if (defaultProperty != null && defaultProperty.IsCollection)
                    {
                        defaultCollectionProperty.ParserAddCollectionElement(null, childValue);
                        CollectionSupport.AddToCollection(defaultProperty.ReturnType, defaultPropertyValue, childValue);
                    }
                    else
                    {
                        if (defaultProperty == null)
                        {
                            throw new XamlLoadException("This element does not have a default value, cannot assign to it");
                        }

                        if (isDefaultValueSet)
                        {
                            throw new XamlLoadException("default property may have only one value assigned");
                        }

                        obj.AddProperty(new XamlProperty(obj, defaultProperty, childValue));
                        isDefaultValueSet = true;
                    }
                }
            }
        }
예제 #7
0
		internal XamlProperty(XamlObject parentObject, XamlPropertyInfo propertyInfo)
		{
			this.parentObject = parentObject;
			this.propertyInfo = propertyInfo;
			
			if (propertyInfo.IsCollection) {
				isCollection = true;
				collectionElements = new CollectionElementsCollection(this);
			}
		}
예제 #8
0
        internal XamlProperty(XamlObject parentObject, XamlPropertyInfo propertyInfo)
        {
            this.parentObject = parentObject;
            this.propertyInfo = propertyInfo;

            if (propertyInfo.IsCollection)
            {
                isCollection       = true;
                collectionElements = new CollectionElementsCollection(this);
            }
        }
예제 #9
0
		internal override object GetValueFor(XamlPropertyInfo targetProperty)
		{
			if (IsMarkupExtension) {
				var value = ProvideValue();
				if (value is string && targetProperty != null && targetProperty.ReturnType != typeof(string)) {
					return XamlParser.CreateObjectFromAttributeText((string)value, targetProperty, this);
				}
				return value;
			} else {
				return instance;
			}
		}
예제 #10
0
		// for use by parser only
		internal XamlProperty(XamlObject parentObject, XamlPropertyInfo propertyInfo, XamlPropertyValue propertyValue)
			: this(parentObject, propertyInfo)
		{
			PossiblyNameChanged(null, propertyValue);

			this.propertyValue = propertyValue;
			if (propertyValue != null) {
				propertyValue.ParentProperty = this;
			}

			UpdateValueOnInstance();
		}
예제 #11
0
        static XamlProperty FindExistingXamlProperty(XamlObject obj, XamlPropertyInfo propertyInfo)
        {
            foreach (XamlProperty existing in obj.Properties)
            {
                if (existing.propertyInfo.FullyQualifiedName == propertyInfo.FullyQualifiedName)
                {
                    return(existing);
                }
            }

            throw new XamlLoadException("Existing XamlProperty " + propertyInfo.FullyQualifiedName + " not found.");
        }
예제 #12
0
        protected override void InsertItem(int index, XamlPropertyValue item)
        {
            XamlPropertyInfo info       = property.propertyInfo;
            object           collection = info.GetValue(property.ParentObject.Instance);

            CollectionSupport.Insert(info.ReturnType, collection, item, index);

            item.ParentProperty = property;
            property.InsertNodeInCollection(item.GetNodeForCollection(), index);

            base.InsertItem(index, item);
        }
예제 #13
0
        // for use by parser only
        internal XamlProperty(XamlObject parentObject, XamlPropertyInfo propertyInfo, XamlPropertyValue propertyValue)
            : this(parentObject, propertyInfo)
        {
            PossiblyNameChanged(null, propertyValue);

            this.propertyValue = propertyValue;
            if (propertyValue != null)
            {
                propertyValue.ParentProperty = this;
            }

            UpdateValueOnInstance();
        }
예제 #14
0
        static XamlPropertyInfo FindAttachedProperty(Type elementType, string propertyName)
        {
            XamlPropertyInfo pi = TryFindAttachedProperty(elementType, propertyName);

            if (pi != null)
            {
                return(pi);
            }
            else
            {
                throw new XamlLoadException("attached property " + elementType.Name + "." + propertyName + " not found");
            }
        }
예제 #15
0
        protected override void RemoveItem(int index)
        {
            XamlPropertyInfo info       = property.propertyInfo;
            object           collection = info.GetValue(property.ParentObject.Instance);

            if (!CollectionSupport.RemoveItemAt(info.ReturnType, collection, index))
            {
                CollectionSupport.RemoveItem(info.ReturnType, collection, this[index].GetValueFor(info));
            }

            this[index].RemoveNodeFromParent();
            this[index].ParentProperty = null;
            base.RemoveItem(index);
        }
예제 #16
0
        internal override object GetValueFor(XamlPropertyInfo targetProperty)
        {
            if (ParentProperty == null)
            {
                throw new InvalidOperationException("Cannot call GetValueFor while ParentProperty is null");
            }

            if (targetProperty == null)
            {
                return(this.Text);
            }

            return(XamlParser.CreateObjectFromAttributeText(Text, targetProperty, ParentProperty.ParentObject));
        }
예제 #17
0
		internal XamlProperty(XamlObject parentObject, XamlPropertyInfo propertyInfo)
		{
			this.parentObject = parentObject;
			this.propertyInfo = propertyInfo;
			
			if (propertyInfo.IsCollection) {
				isCollection = true;
				collectionElements = new CollectionElementsCollection(this);
				
				if (propertyInfo.Name.Equals(XamlConstants.ResourcesPropertyName, StringComparison.Ordinal) &&
				    propertyInfo.ReturnType == typeof(ResourceDictionary)) {
					isResources = true;
				}
			}
		}
예제 #18
0
        internal static object CreateObjectFromAttributeText(string valueText, XamlPropertyInfo targetProperty, XamlObject scope)
        {
            if (targetProperty.ReturnType == typeof(Uri))
            {
                return(scope.OwnerDocument.TypeFinder.ConvertUriToLocalUri(new Uri(valueText, UriKind.RelativeOrAbsolute)));
            }
            else if (targetProperty.ReturnType == typeof(ImageSource))
            {
                var uri = scope.OwnerDocument.TypeFinder.ConvertUriToLocalUri(new Uri(valueText, UriKind.RelativeOrAbsolute));
                return(targetProperty.TypeConverter.ConvertFromString(scope.OwnerDocument.GetTypeDescriptorContext(scope), CultureInfo.InvariantCulture, uri.ToString()));
            }

            return(targetProperty.TypeConverter.ConvertFromString(
                       scope.OwnerDocument.GetTypeDescriptorContext(scope),
                       CultureInfo.InvariantCulture, valueText));
        }
예제 #19
0
 internal override object GetValueFor(XamlPropertyInfo targetProperty)
 {
     if (IsMarkupExtension)
     {
         var value = ProvideValue();
         if (value is string && targetProperty != null && targetProperty.ReturnType != typeof(string))
         {
             return(XamlParser.CreateObjectFromAttributeText((string)value, targetProperty, this));
         }
         return(value);
     }
     else
     {
         return(instance);
     }
 }
예제 #20
0
        internal XamlProperty(XamlObject parentObject, XamlPropertyInfo propertyInfo)
        {
            this.parentObject = parentObject;
            this.propertyInfo = propertyInfo;

            if (propertyInfo.IsCollection)
            {
                isCollection       = true;
                collectionElements = new CollectionElementsCollection(this);

                if (propertyInfo.Name.Equals(XamlConstants.ResourcesPropertyName, StringComparison.Ordinal) &&
                    propertyInfo.ReturnType == typeof(ResourceDictionary))
                {
                    isResources = true;
                }
            }
        }
예제 #21
0
        internal static XamlPropertyInfo FindProperty(object elementInstance, Type propertyType, string propertyName)
        {
            PropertyDescriptorCollection properties;

            if (elementInstance != null)
            {
                properties = TypeDescriptor.GetProperties(elementInstance);
            }
            else
            {
                properties = TypeDescriptor.GetProperties(propertyType);
            }
            PropertyDescriptor propertyInfo = properties[propertyName];

            if (propertyInfo != null)
            {
                return(new XamlNormalPropertyInfo(propertyInfo));
            }
            else
            {
                XamlPropertyInfo pi = TryFindAttachedProperty(propertyType, propertyName);
                if (pi != null)
                {
                    return(pi);
                }
            }
            EventDescriptorCollection events;

            if (elementInstance != null)
            {
                events = TypeDescriptor.GetEvents(elementInstance);
            }
            else
            {
                events = TypeDescriptor.GetEvents(propertyType);
            }
            EventDescriptor eventInfo = events[propertyName];

            if (eventInfo != null)
            {
                return(new XamlEventPropertyInfo(eventInfo));
            }
            throw new XamlLoadException("property " + propertyName + " not found");
        }
        protected override void InsertItem(int index, XamlPropertyValue item)
        {
            XamlPropertyInfo info       = property.propertyInfo;
            object           collection = info.GetValue(property.ParentObject.Instance);

            if (!CollectionSupport.TryInsert(info.ReturnType, collection, item, index))
            {
                CollectionSupport.AddToCollection(info.ReturnType, collection, item);
            }

            item.ParentProperty = property;
            property.InsertNodeInCollection(item.GetNodeForCollection(), index);

            base.InsertItem(index, item);

            if (CollectionChanged != null)
            {
                CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, index));
            }
        }
예제 #23
0
        internal static XamlPropertyInfo FindProperty(object elementInstance, Type propertyType, string propertyName)
        {
            PropertyDescriptor propertyInfo = TypeDescriptor.GetProperties(propertyType)[propertyName];

            if (propertyInfo == null && elementInstance != null)
            {
                propertyInfo = TypeDescriptor.GetProperties(elementInstance).OfType <DependencyPropertyDescriptor>().FirstOrDefault(x => x.IsAttached && x.Name == propertyName);
            }

            if (propertyInfo != null)
            {
                return(new XamlNormalPropertyInfo(propertyInfo));
            }
            else
            {
                XamlPropertyInfo pi = TryFindAttachedProperty(propertyType, propertyName);
                if (pi != null)
                {
                    return(pi);
                }
            }
            EventDescriptorCollection events;

            if (elementInstance != null)
            {
                events = TypeDescriptor.GetEvents(elementInstance);
            }
            else
            {
                events = TypeDescriptor.GetEvents(propertyType);
            }
            EventDescriptor eventInfo = events[propertyName];

            if (eventInfo != null)
            {
                return(new XamlEventPropertyInfo(eventInfo));
            }

            throw new XamlLoadException("property " + propertyName + " not found");
        }
        protected override void RemoveItem(int index)
        {
            XamlPropertyInfo info       = property.propertyInfo;
            object           collection = info.GetValue(property.ParentObject.Instance);

            if (!CollectionSupport.RemoveItemAt(info.ReturnType, collection, index))
            {
                var propertyValue = this[index];
                CollectionSupport.RemoveItem(info.ReturnType, collection, propertyValue.GetValueFor(info), propertyValue);
            }

            var item = this[index];

            item.RemoveNodeFromParent();
            item.ParentProperty = null;
            base.RemoveItem(index);

            if (CollectionChanged != null && !isClearing)
            {
                CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item, index));
            }
        }
예제 #25
0
        void ParseObjectContent(XamlObject obj, XmlElement element, XamlPropertyInfo defaultProperty, XamlTextValue initializeFromTextValueInsteadOfConstructor)
        {
            bool isDefaultValueSet = false;

            XamlProperty collectionProperty        = null;
            object       collectionInstance        = null;
            Type         collectionType            = null;
            XmlElement   collectionPropertyElement = null;
            var          elementChildNodes         = GetNormalizedChildNodes(element);

            if (defaultProperty == null && obj.Instance != null && CollectionSupport.IsCollectionType(obj.Instance.GetType()))
            {
                XamlObject       parentObj     = obj.ParentObject;
                var              parentElement = element.ParentNode;
                XamlPropertyInfo propertyInfo  = GetPropertyInfo(settings.TypeFinder, parentObj.Instance, parentObj.ElementType, parentElement.NamespaceURI, parentElement.LocalName);
                collectionProperty        = FindExistingXamlProperty(parentObj, propertyInfo);
                collectionInstance        = obj.Instance;
                collectionType            = obj.ElementType;
                collectionPropertyElement = element;
            }
            else if (defaultProperty != null && defaultProperty.IsCollection && !element.IsEmpty)
            {
                foreach (XmlNode childNode in elementChildNodes)
                {
                    XmlElement childElement = childNode as XmlElement;
                    if (childElement == null || !ObjectChildElementIsPropertyElement(childElement))
                    {
                        obj.AddProperty(collectionProperty = new XamlProperty(obj, defaultProperty));
                        collectionType     = defaultProperty.ReturnType;
                        collectionInstance = defaultProperty.GetValue(obj.Instance);
                        break;
                    }
                }
            }

            foreach (XmlNode childNode in elementChildNodes)
            {
                XmlElement childElement = childNode as XmlElement;
                if (childElement != null)
                {
                    if (childElement.NamespaceURI == XamlConstants.XamlNamespace)
                    {
                        continue;
                    }

                    if (ObjectChildElementIsPropertyElement(childElement))
                    {
                        ParseObjectChildElementAsPropertyElement(obj, childElement, defaultProperty);
                        continue;
                    }
                }
                if (initializeFromTextValueInsteadOfConstructor != null)
                {
                    continue;
                }
                XamlPropertyValue childValue = ParseValue(childNode);
                if (childValue != null)
                {
                    if (collectionProperty != null)
                    {
                        collectionProperty.ParserAddCollectionElement(collectionPropertyElement, childValue);
                        CollectionSupport.AddToCollection(collectionType, collectionInstance, childValue);
                    }
                    else
                    {
                        if (defaultProperty == null)
                        {
                            throw new XamlLoadException("This element does not have a default value, cannot assign to it");
                        }

                        if (isDefaultValueSet)
                        {
                            throw new XamlLoadException("default property may have only one value assigned");
                        }

                        obj.AddProperty(new XamlProperty(obj, defaultProperty, childValue));
                        isDefaultValueSet = true;
                    }
                }
            }
        }
예제 #26
0
        XamlObject ParseObject(XmlElement element)
        {
            Type elementType = settings.TypeFinder.GetType(element.NamespaceURI, element.LocalName);

            if (elementType == null)
            {
                elementType = settings.TypeFinder.GetType(element.NamespaceURI, element.LocalName + "Extension");
                if (elementType == null)
                {
                    throw new XamlLoadException("Cannot find type " + element.Name);
                }
            }

            XmlSpace   oldXmlSpace      = currentXmlSpace;
            XamlObject parentXamlObject = currentXamlObject;

            if (element.HasAttribute("xml:space"))
            {
                currentXmlSpace = (XmlSpace)Enum.Parse(typeof(XmlSpace), element.GetAttribute("xml:space"), true);
            }

            XamlPropertyInfo defaultProperty = GetDefaultProperty(elementType);

            XamlTextValue initializeFromTextValueInsteadOfConstructor = null;

            if (defaultProperty == null)
            {
                int  numberOfTextNodes = 0;
                bool onlyTextNodes     = true;
                foreach (XmlNode childNode in element.ChildNodes)
                {
                    if (childNode.NodeType == XmlNodeType.Text)
                    {
                        numberOfTextNodes++;
                    }
                    else if (childNode.NodeType == XmlNodeType.Element)
                    {
                        onlyTextNodes = false;
                    }
                }
                if (onlyTextNodes && numberOfTextNodes == 1)
                {
                    foreach (XmlNode childNode in element.ChildNodes)
                    {
                        if (childNode.NodeType == XmlNodeType.Text)
                        {
                            initializeFromTextValueInsteadOfConstructor = (XamlTextValue)ParseValue(childNode);
                        }
                    }
                }
            }

            object instance;

            if (initializeFromTextValueInsteadOfConstructor != null)
            {
                instance = TypeDescriptor.GetConverter(elementType).ConvertFromString(
                    document.GetTypeDescriptorContext(null),
                    CultureInfo.InvariantCulture,
                    initializeFromTextValueInsteadOfConstructor.Text);
            }
            else
            {
                instance = settings.CreateInstanceCallback(elementType, emptyObjectArray);
            }

            XamlObject obj = new XamlObject(document, element, elementType, instance);

            currentXamlObject = obj;
            obj.ParentObject  = parentXamlObject;

            if (parentXamlObject == null && obj.Instance is DependencyObject)
            {
                NameScope.SetNameScope((DependencyObject)obj.Instance, new NameScope());
            }

            ISupportInitialize iSupportInitializeInstance = instance as ISupportInitialize;

            if (iSupportInitializeInstance != null)
            {
                iSupportInitializeInstance.BeginInit();
            }

            foreach (XmlAttribute attribute in element.Attributes)
            {
                if (attribute.Value.StartsWith("clr-namespace", StringComparison.OrdinalIgnoreCase))
                {
                    // the format is "clr-namespace:<Namespace here>;assembly=<Assembly name here>"
                    var clrNamespace = attribute.Value.Split(new[] { ':', ';', '=' });
                    if (clrNamespace.Length == 4)
                    {
                        // get the assembly name
                        var assembly = settings.TypeFinder.LoadAssembly(clrNamespace[3]);
                        if (assembly != null)
                        {
                            settings.TypeFinder.RegisterAssembly(assembly);
                        }
                    }
                    else
                    {
                        // if no assembly name is there, then load the assembly of the opened file.
                        var assembly = settings.TypeFinder.LoadAssembly(null);
                        if (assembly != null)
                        {
                            settings.TypeFinder.RegisterAssembly(assembly);
                        }
                    }
                }
                if (attribute.NamespaceURI == XamlConstants.XmlnsNamespace)
                {
                    continue;
                }
                if (attribute.Name == "xml:space")
                {
                    continue;
                }
                if (GetAttributeNamespace(attribute) == XamlConstants.XamlNamespace)
                {
                    if (attribute.LocalName == "Name")
                    {
                        try {
                            NameScopeHelper.NameChanged(obj, null, attribute.Value);
                        } catch (Exception x) {
                            ReportException(x, attribute);
                        }
                    }
                    continue;
                }

                ParseObjectAttribute(obj, attribute);
            }

            if (!(obj.Instance is Style))
            {
                ParseObjectContent(obj, element, defaultProperty, initializeFromTextValueInsteadOfConstructor);
            }

            if (iSupportInitializeInstance != null)
            {
                iSupportInitializeInstance.EndInit();
            }

            currentXmlSpace   = oldXmlSpace;
            currentXamlObject = parentXamlObject;

            return(obj);
        }
예제 #27
0
        static bool IsElementChildACollectionForProperty(XamlTypeFinder typeFinder, XmlElement element, XamlPropertyInfo propertyInfo)
        {
            var nodes = element.ChildNodes.Cast <XmlNode>().Where(x => !(x is XmlWhitespace)).ToList();

            return(nodes.Count == 1 && propertyInfo.ReturnType.IsAssignableFrom(FindType(typeFinder, nodes[0].NamespaceURI, nodes[0].LocalName)));
        }
예제 #28
0
		void ParseObjectContent(XamlObject obj, XmlElement element, XamlPropertyInfo defaultProperty, XamlTextValue initializeFromTextValueInsteadOfConstructor)
		{
			bool isDefaultValueSet = false;
			
			XamlProperty collectionProperty = null;
			object collectionInstance = null;
			Type collectionType = null;
			XmlElement collectionPropertyElement = null;
			var elementChildNodes = GetNormalizedChildNodes(element);
			
			if (defaultProperty == null && obj.Instance != null && CollectionSupport.IsCollectionType(obj.Instance.GetType())) {
				XamlObject parentObj = obj.ParentObject;
				var parentElement = element.ParentNode;
				XamlPropertyInfo propertyInfo;
				if (parentObj != null) {
					propertyInfo = GetPropertyInfo(settings.TypeFinder, parentObj.Instance, parentObj.ElementType, parentElement.NamespaceURI, parentElement.LocalName);
					collectionProperty = FindExistingXamlProperty(parentObj, propertyInfo);
				}
				collectionInstance = obj.Instance;
				collectionType = obj.ElementType;
				collectionPropertyElement = element;
			} else if (defaultProperty != null && defaultProperty.IsCollection && !element.IsEmpty) {
				foreach (XmlNode childNode in elementChildNodes) {
					currentParsedNode = childNode;
					XmlElement childElement = childNode as XmlElement;
					if (childElement == null || !ObjectChildElementIsPropertyElement(childElement)) {
						obj.AddProperty(collectionProperty = new XamlProperty(obj, defaultProperty));
						collectionType = defaultProperty.ReturnType;
						collectionInstance = defaultProperty.GetValue(obj.Instance);
						break;
					}
				}
			}

			currentParsedNode = element;

			if (collectionType != null && collectionInstance == null && elementChildNodes.Count() == 1)
			{
				var firstChild = elementChildNodes.First() as XmlElement;
				if (ObjectChildElementIsCollectionInstance(firstChild, collectionType))
				{
					collectionInstance = ParseObject(firstChild);
					collectionProperty.PropertyValue = (XamlPropertyValue) collectionInstance;
				}
				else
				{
					throw new XamlLoadException("Collection Instance is null");
				}
			}
			else
			{
				foreach (XmlNode childNode in elementChildNodes) {
					currentParsedNode = childNode;
					XmlElement childElement = childNode as XmlElement;
					if (childElement != null) {
						if (childElement.NamespaceURI == XamlConstants.XamlNamespace)
							continue;
						
						if (ObjectChildElementIsPropertyElement(childElement)) {
							ParseObjectChildElementAsPropertyElement(obj, childElement, defaultProperty);
							continue;
						}
					}
					if (initializeFromTextValueInsteadOfConstructor != null)
						continue;
					XamlPropertyValue childValue = ParseValue(childNode);
					if (childValue != null) {
						if (collectionProperty != null) {
							collectionProperty.ParserAddCollectionElement(collectionPropertyElement, childValue);
							CollectionSupport.AddToCollection(collectionType, collectionInstance, childValue);
						} else {
							if (defaultProperty == null)
								throw new XamlLoadException("This element does not have a default value, cannot assign to it");
							
							if (isDefaultValueSet)
								throw new XamlLoadException("default property may have only one value assigned");
							
							obj.AddProperty(new XamlProperty(obj, defaultProperty, childValue));
							isDefaultValueSet = true;
						}
					}
				}
			}

			currentParsedNode = element;
		}
예제 #29
0
        void ParseObjectContent(XamlObject obj, XmlElement element, XamlPropertyInfo defaultProperty, XamlTextValue initializeFromTextValueInsteadOfConstructor)
        {
            XamlPropertyValue setDefaultValueTo         = null;
            object            defaultPropertyValue      = null;
            XamlProperty      defaultCollectionProperty = null;

            if (defaultProperty != null && defaultProperty.IsCollection && !element.IsEmpty)
            {
                defaultPropertyValue = defaultProperty.GetValue(obj.Instance);
                obj.AddProperty(defaultCollectionProperty = new XamlProperty(obj, defaultProperty));
            }

            foreach (XmlNode childNode in GetNormalizedChildNodes(element))
            {
                // I don't know why the official XamlReader runs the property getter
                // here, but let's try to imitate it as good as possible
                if (defaultProperty != null && !defaultProperty.IsCollection)
                {
                    for (; combinedNormalizedChildNodes > 0; combinedNormalizedChildNodes--)
                    {
                        defaultProperty.GetValue(obj.Instance);
                    }
                }

                XmlElement childElement = childNode as XmlElement;
                if (childElement != null)
                {
                    if (childElement.NamespaceURI == XamlConstants.XamlNamespace)
                    {
                        continue;
                    }

                    if (ObjectChildElementIsPropertyElement(childElement))
                    {
                        // I don't know why the official XamlReader runs the property getter
                        // here, but let's try to imitate it as good as possible
                        if (defaultProperty != null && !defaultProperty.IsCollection)
                        {
                            defaultProperty.GetValue(obj.Instance);
                        }
                        ParseObjectChildElementAsPropertyElement(obj, childElement, defaultProperty, defaultPropertyValue);
                        continue;
                    }
                }
                if (initializeFromTextValueInsteadOfConstructor != null)
                {
                    continue;
                }
                XamlPropertyValue childValue = ParseValue(childNode);
                if (childValue != null)
                {
                    if (defaultProperty != null && defaultProperty.IsCollection)
                    {
                        defaultCollectionProperty.ParserAddCollectionElement(null, childValue);
                        CollectionSupport.AddToCollection(defaultProperty.ReturnType, defaultPropertyValue, childValue);
                    }
                    else
                    {
                        if (setDefaultValueTo != null)
                        {
                            throw new XamlLoadException("default property may have only one value assigned");
                        }
                        setDefaultValueTo = childValue;
                    }
                }
            }

            if (defaultProperty != null && !defaultProperty.IsCollection && !element.IsEmpty)
            {
                // Runs even when defaultValueSet==false!
                // Again, no idea why the official XamlReader does this.
                defaultProperty.GetValue(obj.Instance);
            }
            if (setDefaultValueTo != null)
            {
                if (defaultProperty == null)
                {
                    throw new XamlLoadException("This element does not have a default value, cannot assign to it");
                }
                obj.AddProperty(new XamlProperty(obj, defaultProperty, setDefaultValueTo));
            }
        }
예제 #30
0
		/// <summary>
		/// used internally by the XamlParser.
		/// </summary>
		internal abstract object GetValueFor(XamlPropertyInfo targetProperty);
예제 #31
0
		static bool IsElementChildACollectionForProperty(XamlTypeFinder typeFinder, XmlElement element, XamlPropertyInfo propertyInfo)
		{
			return element.ChildNodes.Count == 1 && propertyInfo.ReturnType.IsAssignableFrom(FindType(typeFinder, element.FirstChild.NamespaceURI, element.FirstChild.LocalName));
		}
예제 #32
0
		internal static object CreateObjectFromAttributeText(string valueText, XamlPropertyInfo targetProperty, XamlObject scope)
		{
			return targetProperty.TypeConverter.ConvertFromString(
				scope.OwnerDocument.GetTypeDescriptorContext(scope),
				CultureInfo.InvariantCulture, valueText);
		}
예제 #33
0
		static XamlProperty FindExistingXamlProperty(XamlObject obj, XamlPropertyInfo propertyInfo)
		{
			foreach (XamlProperty existing in obj.Properties) {
				if (existing.propertyInfo.FullyQualifiedName == propertyInfo.FullyQualifiedName)
					return existing;
			}

			throw new XamlLoadException("Existing XamlProperty " + propertyInfo.FullyQualifiedName + " not found.");
		}
예제 #34
0
		internal override object GetValueFor(XamlPropertyInfo targetProperty)
		{
			if (ParentProperty == null)
				throw new InvalidOperationException("Cannot call GetValueFor while ParentProperty is null");
			
			if (targetProperty == null)
				return this.Text;

			return XamlParser.CreateObjectFromAttributeText(Text, targetProperty, ParentProperty.ParentObject);
		}
예제 #35
0
 static bool IsElementChildACollectionForProperty(XamlTypeFinder typeFinder, XmlElement element, XamlPropertyInfo propertyInfo)
 {
     return(element.ChildNodes.Count == 1 && propertyInfo.ReturnType.IsAssignableFrom(FindType(typeFinder, element.FirstChild.NamespaceURI, element.FirstChild.LocalName)));
 }
예제 #36
0
 internal static object CreateObjectFromAttributeText(string valueText, XamlPropertyInfo targetProperty, XamlObject scope)
 {
     return(targetProperty.TypeConverter.ConvertFromString(
                scope.OwnerDocument.GetTypeDescriptorContext(scope),
                CultureInfo.InvariantCulture, valueText));
 }
예제 #37
0
 /// <summary>
 /// used internally by the XamlParser.
 /// </summary>
 internal abstract object GetValueFor(XamlPropertyInfo targetProperty);
예제 #38
0
		static bool IsElementChildACollectionForProperty(XamlTypeFinder typeFinder, XmlElement element, XamlPropertyInfo propertyInfo)
		{
			var nodes = element.ChildNodes.Cast<XmlNode>().Where(x => !(x is XmlWhitespace)).ToList();
			return nodes.Count == 1 && propertyInfo.ReturnType.IsAssignableFrom(FindType(typeFinder, nodes[0].NamespaceURI, nodes[0].LocalName));
		}
예제 #39
0
		void ParseObjectContent(XamlObject obj, XmlElement element, XamlPropertyInfo defaultProperty, XamlTextValue initializeFromTextValueInsteadOfConstructor)
		{
			XamlPropertyValue setDefaultValueTo = null;
			object defaultPropertyValue = null;
			XamlProperty defaultCollectionProperty = null;
			
			if (defaultProperty != null && defaultProperty.IsCollection && !element.IsEmpty) {
				defaultPropertyValue = defaultProperty.GetValue(obj.Instance);
				obj.AddProperty(defaultCollectionProperty = new XamlProperty(obj, defaultProperty));
			}
			
			foreach (XmlNode childNode in GetNormalizedChildNodes(element)) {
				
				// I don't know why the official XamlReader runs the property getter
				// here, but let's try to imitate it as good as possible
				if (defaultProperty != null && !defaultProperty.IsCollection) {
					for (; combinedNormalizedChildNodes > 0; combinedNormalizedChildNodes--) {
						defaultProperty.GetValue(obj.Instance);
					}
				}
				
				XmlElement childElement = childNode as XmlElement;
				if (childElement != null) {
					if (childElement.NamespaceURI == XamlConstants.XamlNamespace)
						continue;
					
					if (ObjectChildElementIsPropertyElement(childElement)) {
						// I don't know why the official XamlReader runs the property getter
						// here, but let's try to imitate it as good as possible
						if (defaultProperty != null && !defaultProperty.IsCollection) {
							defaultProperty.GetValue(obj.Instance);
						}
						ParseObjectChildElementAsPropertyElement(obj, childElement, defaultProperty, defaultPropertyValue);
						continue;
					}
				}
				if (initializeFromTextValueInsteadOfConstructor != null)
					continue;
				XamlPropertyValue childValue = ParseValue(childNode);
				if (childValue != null) {
					if (defaultProperty != null && defaultProperty.IsCollection) {
						defaultCollectionProperty.ParserAddCollectionElement(null, childValue);
						CollectionSupport.AddToCollection(defaultProperty.ReturnType, defaultPropertyValue, childValue);
					} else {
						if (setDefaultValueTo != null)
							throw new XamlLoadException("default property may have only one value assigned");
						setDefaultValueTo = childValue;
					}
				}
			}
			
			if (defaultProperty != null && !defaultProperty.IsCollection && !element.IsEmpty) {
				// Runs even when defaultValueSet==false!
				// Again, no idea why the official XamlReader does this.
				defaultProperty.GetValue(obj.Instance);
			}
			if (setDefaultValueTo != null) {
				if (defaultProperty == null) {
					throw new XamlLoadException("This element does not have a default value, cannot assign to it");
				}
				obj.AddProperty(new XamlProperty(obj, defaultProperty, setDefaultValueTo));
			}
		}
예제 #40
0
        void ParseObjectChildElementAsPropertyElement(XamlObject obj, XmlElement element, XamlPropertyInfo defaultProperty)
        {
            Debug.Assert(element.LocalName.Contains("."));
            // this is a element property syntax

            XamlPropertyInfo propertyInfo = GetPropertyInfo(settings.TypeFinder, obj.Instance, obj.ElementType, element.NamespaceURI, element.LocalName);
            bool             valueWasSet  = false;

            object       collectionInstance = null;
            bool         isElementChildACollectionForProperty = false;
            XamlProperty collectionProperty = null;

            if (propertyInfo.IsCollection)
            {
                if (defaultProperty != null && defaultProperty.FullyQualifiedName == propertyInfo.FullyQualifiedName)
                {
                    foreach (XamlProperty existing in obj.Properties)
                    {
                        if (existing.propertyInfo == defaultProperty)
                        {
                            collectionProperty = existing;
                            break;
                        }
                    }
                }

                if (collectionProperty == null)
                {
                    obj.AddProperty(collectionProperty = new XamlProperty(obj, propertyInfo));
                }

                isElementChildACollectionForProperty = IsElementChildACollectionForProperty(settings.TypeFinder, element, propertyInfo);
                if (isElementChildACollectionForProperty)
                {
                    collectionProperty.ParserSetPropertyElement((XmlElement)element.FirstChild);
                }
                else
                {
                    collectionInstance = collectionProperty.propertyInfo.GetValue(obj.Instance);
                    collectionProperty.ParserSetPropertyElement(element);
                }
            }

            XmlSpace oldXmlSpace = currentXmlSpace;

            if (element.HasAttribute("xml:space"))
            {
                currentXmlSpace = (XmlSpace)Enum.Parse(typeof(XmlSpace), element.GetAttribute("xml:space"), true);
            }

            foreach (XmlNode childNode in element.ChildNodes)
            {
                XamlPropertyValue childValue = ParseValue(childNode);
                if (childValue != null)
                {
                    if (propertyInfo.IsCollection)
                    {
                        if (isElementChildACollectionForProperty)
                        {
                            collectionProperty.PropertyValue = childValue;
                        }
                        else
                        {
                            CollectionSupport.AddToCollection(propertyInfo.ReturnType, collectionInstance, childValue);
                            collectionProperty.ParserAddCollectionElement(element, childValue);
                        }
                    }
                    else
                    {
                        if (valueWasSet)
                        {
                            throw new XamlLoadException("non-collection property may have only one child element");
                        }
                        valueWasSet = true;
                        XamlProperty xp = new XamlProperty(obj, propertyInfo, childValue);
                        xp.ParserSetPropertyElement(element);
                        obj.AddProperty(xp);
                    }
                }
            }

            currentXmlSpace = oldXmlSpace;
        }
예제 #41
0
		void ParseObjectChildElementAsPropertyElement(XamlObject obj, XmlElement element, XamlPropertyInfo defaultProperty)
		{
			Debug.Assert(element.LocalName.Contains("."));
			// this is a element property syntax
			
			XamlPropertyInfo propertyInfo = GetPropertyInfo(settings.TypeFinder, obj.Instance, obj.ElementType, element.NamespaceURI, element.LocalName);
			bool valueWasSet = false;
			
			object collectionInstance = null;
			bool isElementChildACollectionForProperty = false;
			XamlProperty collectionProperty = null;
			if (propertyInfo.IsCollection) {
				if (defaultProperty != null && defaultProperty.FullyQualifiedName == propertyInfo.FullyQualifiedName) {
					foreach (XamlProperty existing in obj.Properties) {
						if (existing.propertyInfo == defaultProperty) {
							collectionProperty = existing;
							break;
						}
					}
				}
				
				if (collectionProperty == null) {
					obj.AddProperty(collectionProperty = new XamlProperty(obj, propertyInfo));
				}
				
				isElementChildACollectionForProperty = IsElementChildACollectionForProperty(settings.TypeFinder, element, propertyInfo);
				if (isElementChildACollectionForProperty)
					collectionProperty.ParserSetPropertyElement((XmlElement)element.ChildNodes.Cast<XmlNode>().Where(x => !(x is XmlWhitespace)).First());
				else {
					collectionInstance = collectionProperty.propertyInfo.GetValue(obj.Instance);
					collectionProperty.ParserSetPropertyElement(element);
					collectionInstance = collectionInstance ?? Activator.CreateInstance(collectionProperty.propertyInfo.ReturnType);
				}
			}
			
			XmlSpace oldXmlSpace = currentXmlSpace;
			if (element.HasAttribute("xml:space")) {
				currentXmlSpace = (XmlSpace)Enum.Parse(typeof(XmlSpace), element.GetAttribute("xml:space"), true);
			}
			
			foreach (XmlNode childNode in element.ChildNodes) {
				currentParsedNode = childNode;
				XamlPropertyValue childValue = ParseValue(childNode);
				if (childValue != null) {
					if (propertyInfo.IsCollection) {
						if (isElementChildACollectionForProperty) {
							collectionProperty.PropertyValue = childValue;
						}
						else {
							CollectionSupport.AddToCollection(propertyInfo.ReturnType, collectionInstance, childValue);
							collectionProperty.ParserAddCollectionElement(element, childValue);
						}
					} else {
						if (valueWasSet)
							throw new XamlLoadException("non-collection property may have only one child element");
						valueWasSet = true;
						XamlProperty xp = new XamlProperty(obj, propertyInfo, childValue);
						xp.ParserSetPropertyElement(element);
						obj.AddProperty(xp);
					}
				}
			}

			currentParsedNode = element;

			currentXmlSpace = oldXmlSpace;
		}
예제 #42
0
		internal static object CreateObjectFromAttributeText(string valueText, XamlPropertyInfo targetProperty, XamlObject scope)
		{
			if (targetProperty.ReturnType == typeof(Uri)) {
				return scope.OwnerDocument.TypeFinder.ConvertUriToLocalUri(new Uri(valueText, UriKind.RelativeOrAbsolute));
			} else if (targetProperty.ReturnType == typeof(ImageSource)) {
				var uri = scope.OwnerDocument.TypeFinder.ConvertUriToLocalUri(new Uri(valueText, UriKind.RelativeOrAbsolute));
				return targetProperty.TypeConverter.ConvertFromString(scope.OwnerDocument.GetTypeDescriptorContext(scope), CultureInfo.InvariantCulture, uri.ToString());
			}

			return targetProperty.TypeConverter.ConvertFromString(
				scope.OwnerDocument.GetTypeDescriptorContext(scope),
				CultureInfo.InvariantCulture, valueText);
		}
예제 #43
0
		void ParseObjectContent(XamlObject obj, XmlElement element, XamlPropertyInfo defaultProperty, XamlTextValue initializeFromTextValueInsteadOfConstructor)
		{
			bool isDefaultValueSet = false;
			object defaultPropertyValue = null;
			XamlProperty defaultCollectionProperty = null;
			
			if (defaultProperty != null && defaultProperty.IsCollection && !element.IsEmpty) {
				defaultPropertyValue = defaultProperty.GetValue(obj.Instance);
				obj.AddProperty(defaultCollectionProperty = new XamlProperty(obj, defaultProperty));
			}
			
			foreach (XmlNode childNode in GetNormalizedChildNodes(element)) {
				XmlElement childElement = childNode as XmlElement;
				if (childElement != null) {
					if (childElement.NamespaceURI == XamlConstants.XamlNamespace)
						continue;
					
					if (ObjectChildElementIsPropertyElement(childElement)) {
						ParseObjectChildElementAsPropertyElement(obj, childElement, defaultProperty, defaultPropertyValue);
						continue;
					}
				}
				if (initializeFromTextValueInsteadOfConstructor != null)
					continue;
				XamlPropertyValue childValue = ParseValue(childNode);
				if (childValue != null) {
					if (defaultProperty != null && defaultProperty.IsCollection) {
						defaultCollectionProperty.ParserAddCollectionElement(null, childValue);
						CollectionSupport.AddToCollection(defaultProperty.ReturnType, defaultPropertyValue, childValue);
					} else {
						if (defaultProperty == null)
							throw new XamlLoadException("This element does not have a default value, cannot assign to it");
						
						if (isDefaultValueSet)
							throw new XamlLoadException("default property may have only one value assigned");
						
						obj.AddProperty(new XamlProperty(obj, defaultProperty, childValue));
						isDefaultValueSet = true;
					}
				}
			}
		}