|
|
|
@ -285,22 +285,41 @@ namespace ICSharpCode.WpfDesign.XamlDom
@@ -285,22 +285,41 @@ namespace ICSharpCode.WpfDesign.XamlDom
|
|
|
|
|
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)); |
|
|
|
|
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 GetNormalizedChildNodes(element)) { |
|
|
|
|
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, defaultPropertyValue); |
|
|
|
|
ParseObjectChildElementAsPropertyElement(obj, childElement, defaultProperty); |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -308,9 +327,9 @@ namespace ICSharpCode.WpfDesign.XamlDom
@@ -308,9 +327,9 @@ namespace ICSharpCode.WpfDesign.XamlDom
|
|
|
|
|
continue; |
|
|
|
|
XamlPropertyValue childValue = ParseValue(childNode); |
|
|
|
|
if (childValue != null) { |
|
|
|
|
if (defaultProperty != null && defaultProperty.IsCollection) { |
|
|
|
|
defaultCollectionProperty.ParserAddCollectionElement(null, childValue); |
|
|
|
|
CollectionSupport.AddToCollection(defaultProperty.ReturnType, defaultPropertyValue, childValue); |
|
|
|
|
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"); |
|
|
|
@ -386,6 +405,16 @@ namespace ICSharpCode.WpfDesign.XamlDom
@@ -386,6 +405,16 @@ namespace ICSharpCode.WpfDesign.XamlDom
|
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
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."); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static XamlPropertyInfo GetDefaultProperty(Type elementType) |
|
|
|
|
{ |
|
|
|
|
foreach (ContentPropertyAttribute cpa in elementType.GetCustomAttributes(typeof(ContentPropertyAttribute), true)) { |
|
|
|
@ -531,7 +560,12 @@ namespace ICSharpCode.WpfDesign.XamlDom
@@ -531,7 +560,12 @@ namespace ICSharpCode.WpfDesign.XamlDom
|
|
|
|
|
return element.LocalName.Contains("."); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ParseObjectChildElementAsPropertyElement(XamlObject obj, XmlElement element, XamlPropertyInfo defaultProperty, object defaultPropertyValue) |
|
|
|
|
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)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ParseObjectChildElementAsPropertyElement(XamlObject obj, XmlElement element, XamlPropertyInfo defaultProperty) |
|
|
|
|
{ |
|
|
|
|
Debug.Assert(element.LocalName.Contains(".")); |
|
|
|
|
// this is a element property syntax
|
|
|
|
@ -540,23 +574,29 @@ namespace ICSharpCode.WpfDesign.XamlDom
@@ -540,23 +574,29 @@ namespace ICSharpCode.WpfDesign.XamlDom
|
|
|
|
|
bool valueWasSet = false; |
|
|
|
|
|
|
|
|
|
object collectionInstance = null; |
|
|
|
|
bool isElementChildACollectionForProperty = false; |
|
|
|
|
XamlProperty collectionProperty = null; |
|
|
|
|
if (propertyInfo.IsCollection) { |
|
|
|
|
if (defaultProperty != null && defaultProperty.FullyQualifiedName == propertyInfo.FullyQualifiedName) { |
|
|
|
|
collectionInstance = defaultPropertyValue; |
|
|
|
|
foreach (XamlProperty existing in obj.Properties) { |
|
|
|
|
if (existing.propertyInfo == defaultProperty) { |
|
|
|
|
collectionProperty = existing; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
collectionInstance = propertyInfo.GetValue(obj.Instance); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (collectionProperty == null) { |
|
|
|
|
obj.AddProperty(collectionProperty = new XamlProperty(obj, propertyInfo)); |
|
|
|
|
} |
|
|
|
|
collectionProperty.ParserSetPropertyElement(element); |
|
|
|
|
|
|
|
|
|
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; |
|
|
|
@ -568,7 +608,10 @@ namespace ICSharpCode.WpfDesign.XamlDom
@@ -568,7 +608,10 @@ namespace ICSharpCode.WpfDesign.XamlDom
|
|
|
|
|
XamlPropertyValue childValue = ParseValue(childNode); |
|
|
|
|
if (childValue != null) { |
|
|
|
|
if (propertyInfo.IsCollection) { |
|
|
|
|
if (collectionInstance!=null) { |
|
|
|
|
if (isElementChildACollectionForProperty) { |
|
|
|
|
collectionProperty.PropertyValue = childValue; |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
CollectionSupport.AddToCollection(propertyInfo.ReturnType, collectionInstance, childValue); |
|
|
|
|
collectionProperty.ParserAddCollectionElement(element, childValue); |
|
|
|
|
} |
|
|
|
|