Exemple #1
0
        /// <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);
            }
        }
        // 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;
        }
        /// <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);
        }
        internal BamlRecord CloneRecord(BamlRecord record)
        {
            BamlRecord newRecord;
            
            switch (record.RecordType)
            {
                case BamlRecordType.ElementStart:
                    if (record is BamlNamedElementStartRecord)
                    {
                        newRecord= new BamlNamedElementStartRecord();
                    }
                    else
                    {
                        newRecord = new BamlElementStartRecord();
                    }
                    break;
                    
                case BamlRecordType.PropertyCustom:
                    if (record is BamlPropertyCustomWriteInfoRecord)
                    {
                        newRecord = new BamlPropertyCustomWriteInfoRecord();
                    }
                    else
                    {
                        newRecord = new BamlPropertyCustomRecord();
                    }
                    break;
            
                default:
                    newRecord = AllocateRecord(record.RecordType);
                    break;
            }

            record.Copy(newRecord);
            
            return newRecord;
        }