/// <summary> /// If the Style represented by a group of baml records is stored in a dictionary, this /// method will extract the key used for this dictionary from the passed /// collection of baml records. For Style, this is the type of the first element record /// in the record collection, skipping over the Style element itself. /// </summary> //CASRemoval:[StrongNameIdentityPermission(SecurityAction.InheritanceDemand, PublicKey = Microsoft.Internal.BuildInfo.WCP_PUBLIC_KEY_STRING)] internal override object GetDictionaryKey(BamlRecord startRecord, ParserContext parserContext) { Type styleTargetType = Style.DefaultTargetType; bool styleTargetTypeSet = false; object targetType = null; int numberOfElements = 0; BamlRecord record = startRecord; short ownerTypeId = 0; while (record != null) { if (record.RecordType == BamlRecordType.ElementStart) { BamlElementStartRecord elementStart = record as BamlElementStartRecord; if (++numberOfElements == 1) { // save the type ID of the first element (i.e. <Style>) ownerTypeId = elementStart.TypeId; } else if (numberOfElements == 2) { styleTargetType = parserContext.MapTable.GetTypeFromId(elementStart.TypeId); styleTargetTypeSet = true; break; } } else if (record.RecordType == BamlRecordType.Property && numberOfElements == 1) { // look for the TargetType property on the <Style> element BamlPropertyRecord propertyRecord = record as BamlPropertyRecord; if (parserContext.MapTable.DoesAttributeMatch(propertyRecord.AttributeId, ownerTypeId, TargetTypePropertyName)) { targetType = parserContext.XamlTypeMapper.GetDictionaryKey(propertyRecord.Value, parserContext); } } else if (record.RecordType == BamlRecordType.PropertyComplexStart || record.RecordType == BamlRecordType.PropertyIListStart) { // We didn't find the second element before a complex property like // Style.Triggers, so return the default style target type: FrameworkElement. break; } record = record.Next; } if (targetType == null) { if (!styleTargetTypeSet) { ThrowException(SRID.StyleNoDictionaryKey, parserContext.LineNumber, parserContext.LinePosition); } return(styleTargetType); } else { return(targetType); } }
/// <summary> /// If the Template represented by a group of baml records is stored in a dictionary, this /// method will extract the key used for this dictionary from the passed /// collection of baml records. For ControlTemplate, this is the styleTargetType. /// For DataTemplate, this is the DataTemplateKey containing the DataType. /// </summary> //CASRemoval:[StrongNameIdentityPermission(SecurityAction.InheritanceDemand, PublicKey = Microsoft.Internal.BuildInfo.WCP_PUBLIC_KEY_STRING)] internal override object GetDictionaryKey(BamlRecord startRecord, ParserContext parserContext) { object key = null; int numberOfElements = 0; BamlRecord record = startRecord; short ownerTypeId = 0; while (record != null) { if (record.RecordType == BamlRecordType.ElementStart) { BamlElementStartRecord elementStart = record as BamlElementStartRecord; if (++numberOfElements == 1) { // save the type ID of the first element (i.e. <ControlTemplate>) ownerTypeId = elementStart.TypeId; } else { // We didn't find the key before a reading the // VisualTree nodes of the template break; } } else if (record.RecordType == BamlRecordType.Property && numberOfElements == 1) { // look for the TargetType property on the <ControlTemplate> element // or the DataType property on the <DataTemplate> element BamlPropertyRecord propertyRecord = record as BamlPropertyRecord; short attributeOwnerTypeId; string attributeName; BamlAttributeUsage attributeUsage; parserContext.MapTable.GetAttributeInfoFromId(propertyRecord.AttributeId, out attributeOwnerTypeId, out attributeName, out attributeUsage); if (attributeOwnerTypeId == ownerTypeId) { if (attributeName == TargetTypePropertyName) { key = parserContext.XamlTypeMapper.GetDictionaryKey(propertyRecord.Value, parserContext); } else if (attributeName == DataTypePropertyName) { object dataType = parserContext.XamlTypeMapper.GetDictionaryKey(propertyRecord.Value, parserContext); Exception ex = TemplateKey.ValidateDataType(dataType, null); if (ex != null) { ThrowException(SRID.TemplateBadDictionaryKey, parserContext.LineNumber, parserContext.LinePosition, ex); } // key = new DataTemplateKey(dataType); } } } else if (record.RecordType == BamlRecordType.PropertyComplexStart || record.RecordType == BamlRecordType.PropertyIListStart || record.RecordType == BamlRecordType.ElementEnd) { // We didn't find the targetType before a complex property like // FrameworkTemplate.VisualTree or the </ControlTemplate> tag or // TableTemplate.Tree or the </TableTemplate> tag break; } record = record.Next; } if (key == null) { ThrowException(SRID.StyleNoDictionaryKey, parserContext.LineNumber, parserContext.LinePosition, null); } return(key); }
// Helper function to create a BamlRecord from a BamlRecordType private BamlRecord AllocateRecord(BamlRecordType recordType) { BamlRecord record; switch(recordType) { case BamlRecordType.DocumentStart: record = new BamlDocumentStartRecord(); break; case BamlRecordType.DocumentEnd: record = new BamlDocumentEndRecord(); break; case BamlRecordType.ConnectionId: record = new BamlConnectionIdRecord(); break; case BamlRecordType.ElementStart: record = new BamlElementStartRecord(); break; case BamlRecordType.ElementEnd: record = new BamlElementEndRecord(); break; case BamlRecordType.DeferableContentStart: record = new BamlDeferableContentStartRecord(); break; case BamlRecordType.DefAttributeKeyString: record = new BamlDefAttributeKeyStringRecord(); break; case BamlRecordType.DefAttributeKeyType: record = new BamlDefAttributeKeyTypeRecord(); break; case BamlRecordType.LiteralContent: record = new BamlLiteralContentRecord(); break; case BamlRecordType.Property: record = new BamlPropertyRecord(); break; case BamlRecordType.PropertyWithConverter: record = new BamlPropertyWithConverterRecord(); break; case BamlRecordType.PropertyStringReference: record = new BamlPropertyStringReferenceRecord(); break; case BamlRecordType.PropertyTypeReference: record = new BamlPropertyTypeReferenceRecord(); break; case BamlRecordType.PropertyWithExtension: record = new BamlPropertyWithExtensionRecord(); break; case BamlRecordType.PropertyCustom: record = new BamlPropertyCustomRecord(); break; case BamlRecordType.PropertyComplexStart: record = new BamlPropertyComplexStartRecord(); break; case BamlRecordType.PropertyComplexEnd: record = new BamlPropertyComplexEndRecord(); break; case BamlRecordType.RoutedEvent: record = new BamlRoutedEventRecord(); break; case BamlRecordType.PropertyArrayStart: record = new BamlPropertyArrayStartRecord(); break; case BamlRecordType.PropertyArrayEnd: record = new BamlPropertyArrayEndRecord(); break; case BamlRecordType.PropertyIListStart: record = new BamlPropertyIListStartRecord(); break; case BamlRecordType.PropertyIListEnd: record = new BamlPropertyIListEndRecord(); break; case BamlRecordType.PropertyIDictionaryStart: record = new BamlPropertyIDictionaryStartRecord(); break; case BamlRecordType.PropertyIDictionaryEnd: record = new BamlPropertyIDictionaryEndRecord(); break; case BamlRecordType.Text: record = new BamlTextRecord(); break; case BamlRecordType.TextWithConverter: record = new BamlTextWithConverterRecord(); break; case BamlRecordType.TextWithId: record = new BamlTextWithIdRecord(); break; case BamlRecordType.XmlnsProperty: record = new BamlXmlnsPropertyRecord(); break; case BamlRecordType.PIMapping: record = new BamlPIMappingRecord(); break; case BamlRecordType.DefAttribute: record = new BamlDefAttributeRecord(); break; case BamlRecordType.PresentationOptionsAttribute: record = new BamlPresentationOptionsAttributeRecord(); break; case BamlRecordType.KeyElementStart: record = new BamlKeyElementStartRecord(); break; case BamlRecordType.KeyElementEnd: record = new BamlKeyElementEndRecord(); break; case BamlRecordType.ConstructorParametersStart: record = new BamlConstructorParametersStartRecord(); break; case BamlRecordType.ConstructorParametersEnd: record = new BamlConstructorParametersEndRecord(); break; case BamlRecordType.ConstructorParameterType: record = new BamlConstructorParameterTypeRecord(); break; case BamlRecordType.ContentProperty: record = new BamlContentPropertyRecord(); break; case BamlRecordType.AssemblyInfo: case BamlRecordType.TypeInfo: case BamlRecordType.TypeSerializerInfo: case BamlRecordType.AttributeInfo: case BamlRecordType.StringInfo: Debug.Assert(false,"Assembly, Type and Attribute records are not cached, so don't ask for one."); record = null; break; case BamlRecordType.StaticResourceStart: record = new BamlStaticResourceStartRecord(); break; case BamlRecordType.StaticResourceEnd: record = new BamlStaticResourceEndRecord(); break; case BamlRecordType.StaticResourceId: record = new BamlStaticResourceIdRecord(); break; case BamlRecordType.LineNumberAndPosition: record = new BamlLineAndPositionRecord(); break; case BamlRecordType.LinePosition: record = new BamlLinePositionRecord(); break; case BamlRecordType.OptimizedStaticResource: record = new BamlOptimizedStaticResourceRecord(); break; case BamlRecordType.PropertyWithStaticResourceId: record = new BamlPropertyWithStaticResourceIdRecord(); break; default: Debug.Assert(false,"Unknown RecordType"); record = null; break; } return record; }