// This method writes out BAML to produce a resource key based on the // DataType property. private void WriteDataTypeKey(XamlPropertyWithTypeNode xamlPropertyNode) { base.WriteKeyElementStart(new XamlElementStartNode( xamlPropertyNode.LineNumber, xamlPropertyNode.LinePosition, xamlPropertyNode.Depth, _templateKeyType.Assembly.FullName, _templateKeyType.FullName, _templateKeyType, null)); base.WriteConstructorParametersStart(new XamlConstructorParametersStartNode( xamlPropertyNode.LineNumber, xamlPropertyNode.LinePosition, xamlPropertyNode.Depth)); base.WriteConstructorParameterType(new XamlConstructorParameterTypeNode( xamlPropertyNode.LineNumber, xamlPropertyNode.LinePosition, xamlPropertyNode.Depth, xamlPropertyNode.ValueTypeFullName, xamlPropertyNode.ValueTypeAssemblyName, xamlPropertyNode.ValueElementType)); base.WriteConstructorParametersEnd(new XamlConstructorParametersEndNode( xamlPropertyNode.LineNumber, xamlPropertyNode.LinePosition, xamlPropertyNode.Depth)); base.WriteKeyElementEnd(new XamlElementEndNode( xamlPropertyNode.LineNumber, xamlPropertyNode.LinePosition, xamlPropertyNode.Depth)); }
/// <summary> /// Write a Property, which has the form in markup of property="value" where /// value has been resolved to a Type reference. /// </summary> /// <remarks> /// When in a VisualTree, only DependencyProperties can be set directly on /// a FrameworkElementFactory. This method checks the state of parsing and /// with throw an exception if a clr property is set on a FrameworkElementFactory. /// </remarks> public override void WritePropertyWithType(XamlPropertyWithTypeNode xamlPropertyNode) { StyleMode mode = _styleModeStack.Mode; if (mode == StyleMode.Base && xamlPropertyNode.PropName == XamlTemplateSerializer.TargetTypePropertyName) { _templateTargetTypeType = xamlPropertyNode.ValueElementType; } // If we are on the DataTemplate tag itself, and we encounter a DataType property, // this can be used as the key when placing this template in a ResourceDictionary. // In that case, remember what the property value is so that we can // later update the defer key held by the baml writer. else if (mode == StyleMode.Base && xamlPropertyNode.PropName == XamlTemplateSerializer.DataTypePropertyName) { #if PBTCOMPILER // Treat DataType="some type" as a key in a resource dictionary. // Generate a sequence of baml records to describe the key. if (InDeferLoadedSection && !_defNameFound) { _dataTypePropertyNode = xamlPropertyNode; _dataTypePropertyNodeDepth = _styleModeStack.Depth; } #endif } #if PBTCOMPILER else if (mode == StyleMode.DataTypeProperty && InDeferLoadedSection && !_defNameFound) { // We have to treat DataType="{x:Type SomeType}" as a key in a // resource dictionary, if one is present. This means generating // a series of baml records to use as the key for the defer loaded // body of the Style. base.WritePropertyWithType(xamlPropertyNode); } #endif base.WritePropertyWithType(xamlPropertyNode); }
/// <summary> /// Write a Property, which has the form in markup of property="value". /// </summary> /// <remarks> /// Note that for DependencyProperties, the assemblyName, TypeFullName, PropIdName /// refer to DependencyProperty field /// that the property was found on. This may be different from the ownerType /// of the propId if the property was registered as an alias so if the /// callback is persisting we want to persist the information that the propId /// was found on in case the alias is a private or internal field. /// </remarks> public virtual void WritePropertyWithType(XamlPropertyWithTypeNode xamlPropertyNode) { if (BamlRecordWriter != null) { if (xamlPropertyNode.ValueElementType == null) { ThrowException(SRID.ParserNoType, xamlPropertyNode.ValueTypeFullName, xamlPropertyNode.LineNumber, xamlPropertyNode.LinePosition); } BamlRecordWriter.WritePropertyWithType(xamlPropertyNode); } }
/// <summary> /// Represent a single property for a MarkupExtension as a complex property. /// </summary> private void CompileProperty( ArrayList xamlNodes, string name, string value, Type parentType, string parentTypeNamespaceUri, AttributeData data, int lineNumber, int linePosition, int depth) { RemoveEscapes(ref name); RemoveEscapes(ref value); int nameIndex = name.IndexOf(':'); string localName = (nameIndex < 0) ? name : name.Substring(nameIndex+1); string prefix = (nameIndex < 0) ? String.Empty : name.Substring(0, nameIndex); string attribNamespaceURI = ResolveAttributeNamespaceURI(prefix, localName, parentTypeNamespaceUri); object dynamicObject; string assemblyName; string typeFullName; Type declaringType; string dynamicObjectName; if (String.IsNullOrEmpty(attribNamespaceURI)) { ThrowException(SRID.ParserPrefixNSProperty, prefix, name, lineNumber, linePosition); } AttributeContext attributeContext = GetAttributeContext( parentType, parentTypeNamespaceUri, attribNamespaceURI, localName, out dynamicObject, out assemblyName, out typeFullName, out declaringType, out dynamicObjectName); if (attributeContext != AttributeContext.Property) { ThrowException(SRID.ParserMarkupExtensionUnknownAttr, localName, parentType.FullName, lineNumber, linePosition); } MemberInfo info = dynamicObject as MemberInfo; Debug.Assert(null != info, "No property or method info for field Name"); if (data != null && data.IsSimple) { if (data.IsTypeExtension) { string typeValueFullName = value; // set this to original value for error reporting if reqd. string typeValueAssemblyFullName = null; Type typeValue = _parserContext.XamlTypeMapper.GetTypeFromBaseString(value, _parserContext, true); if (typeValue != null) { typeValueFullName = typeValue.FullName; typeValueAssemblyFullName = typeValue.Assembly.FullName; } XamlPropertyWithTypeNode xamlPropertyWithTypeNode = new XamlPropertyWithTypeNode(data.LineNumber, data.LinePosition, data.Depth, dynamicObject, assemblyName, typeFullName, localName, typeValueFullName, typeValueAssemblyFullName, typeValue, string.Empty, string.Empty); xamlNodes.Add(xamlPropertyWithTypeNode); } else { XamlPropertyWithExtensionNode xamlPropertyWithExtensionNode = new XamlPropertyWithExtensionNode(data.LineNumber, data.LinePosition, data.Depth, dynamicObject, assemblyName, typeFullName, localName, value, data.ExtensionTypeId, data.IsValueNestedExtension, data.IsValueTypeExtension); xamlNodes.Add(xamlPropertyWithExtensionNode); } } else { XamlPropertyNode xamlPropertyNode = new XamlPropertyNode(lineNumber, linePosition, depth, dynamicObject, assemblyName, typeFullName, dynamicObjectName, value, BamlAttributeUsage.Default, true); xamlNodes.Add(xamlPropertyNode); } }
// Write a property baml record for a property that is of type 'Type'. This means // that the baml record contains a typeid reference for a type which was resolved at // compile time. internal virtual void WritePropertyWithType(XamlPropertyWithTypeNode xamlPropertyWithType) { short attributeId = MapTable.AddAttributeInfoMap(BinaryWriter, xamlPropertyWithType.AssemblyName, xamlPropertyWithType.TypeFullName, xamlPropertyWithType.PropDeclaringType, xamlPropertyWithType.PropName, xamlPropertyWithType.PropValidType, BamlAttributeUsage.Default); // If we do not already have a type record for the type of this property, // then add a new TypeInfo record to the map table. short typeId; if (!MapTable.GetTypeInfoId(BinaryWriter, xamlPropertyWithType.ValueTypeAssemblyName, xamlPropertyWithType.ValueTypeFullName, out typeId)) { typeId = MapTable.AddTypeInfoMap(BinaryWriter, xamlPropertyWithType.ValueTypeAssemblyName, xamlPropertyWithType.ValueTypeFullName, xamlPropertyWithType.ValueElementType, xamlPropertyWithType.ValueSerializerTypeAssemblyName, xamlPropertyWithType.ValueSerializerTypeFullName); } BamlPropertyTypeReferenceRecord bamlProperty = BamlRecordManager.GetWriteRecord( BamlRecordType.PropertyTypeReference) as BamlPropertyTypeReferenceRecord; bamlProperty.AttributeId = attributeId; bamlProperty.TypeId = typeId; WriteAndReleaseRecord(bamlProperty, xamlPropertyWithType); }
/// <summary> /// Write a Property, which has the form in markup of property="value" where /// "value" has been resolved into a Type object. /// </summary> public override void WritePropertyWithType(XamlPropertyWithTypeNode xamlPropertyNode) { // If we are on the Style tag itself, and we encounter a TargetType property, // this can be used as the key when placing this style in a ResourceDictionary. if (_styleModeStack.Mode == StyleMode.Base && xamlPropertyNode.PropName == XamlStyleSerializer.TargetTypePropertyName) { _styleTargetTypeType = xamlPropertyNode.ValueElementType; #if PBTCOMPILER if (InDeferLoadedSection && !_defNameFound) { if (BamlRecordWriter != null && xamlPropertyNode.ValueElementType == null) { ThrowException(SRID.ParserNoType, xamlPropertyNode.ValueTypeFullName, xamlPropertyNode.LineNumber, xamlPropertyNode.LinePosition); } // We have to treat TargetType="{x:Type SomeType}" as a key in a // resource dictionary, if one is present. This means generating // a baml record to use as the key for the defer loaded // body of the Style. base.WriteDefAttributeKeyType( new XamlDefAttributeKeyTypeNode(xamlPropertyNode.LineNumber, xamlPropertyNode.LinePosition,xamlPropertyNode.Depth, xamlPropertyNode.ValueTypeFullName, xamlPropertyNode.ValueTypeAssemblyName, xamlPropertyNode.ValueElementType)); } #endif } base.WritePropertyWithType(xamlPropertyNode); }