static bool TryAddToProperty(object element, XmlName propertyName, object value, string xKey, IXmlLineInfo lineInfo, XamlServiceProvider serviceProvider, HydrationContext context, out Exception exception) { exception = null; object targetProperty; var collection = GetPropertyValue(element, propertyName, context, lineInfo, out targetProperty) as IEnumerable; if (collection == null) { return(false); } if (exception == null && TryAddToResourceDictionary(collection as ResourceDictionary, value, xKey, lineInfo, out exception)) { return(true); } if (exception != null) { return(false); } var addMethod = collection.GetType().GetRuntimeMethods().First(mi => mi.Name == "Add" && mi.GetParameters().Length == 1); if (addMethod == null) { return(false); } if (serviceProvider != null) { ((XamlValueTargetProvider)serviceProvider.IProvideValueTarget).TargetProperty = targetProperty; } try { addMethod.Invoke(collection, new[] { value.ConvertTo(addMethod.GetParameters()[0].ParameterType, (Func <TypeConverter>)null, serviceProvider, out exception) }); } catch (Exception e) { exception = e; } return(exception == null); }
static bool TrySetProperty(object element, string localName, object value, IXmlLineInfo lineInfo, XamlServiceProvider serviceProvider, HydrationContext context, out Exception exception) { exception = null; var elementType = element.GetType(); var propertyInfo = elementType.GetRuntimeProperties().FirstOrDefault(p => p.Name == localName); MethodInfo setter; if (propertyInfo == null || !propertyInfo.CanWrite || (setter = propertyInfo.SetMethod) == null) { return(false); } if (!IsVisibleFrom(setter, context.RootElement)) { return(false); } if (serviceProvider != null && serviceProvider.IProvideValueTarget != null) { ((XamlValueTargetProvider)serviceProvider.IProvideValueTarget).TargetProperty = propertyInfo; } object convertedValue = value.ConvertTo(propertyInfo.PropertyType, () => propertyInfo, serviceProvider, out exception); if (exception != null || (convertedValue != null && !propertyInfo.PropertyType.IsInstanceOfType(convertedValue))) { return(false); } try { setter.Invoke(element, new object[] { convertedValue }); return(true); } catch (Exception e) { exception = e; return(false); } }
static bool TryGetProperty(object element, string localName, out object value, IXmlLineInfo lineInfo, HydrationContext context, out Exception exception, out object targetProperty) { exception = null; value = null; var elementType = element.GetType(); PropertyInfo propertyInfo = null; #if NETSTANDARD1_0 try { propertyInfo = elementType.GetRuntimeProperty(localName); } catch (AmbiguousMatchException) { // Get most derived instance of property foreach (var property in elementType.GetRuntimeProperties().Where(prop => prop.Name == localName)) { if (propertyInfo == null || propertyInfo.DeclaringType.IsAssignableFrom(property.DeclaringType)) { propertyInfo = property; } } } #else while (elementType != null && propertyInfo == null) { try { propertyInfo = elementType.GetProperty(localName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.DeclaredOnly); } catch (AmbiguousMatchException e) { throw new XamlParseException($"Multiple properties with name '{elementType}.{localName}' found.", lineInfo, innerException: e); } elementType = elementType.BaseType; } #endif MethodInfo getter; targetProperty = propertyInfo; if (propertyInfo == null || !propertyInfo.CanRead || (getter = propertyInfo.GetMethod) == null) { return(false); } if (!IsVisibleFrom(getter, context.RootElement)) { return(false); } value = getter.Invoke(element, new object[] { }); return(true); }
public static void SetPropertyValue(object xamlelement, XmlName propertyName, object value, object rootElement, INode node, HydrationContext context, IXmlLineInfo lineInfo) { var localName = propertyName.LocalName; var serviceProvider = new XamlServiceProvider(node, context); Exception xpe = null; var xKey = node is IElementNode && ((IElementNode)node).Properties.ContainsKey(XmlName.xKey) ? ((ValueNode)((IElementNode)node).Properties[XmlName.xKey]).Value as string : null; //If it's an attached BP, update elementType and propertyName var bpOwnerType = xamlelement.GetType(); var attached = GetRealNameAndType(ref bpOwnerType, propertyName.NamespaceURI, ref localName, context, lineInfo); var property = GetBindableProperty(bpOwnerType, localName, lineInfo, false); //If the target is an event, connect if (xpe == null && TryConnectEvent(xamlelement, localName, attached, value, rootElement, lineInfo, out xpe)) { return; } //If Value is DynamicResource and it's a BP, SetDynamicResource if (xpe == null && TrySetDynamicResource(xamlelement, property, value, lineInfo, out xpe)) { return; } //If value is BindingBase, SetBinding if (xpe == null && TrySetBinding(xamlelement, property, localName, value, lineInfo, out xpe)) { return; } //If it's a BindableProberty, SetValue if (xpe == null && TrySetValue(xamlelement, property, attached, value, lineInfo, serviceProvider, out xpe)) { return; } //If we can assign that value to a normal property, let's do it if (xpe == null && TrySetProperty(xamlelement, localName, value, lineInfo, serviceProvider, context, out xpe)) { return; } //If it's an already initialized property, add to it if (xpe == null && TryAddToProperty(xamlelement, propertyName, value, xKey, lineInfo, serviceProvider, context, out xpe)) { return; } xpe = xpe ?? new XamlParseException($"Cannot assign property \"{localName}\": Property does not exist, or is not assignable, or mismatching type between value and property", lineInfo); if (context.ExceptionHandler != null) { context.ExceptionHandler(xpe); } else { throw xpe; } }
public static object GetPropertyValue(object xamlElement, XmlName propertyName, HydrationContext context, IXmlLineInfo lineInfo, out object targetProperty) { var localName = propertyName.LocalName; Exception xpe = null; object value; targetProperty = null; //If it's an attached BP, update elementType and propertyName var bpOwnerType = xamlElement.GetType(); var attached = GetRealNameAndType(ref bpOwnerType, propertyName.NamespaceURI, ref localName, context, lineInfo); var property = GetBindableProperty(bpOwnerType, localName, lineInfo, false); //If it's a BindableProberty, GetValue if (xpe == null && TryGetValue(xamlElement, property, attached, out value, lineInfo, out xpe, out targetProperty)) { return(value); } //If it's a normal property, get it if (xpe == null && TryGetProperty(xamlElement, localName, out value, lineInfo, context, out xpe, out targetProperty)) { return(value); } xpe = xpe ?? new XamlParseException($"Property {localName} is not found or does not have an accessible getter", lineInfo); if (context.ExceptionHandler != null) { context.ExceptionHandler(xpe); } else { throw xpe; } return(null); }
public ExpandMarkupsVisitor(HydrationContext context) { Context = context; }
public ApplyPropertiesVisitor(HydrationContext context, bool stopOnResourceDictionary = false) { Context = context; StopOnResourceDictionary = stopOnResourceDictionary; }
static bool TryGetProperty(object element, string localName, out object value, IXmlLineInfo lineInfo, HydrationContext context, out Exception exception) { exception = null; value = null; var elementType = element.GetType(); PropertyInfo propertyInfo = null; try { propertyInfo = elementType.GetRuntimeProperty(localName); } catch (AmbiguousMatchException) { // Get most derived instance of property foreach (var property in elementType.GetRuntimeProperties().Where(prop => prop.Name == localName)) { if (propertyInfo == null || propertyInfo.DeclaringType.IsAssignableFrom(property.DeclaringType)) { propertyInfo = property; } } } MethodInfo getter; if (propertyInfo == null || !propertyInfo.CanRead || (getter = propertyInfo.GetMethod) == null) { return(false); } if (!IsVisibleFrom(getter, context.RootElement)) { return(false); } value = getter.Invoke(element, new object[] { }); return(true); }
public FillResourceDictionariesVisitor(HydrationContext context) { Context = context; }
public RegisterXNamesVisitor(HydrationContext context) { Context = context; Values = context.Values; }
public CreateValuesVisitor(HydrationContext context) { Context = context; }
public static void SetPropertyValue(object xamlelement, XmlName propertyName, object value, object rootElement, INode node, HydrationContext context, IXmlLineInfo lineInfo) { var localName = propertyName.LocalName; var serviceProvider = new XamlServiceProvider(node, context); Exception xpe = null; var xKey = node is IElementNode && ((IElementNode)node).Properties.ContainsKey(XmlName.xKey) ? ((ValueNode)((IElementNode)node).Properties[XmlName.xKey]).Value as string : null; //If it's an attached BP, update elementType and propertyName var bpOwnerType = xamlelement.GetType(); var attached = GetRealNameAndType(ref bpOwnerType, propertyName.NamespaceURI, ref localName, context, lineInfo); var property = GetBindableProperty(bpOwnerType, localName, lineInfo, false); //If the target is an event, connect if (xpe == null && TryConnectEvent(xamlelement, localName, attached, value, rootElement, lineInfo, out xpe)) { return; } //If Value is DynamicResource and it's a BP, SetDynamicResource if (xpe == null && TrySetDynamicResource(xamlelement, property, value, lineInfo, out xpe)) { return; } //If value is BindingBase, SetBinding if (xpe == null && TrySetBinding(xamlelement, property, localName, value, lineInfo, out xpe)) { return; } var assemblyName = (context.RootAssembly ?? rootElement.GetType().GetTypeInfo().Assembly)?.GetName().Name; //If it's a BindableProberty, SetValue if (xpe == null && TrySetValue(xamlelement, property, attached, value, lineInfo, serviceProvider, out xpe)) { if (!(node is ValueNode) && value != null && !value.GetType().GetTypeInfo().IsValueType&& XamlFilePathAttribute.GetFilePathForObject(context.RootElement) is string path) { VisualDiagnostics.RegisterSourceInfo(value, new Uri($"{path};assembly={assemblyName}", UriKind.Relative), ((IXmlLineInfo)node).LineNumber, ((IXmlLineInfo)node).LinePosition); } return; } //If we can assign that value to a normal property, let's do it if (xpe == null && TrySetProperty(xamlelement, localName, value, lineInfo, serviceProvider, context, out xpe)) { if (!(node is ValueNode) && value != null && !value.GetType().GetTypeInfo().IsValueType&& XamlFilePathAttribute.GetFilePathForObject(context.RootElement) is string path) { VisualDiagnostics.RegisterSourceInfo(value, new Uri($"{path};assembly={assemblyName}", UriKind.Relative), ((IXmlLineInfo)node).LineNumber, ((IXmlLineInfo)node).LinePosition); } return; } //If it's an already initialized property, add to it if (xpe == null && TryAddToProperty(xamlelement, propertyName, value, xKey, lineInfo, serviceProvider, context, out xpe)) { if (!(node is ValueNode) && value != null && !value.GetType().GetTypeInfo().IsValueType&& XamlFilePathAttribute.GetFilePathForObject(context.RootElement) is string path) { VisualDiagnostics.RegisterSourceInfo(value, new Uri($"{path};assembly={assemblyName}", UriKind.Relative), ((IXmlLineInfo)node).LineNumber, ((IXmlLineInfo)node).LinePosition); } return; } xpe = xpe ?? new XamlParseException($"Cannot assign property \"{localName}\": Property does not exist, or is not assignable, or mismatching type between value and property", lineInfo); if (context.ExceptionHandler != null) { context.ExceptionHandler(xpe); } else { throw xpe; } }
public NamescopingVisitor(HydrationContext context) { Values = context.Values; }
public NamescopingVisitor(HydrationContext context) { }
public static void SetPropertyValue(object xamlelement, XmlName propertyName, object value, object rootElement, INode node, HydrationContext context, IXmlLineInfo lineInfo) { var serviceProvider = new XamlServiceProvider(node, context); var xKey = node is IElementNode && ((IElementNode)node).Properties.ContainsKey(XmlName.xKey) ? ((ValueNode)((IElementNode)node).Properties[XmlName.xKey]).Value as string : null; if (TrySetPropertyValue(xamlelement, propertyName, xKey, value, rootElement, lineInfo, serviceProvider, out var xpe)) { return; } if (context.ExceptionHandler != null) { context.ExceptionHandler(xpe); } else { throw xpe; } }
private static object GetTargetProperty(object xamlelement, XmlName propertyName, HydrationContext context, IXmlLineInfo lineInfo) { var localName = propertyName.LocalName; //If it's an attached BP, update elementType and propertyName var bpOwnerType = xamlelement.GetType(); GetRealNameAndType(ref bpOwnerType, propertyName.NamespaceURI, ref localName, context, lineInfo); var property = GetBindableProperty(bpOwnerType, localName, lineInfo, false); if (property != null) { return(property); } var elementType = xamlelement.GetType(); var propertyInfo = elementType.GetRuntimeProperties().FirstOrDefault(p => p.Name == localName); return(propertyInfo); }