XamlExtension InlineExtension(XamlContext ctx, XElement ctxElement) { var type = ctxElement.Annotation<XamlType>(); if (type == null) return null; var ext = new XamlExtension(type); foreach (var attr in ctxElement.Attributes().Where(attr => attr.Name.Namespace != XNamespace.Xmlns)) ext.NamedArguments[attr.Name.LocalName] = attr.Value; foreach (var child in ctxElement.Nodes()) { var elem = child as XElement; if (elem == null) return null; if (elem.Name == ctor) { if (ext.Initializer != null) return null; var args = InlineCtor(ctx, elem); if (args == null) return null; ext.Initializer = args; continue; } var property = elem.Annotation<XamlProperty>(); if (property == null || elem.Nodes().Count() != 1 || elem.Attributes().Any(attr => attr.Name.Namespace != XNamespace.Xmlns)) return null; var name = property.PropertyName; var value = InlineObject(ctx, elem.Nodes().Single()); ext.NamedArguments[name] = value; } return ext; }
public BamlElement Translate(XamlContext ctx, BamlNode node, BamlElement parent) { var record = (PropertyWithExtensionRecord)((BamlRecordNode)node).Record; var extTypeId = ((short)record.Flags & 0xfff); bool valTypeExt = ((short)record.Flags & 0x4000) == 0x4000; bool valStaticExt = ((short)record.Flags & 0x2000) == 0x2000; var elemType = parent.Xaml.Element.Annotation<XamlType>(); var xamlProp = ctx.ResolveProperty(record.AttributeId); var extType = ctx.ResolveType((ushort)-extTypeId); extType.ResolveNamespace(parent.Xaml, ctx); var ext = new XamlExtension(extType); if (valTypeExt || extTypeId == (short)KnownTypes.TypeExtension) { var value = ctx.ResolveType(record.ValueId); ext.Initializer = new object[] { ctx.ToString(parent.Xaml, value) }; } else if (extTypeId == (short)KnownTypes.TemplateBindingExtension) { var value = ctx.ResolveProperty(record.ValueId); value.DeclaringType.ResolveNamespace(parent.Xaml, ctx); var xName = value.ToXName(ctx, parent.Xaml, false); ext.Initializer = new object[] { ctx.ToString(parent.Xaml, xName) }; } else if (valStaticExt || extTypeId == (short)KnownTypes.StaticExtension) { string attrName; if (record.ValueId > 0x7fff) { bool isKey = true; short bamlId = (short)-record.ValueId; if (bamlId > 232 && bamlId < 464) { bamlId -= 232; isKey = false; } else if (bamlId > 464 && bamlId < 467) { bamlId -= 231; } else if (bamlId > 467 && bamlId < 470) { bamlId -= 234; isKey = false; } var res = ctx.Baml.KnownThings.Resources(bamlId); string name; if (isKey) name = res.Item1 + "." + res.Item2; else name = res.Item1 + "." + res.Item3; var xmlns = ctx.GetXmlNamespace("http://schemas.microsoft.com/winfx/2006/xaml/presentation"); attrName = ctx.ToString(parent.Xaml, xmlns.GetName(name)); } else { var value = ctx.ResolveProperty(record.ValueId); value.DeclaringType.ResolveNamespace(parent.Xaml, ctx); var xName = value.ToXName(ctx, parent.Xaml); attrName = ctx.ToString(parent.Xaml, xName); } ext.Initializer = new object[] { attrName }; } else { ext.Initializer = new object[] { XamlUtils.Escape(ctx.ResolveString(record.ValueId)) }; } var extValue = ext.ToString(ctx, parent.Xaml); var attr = new XAttribute(xamlProp.ToXName(ctx, parent.Xaml, xamlProp.IsAttachedTo(elemType)), extValue); parent.Xaml.Element.Add(attr); return null; }