private void LoadNode(IEnumerable nodes, Element parent) { foreach (XmlNode node in nodes) { // Create an instance of the control. var control = CreateControlInstance(node, parent); if (control == null) continue; control.LogicalParent = parent; control.Parent = parent; if (node.Attributes != null) { // Get all the dependency properties (and those inherited) of the control. var props = DependencyProperty.GetProperties(control.GetType()); List<DependencyProperty> parentProps = null; // For each xml property, try and find a dependency property to set. foreach (XmlAttribute xmlProperty in node.Attributes) { var propertyName = xmlProperty.Name; var prop = props.FirstOrDefault(p => p.Name == propertyName); if (prop != null) { if (prop.Attached) throw new InvalidOperationException("Attached property cannot be set on the parent."); // Convert the string value to the dependency property type. var value = ConvertValue(xmlProperty.Value, prop.ValueType); control.SetValue(prop, value); } // Attached properties. else if (propertyName.Contains(".") && parent != null) { if (parentProps == null) // Get parent properties only when needed and only once. parentProps = DependencyProperty.GetProperties(parent.GetType()); var parts = propertyName.Split('.'); if (parts.Length == 2) { var parentName = parts[0]; propertyName = parts[1]; var parentType = parent.GetType(); if (parentType.Name == parentName) { prop = parentProps.FirstOrDefault(p => p.Attached && p.Name == propertyName); if (prop != null) { var value = ConvertValue(xmlProperty.Value, prop.ValueType); control.SetValue(prop, value); } } else throw new InvalidOperationException("No parent found matching " + parentName); } } } } // Add element to parent or set as root element. if (parent == null) manager.AddRootElement(control); else parent.Add(control); LoadNode(node.ChildNodes, control); } }
private void LoadNode(IEnumerable nodes, Element parent) { foreach (XmlNode node in nodes) { var control = CreateControlInstance(node, parent); if (control == null) continue; var props = TypeDescriptor.GetProperties(control.GetType()); // Set attributes. if (node.Attributes != null) { foreach (XmlAttribute xmlProperty in node.Attributes) { var propertyName = xmlProperty.Name; var propertyDescriptor = props[propertyName]; if (propertyDescriptor != null) { object value = null; // Convert the attribute to a value using a converter or Convert.ChangeType. var found = false; for (var i = 0; i < converters.Count; i++) { var converter = converters[i]; if (converter.CanConvert(propertyDescriptor.PropertyType)) { value = converter.Convert(propertyDescriptor.PropertyType, xmlProperty.Value); found = true; break; } } if (!found) value = Convert.ChangeType(xmlProperty.Value, propertyDescriptor.PropertyType); propertyDescriptor.SetValue(control, value); } } } // Add element to parent or set as root element. if (parent == null) manager.Elements.Add(control); else parent.Add(control); LoadNode(node.ChildNodes, control); } }