/// <summary> /// Adds a value to the end of a collection. /// </summary> public static void AddToCollection(Type collectionType, object collectionInstance, XamlPropertyValue newElement) { IAddChild addChild = collectionInstance as IAddChild; if (addChild != null) { if (newElement is XamlTextValue) { addChild.AddText((string)newElement.GetValueFor(null)); } else { addChild.AddChild(newElement.GetValueFor(null)); } } else if (collectionInstance is IDictionary) { object val = newElement.GetValueFor(null); object key = newElement is XamlObject ? ((XamlObject)newElement).GetXamlAttribute("Key") : null; //if (key == null || key == "") { // if (val is Style) // key = ((Style)val).TargetType; //} if (key == null || (key as string) == "") key = val; ((IDictionary)collectionInstance).Add(key, val); } else { collectionType.InvokeMember( "Add", BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Instance, null, collectionInstance, new object[] { newElement.GetValueFor(null) }, CultureInfo.InvariantCulture); } }
void PossiblyNameChanged(XamlPropertyValue oldValue, XamlPropertyValue newValue) { if (ParentObject.RuntimeNameProperty != null && PropertyName == ParentObject.RuntimeNameProperty) { if (!String.IsNullOrEmpty(ParentObject.GetXamlAttribute("Name"))) { throw new XamlLoadException("The property 'Name' is set more than once."); } string oldName = null; string newName = null; var oldTextValue = oldValue as XamlTextValue; if (oldTextValue != null) { oldName = oldTextValue.Text; } var newTextValue = newValue as XamlTextValue; if (newTextValue != null) { newName = newTextValue.Text; } NameScopeHelper.NameChanged(ParentObject, oldName, newName); } }
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); }
private static void AppendPropertyValue(StringBuilder sb, XamlPropertyValue value, bool isStringProperty) { var textValue = value as XamlTextValue; if (textValue != null) { string text = textValue.Text; bool containsSpace = text.Contains(' '); if (containsSpace) { sb.Append('\''); } if (isStringProperty) { sb.Append(text.Replace("\\", "\\\\").Replace("{", "\\{").Replace("}", "\\}")); } else { sb.Append(text.Replace("\\", "\\\\")); } if (containsSpace) { sb.Append('\''); } } else if (value is XamlObject) { sb.Append(Print(value as XamlObject)); } }
/// <summary> /// Adds a value at the specified index in the collection. /// </summary> public static void Insert(Type collectionType, object collectionInstance, XamlPropertyValue newElement, int index) { collectionType.InvokeMember( "Insert", BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Instance, null, collectionInstance, new object[] { index, newElement.GetValueFor(null) }, CultureInfo.InvariantCulture); }
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; } } } }
// 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(); }
void ResetInternal() { if (propertyValue != null) { propertyValue.RemoveNodeFromParent(); propertyValue.ParentProperty = null; propertyValue = null; } if (_propertyElement != null) { _propertyElement.ParentNode.RemoveChild(_propertyElement); _propertyElement = null; } }
void PossiblyNameChanged(XamlPropertyValue oldValue, XamlPropertyValue newValue) { if (PropertyName == "Name" && ReturnType == typeof(string)) { string oldName = null; string newName = null; var oldTextValue = oldValue as XamlTextValue; if (oldTextValue != null) { oldName = oldTextValue.Text; } var newTextValue = newValue as XamlTextValue; if (newTextValue != null) { newName = newTextValue.Text; } var obj = ParentObject; while (obj != null) { var nameScope = obj.Instance as INameScope; if (nameScope == null) { if (obj.Instance is DependencyObject) { nameScope = NameScope.GetNameScope((DependencyObject)obj.Instance); } } if (nameScope != null) { if (oldName != null) { try { nameScope.UnregisterName(oldName); } catch (Exception x) { Debug.WriteLine(x.Message); } } if (newName != null) { nameScope.RegisterName(newName, ParentObject.Instance); } break; } obj = obj.ParentObject; } } }
/// <summary> /// Adds a value at the specified index in the collection. /// </summary> public static bool Insert(Type collectionType, object collectionInstance, XamlPropertyValue newElement, int index) { var hasInsert = collectionType.GetMethods().Any(x => x.Name == "Insert"); if (hasInsert) { collectionType.InvokeMember( "Insert", BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Instance, null, collectionInstance, new object[] { index, newElement.GetValueFor(null) }, CultureInfo.InvariantCulture); return(true); } return(false); }
void SetPropertyValue(XamlPropertyValue value) { // Binding... //if (IsCollection) { // throw new InvalidOperationException("Cannot set the value of collection properties."); //} bool wasSet = this.IsSet; PossiblyNameChanged(propertyValue, value); //reset expression var xamlObject = propertyValue as XamlObject; if (xamlObject != null && xamlObject.IsMarkupExtension) { propertyInfo.ResetValue(parentObject.Instance); } ResetInternal(); propertyValue = value; if (propertyValue != null) { propertyValue.ParentProperty = this; propertyValue.AddNodeTo(this); } UpdateValueOnInstance(); ParentObject.OnPropertyChanged(this); if (!wasSet) { if (IsSetChanged != null) { IsSetChanged(this, EventArgs.Empty); } } if (ValueChanged != null) { ValueChanged(this, EventArgs.Empty); } }
/// <summary> /// Adds a value at the specified index in the collection. /// </summary> public static bool Insert(Type collectionType, object collectionInstance, XamlPropertyValue newElement, int index) { object value = newElement.GetValueFor(null); // Using IList, with possible Add instead of Insert, was primarily added as a workaround // for a peculiarity (or bug) with collections inside System.Windows.Input namespace. // See CollectionTests.InputCollectionsPeculiarityOrBug test method for details. var list = collectionInstance as IList; if (list != null) { if (list.Count == index) { list.Add(value); } else { list.Insert(index, value); } return(true); } else { var hasInsert = collectionType.GetMethods().Any(x => x.Name == "Insert"); if (hasInsert) { collectionType.InvokeMember( "Insert", BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Instance, null, collectionInstance, new object[] { index, value }, CultureInfo.InvariantCulture); return(true); } } return(false); }
void ResetInternal() { bool isExplicitCollection = false; if (propertyValue != null) { isExplicitCollection = IsCollection; propertyValue.RemoveNodeFromParent(); propertyValue.ParentProperty = null; propertyValue = null; } if (_propertyElement != null) { Debug.Assert(!isExplicitCollection || _propertyElement.ParentNode == null); if (!isExplicitCollection) { _propertyElement.ParentNode.RemoveChild(_propertyElement); } _propertyElement = null; } }
/// <summary> /// Adds a value at the specified index in the collection. /// </summary> public static bool Insert(Type collectionType, object collectionInstance, XamlPropertyValue newElement, int index) { object value = newElement.GetValueFor(null); // Using IList, with possible Add instead of Insert, was primarily added as a workaround // for a peculiarity (or bug) with collections inside System.Windows.Input namespace. // See CollectionTests.InputCollectionsPeculiarityOrBug test method for details. var list = collectionInstance as IList; if (list != null) { if (list.Count == index) { list.Add(value); } else { list.Insert(index, value); } return true; } else { var hasInsert = collectionType.GetMethods().Any(x => x.Name == "Insert"); if (hasInsert) { collectionType.InvokeMember( "Insert", BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Instance, null, collectionInstance, new object[] { index, value }, CultureInfo.InvariantCulture); return true; } } return false; }
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; } } } }
void PossiblyNameChanged(XamlPropertyValue oldValue, XamlPropertyValue newValue) { if (PropertyName == "Name" && ReturnType == typeof(string)) { string oldName = null; string newName = null; var oldTextValue = oldValue as XamlTextValue; if (oldTextValue != null) oldName = oldTextValue.Text; var newTextValue = newValue as XamlTextValue; if (newTextValue != null) newName = newTextValue.Text; var obj = ParentObject; while (obj != null) { var nameScope = obj.Instance as INameScope; if (nameScope == null) { if (obj.Instance is DependencyObject) nameScope = NameScope.GetNameScope((DependencyObject)obj.Instance); } if (nameScope != null) { if (oldName != null) { try { nameScope.UnregisterName(oldName); } catch (Exception x) { Debug.WriteLine(x.Message); } } if (newName != null) { nameScope.RegisterName(newName, ParentObject.Instance); } break; } obj = obj.ParentObject; } } }
/// <summary> /// used internally by the XamlParser. /// Add a collection element that already is part of the XML DOM. /// </summary> internal void ParserAddCollectionElement(XmlElement collectionPropertyElement, XamlPropertyValue val) { if (collectionPropertyElement != null && _propertyElement == null) { ParserSetPropertyElement(collectionPropertyElement); } collectionElements.AddInternal(val); val.ParentProperty = this; if (collectionPropertyElement != _propertyElement) { val.RemoveNodeFromParent(); val.AddNodeTo(this); } }
/// <summary> /// Removes an item instance from the specified collection. /// </summary> internal static void RemoveItem(Type collectionType, object collectionInstance, object item, XamlPropertyValue element) { var dictionary = collectionInstance as IDictionary; var xamlObject = element as XamlObject; if (dictionary != null && xamlObject != null) { dictionary.Remove(xamlObject.GetXamlAttribute("Key")); } else { RemoveItem(collectionType, collectionInstance, item); } }
private static void AppendPropertyValue(StringBuilder sb, XamlPropertyValue value, bool isStringProperty) { var textValue = value as XamlTextValue; if (textValue != null) { string text = textValue.Text; bool containsSpace = text.Contains(' '); if(containsSpace) { sb.Append('\''); } if (isStringProperty) sb.Append(text.Replace("\\", "\\\\").Replace("{", "\\{").Replace("}", "\\}")); else sb.Append(text.Replace("\\", "\\\\")); if(containsSpace) { sb.Append('\''); } } else if (value is XamlObject) { sb.Append(Print(value as XamlObject)); } }
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)); } }
/// <summary> /// Adds a value at the specified index in the collection. A return value indicates whether the Insert succeeded. /// </summary> /// <returns>True if the Insert succeeded, false if the collection type does not support Insert.</returns> internal static bool TryInsert(Type collectionType, object collectionInstance, XamlPropertyValue newElement, int index) { try { Insert(collectionType, collectionInstance, newElement, index); } catch (MissingMethodException) { return false; } return true; }
private static IElement ParseObject(XamlPropertyValue @object, IHtmlDocument htmlDocument, IElement outerElement) { IElement element = null; if (@object is XamlObject) { bool alreadyAdded = false; bool childsParsed = false; var xamlObject = (XamlObject)@object; switch (xamlObject.ElementType.Name) { case "Viewbox": { element = htmlDocument.CreateElement("div"); //todo: stretch, zoom?? break; } case "Border": { element = htmlDocument.CreateElement("div"); break; } case "Canvas": { element = htmlDocument.CreateElement("div"); ((IHtmlElement)element).Style.Position = "absolute"; break; } case "StackPanel": { element = htmlDocument.CreateElement("div"); ((IHtmlElement)element).Style.Display = "flex"; ((IHtmlElement)element).Style.FlexDirection = "column"; break; } case "WrapPanel": { element = htmlDocument.CreateElement("div"); ((IHtmlElement)element).Style.Display = "flex"; ((IHtmlElement)element).Style.FlexWrap = "wrap"; ((IHtmlElement)element).Style.FlexDirection = "column"; break; } case "DockPanel": { element = htmlDocument.CreateElement("div"); ((IHtmlElement)element).Style.Display = "flex"; ((IHtmlElement)element).Style.FlexDirection = "column"; break; } case "Grid": { var tbl = htmlDocument.CreateElement("table"); ((IHtmlElement)tbl).Style.Width = "100%"; ((IHtmlElement)tbl).Style.Height = "100%"; outerElement.AppendChild(tbl); alreadyAdded = true; childsParsed = true; var grid = xamlObject.Instance as Grid; foreach (var xamlProperty in xamlObject.Properties.Where(x => x.PropertyName != "Children")) { ParseProperty(xamlProperty, htmlDocument, (IHtmlElement)tbl); } var children = xamlObject.Properties.FirstOrDefault(x => x.PropertyName == "Children"); for (int n = 0; n < (grid.RowDefinitions.Count > 0 ? grid.RowDefinitions.Count : 1); n++) { var row = htmlDocument.CreateElement("tr"); ((IHtmlElement)row).Style.VerticalAlign = "top"; tbl.AppendChild(row); if (grid.RowDefinitions.Count > 0) { var rd = grid.RowDefinitions[n]; ((IHtmlElement)row).Style.Height = ParseGridLenth(rd.Height); } row.ClassList.Add("visuGrid"); for (int p = 0; p < (grid.ColumnDefinitions.Count > 0 ? grid.ColumnDefinitions.Count : 1); p++) { var td = htmlDocument.CreateElement("td"); td.ClassList.Add("visuGrid"); row.AppendChild(td); element = htmlDocument.CreateElement("div"); td.AppendChild(element); ((IHtmlElement)element).Style.Width = "100%"; ((IHtmlElement)element).Style.Height = "100%"; if (grid.ColumnDefinitions.Count > 0) { var rd = grid.ColumnDefinitions[p]; ((IHtmlElement)td).Style.Width = ParseGridLenth(rd.Width); } //Row Col Span should be used var p1 = p; var n1 = n; var childs = children.CollectionElements.OfType<XamlObject>().Where(x => Grid.GetColumn((UIElement)x.Instance) == p1 && Grid.GetRow((UIElement)x.Instance) == n1); foreach (var child in childs) { var el = ParseObject(child, htmlDocument, element); //((IHtmlElement) el).Style.Position = null; } } } element = tbl; break; } case "Image": { element = htmlDocument.CreateElement("div"); break; } case "Rectangle": { element = htmlDocument.CreateElement("div"); break; } case "Button": { element = htmlDocument.CreateElement("button"); break; } case "TextBlock": { element = htmlDocument.CreateElement("span"); break; } case "TextBox": { element = htmlDocument.CreateElement("input"); element.SetAttribute("type", "text"); break; } default: { break; } } if (element != null) { if (xamlObject.ParentObject != null && (xamlObject.ParentObject.Instance is Grid || xamlObject.ParentObject.Instance is Canvas)) { //((IHtmlElement) element).Style.Position = "absolute"; } if (xamlObject.ParentObject != null && xamlObject.ParentObject.Instance is Grid) { if (((FrameworkElement)xamlObject.Instance).HorizontalAlignment != HorizontalAlignment.Stretch) { SetFixedWidth((IHtmlElement)element, xamlObject); } else { ((IHtmlElement)element).Style.Width = "100%"; } if (((FrameworkElement)xamlObject.Instance).VerticalAlignment != VerticalAlignment.Stretch) { SetFixedHeight((IHtmlElement)element, xamlObject); } else { ((IHtmlElement)element).Style.Height = "100%"; } } else { SetFixedWidth((IHtmlElement)element, xamlObject); SetFixedHeight((IHtmlElement)element, xamlObject); } } if (element != null && !childsParsed) { foreach (var xamlProperty in xamlObject.Properties) { ParseProperty(xamlProperty, htmlDocument, (IHtmlElement)element); } if (!alreadyAdded) { outerElement.AppendChild(element); } } } else if (@object is XamlTextValue) { var text = @object as XamlTextValue; outerElement.TextContent = text.Text; } return element; }
/// <summary> /// Adds a value at the specified index in the collection. A return value indicates whether the Insert succeeded. /// </summary> /// <returns>True if the Insert succeeded, false if the collection type does not support Insert.</returns> internal static bool TryInsert(Type collectionType, object collectionInstance, XamlPropertyValue newElement, int index) { try { Insert(collectionType, collectionInstance, newElement, index); } catch (MissingMethodException) { return(false); } return(true); }
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; }
void SetPropertyValue(XamlPropertyValue value) { // Binding... //if (IsCollection) { // throw new InvalidOperationException("Cannot set the value of collection properties."); //} bool wasSet = this.IsSet; PossiblyNameChanged(propertyValue, value); //reset expression var xamlObject = propertyValue as XamlObject; if (xamlObject != null && xamlObject.IsMarkupExtension) propertyInfo.ResetValue(parentObject.Instance); ResetInternal(); propertyValue = value; propertyValue.ParentProperty = this; propertyValue.AddNodeTo(this); UpdateValueOnInstance(); ParentObject.OnPropertyChanged(this); if (!wasSet) { if (IsSetChanged != null) { IsSetChanged(this, EventArgs.Empty); } } if (ValueChanged != null) { ValueChanged(this, EventArgs.Empty); } }
/// <summary> /// Adds a value to the end of a collection. /// </summary> public static void AddToCollection(Type collectionType, object collectionInstance, XamlPropertyValue newElement) { IAddChild addChild = collectionInstance as IAddChild; if (addChild != null) { if (newElement is XamlTextValue) { addChild.AddText((string)newElement.GetValueFor(null)); } else { addChild.AddChild(newElement.GetValueFor(null)); } } else if (collectionInstance is ResourceDictionary) { object val = newElement.GetValueFor(null); object key = newElement is XamlObject ? ((XamlObject)newElement).GetXamlAttribute("Key") : null; //if (key == null || key == "") { // if (val is Style) // key = ((Style)val).TargetType; //} if (key == null || key == "") { key = val; } ((ResourceDictionary)collectionInstance).Add(key, val); } else { collectionType.InvokeMember( "Add", BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Instance, null, collectionInstance, new object[] { newElement.GetValueFor(null) }, CultureInfo.InvariantCulture); } }
void PossiblyNameChanged(XamlPropertyValue oldValue, XamlPropertyValue newValue) { if (ParentObject.RuntimeNameProperty != null && PropertyName == ParentObject.RuntimeNameProperty) { if (!String.IsNullOrEmpty(ParentObject.GetXamlAttribute("Name"))) { throw new XamlLoadException("The property 'Name' is set more than once."); } string oldName = null; string newName = null; var oldTextValue = oldValue as XamlTextValue; if (oldTextValue != null) oldName = oldTextValue.Text; var newTextValue = newValue as XamlTextValue; if (newTextValue != null) newName = newTextValue.Text; NameScopeHelper.NameChanged(ParentObject, oldName, newName); } }