Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / wpf / src / Framework / System / Windows / Markup / StyleBamlRecordReader.cs / 1 / StyleBamlRecordReader.cs
/****************************************************************************\ * * File: StyleBamlRecordReader.cs * * Purpose: Main class to handle reading a Style Baml records from a stream * * History: * 11/13/03: peterost Created * * Copyright (C) 2003 by Microsoft Corporation. All rights reserved. * \***************************************************************************/ using System; using System.Xml; using System.IO; using System.Windows; using System.Windows.Navigation; using System.Text; using System.Collections; using System.ComponentModel; using System.Windows.Media.Animation; using System.Diagnostics; using System.Reflection; using System.Windows.Threading; using System.Windows.Data; using System.Globalization; using MS.Utility; namespace System.Windows.Markup { ////// Reads BAML from a Stream that pertains to Style elements and properties. /// This is an internal class /// internal class StyleBamlRecordReader : BamlRecordReader { /***************************************************************************\ * * StylePropType * * The type of a property, as determined by its syntax. Property types are * specified in markup as: * 1) "SomeString" - convert to an object using ParseProperty, which * calls upon the type converter logic * 2) "*Alias(AnotherDP)" - Refer to another DependencyProperty which * is resolved based on current context * 3) "{ResourceRef}" - Reference to a resource somewhere in the tree, * which is resolved at runtime. * \***************************************************************************/ private enum StylePropType { Default, // Normal property converted from string Resource, // Resource reference } #region Constructor ////// StyleBamlRecordReader constructor /// /// The input BAML stream, if loading from a file /// StartRecord for List of records, if loading from a dictionary /// Index Record into list of records to start parsing at /// The parser context /// Reader stack from upper level parser to get /// context for things such as dictionaries and parents. /// list of root objects for the parse internal StyleBamlRecordReader( Stream bamlStream, BamlRecord bamlStartRecord, BamlRecord bamlIndexRecord, ParserContext parserContext, ParserStack bamlReaderStack, ArrayList rootList) { Debug.Assert(null != bamlStream || bamlStartRecord != null); Debug.Assert(null != parserContext && null != parserContext.XamlTypeMapper); SetPreviousBamlRecordReader( parserContext.BamlReader ); ParserContext = parserContext; RootList = rootList; PreParsedRecordsStart = bamlStartRecord; PreParsedCurrentRecord = bamlIndexRecord; if (bamlStream != null) { BamlStream = bamlStream; } RootElement = ParserContext.RootElement; ContextStack = bamlReaderStack; _styleConnector = ParserContext.StyleConnector; NullVisualTriggerData(); NullSettersData(); } #endregion Constructor #region Overrides /***************************************************************************\ * * StyleBamlRecordReader.ReadRecord * * Read a single record and process it. Return false if there are no * more records to process. * \***************************************************************************/ internal override bool ReadRecord(BamlRecord bamlRecord) { bool moreData = base.ReadRecord(bamlRecord); return (_styleModeStack.Depth > 0 && moreData); } /***************************************************************************\ * * StyleBamlRecordReader.ReadXmlnsPropertyRecord * * Read an XML namespace definition record. This contains a mapping from * an xml namespace to a prefix used within the scope of the current element. * Note that for Styles, we may not always have an object where we can store * the namespace dictionary, so ignore those cases (eg - Triggers) * \***************************************************************************/ protected override void ReadXmlnsPropertyRecord( BamlXmlnsPropertyRecord xmlnsRecord) { Debug.Assert(ReaderFlags.DependencyObject == CurrentContext.ContextType || ReaderFlags.ClrObject == CurrentContext.ContextType || ReaderFlags.PropertyComplexClr == CurrentContext.ContextType || ReaderFlags.PropertyComplexDP == CurrentContext.ContextType); // Accept name space directives for DependencyObjects and clr objects only if (ReaderFlags.DependencyObject == CurrentContext.ContextType || ReaderFlags.ClrObject == CurrentContext.ContextType || ReaderFlags.PropertyComplexClr == CurrentContext.ContextType || ReaderFlags.PropertyComplexDP == CurrentContext.ContextType) { XmlnsDictionary[xmlnsRecord.Prefix] = xmlnsRecord.XmlNamespace; } } /****************************************************************************\ * * StyleBamlRecordReader.ReaKeyElementStartRecord * * Read the start of an x:Key dictionary key section. This involves creating * an object tree for the key, and storing this in the associated dictionary. * \***************************************************************************/ internal override void ReadKeyElementStartRecord( BamlKeyElementStartRecord bamlKeyElementStartRecord) { StyleMode mode = _styleModeStack.Mode; if (mode == StyleMode.Base) { _baseParsing = true; mode = StyleMode.Key; } base.ReadKeyElementStartRecord(bamlKeyElementStartRecord); _styleModeStack.Push(mode); } /***************************************************************************\ * * StyleBamlRecordReader.ReaKeyElementEndRecord * * Read the end of an x:Key dictionary key section. * \***************************************************************************/ internal override void ReadKeyElementEndRecord() { if (_styleModeStack.Pop() == StyleMode.Key) { _baseParsing = false; } base.ReadKeyElementEndRecord(); } protected override void ReadConnectionId(BamlConnectionIdRecord bamlConnectionIdRecord) { // Hookup any IDs or events that correspond to this connectionId on the Style if (_styleConnector != null) { object target = _styleModeStack.Mode == StyleMode.Setters ? _style : GetCurrentObjectData(); _styleConnector.Connect(bamlConnectionIdRecord.ConnectionId, target); } } /****************************************************************************\ * * StyleBamlRecordReader.ReadElementStartRecord * * Read the start of an element. This involves creating a new object, and * storing it for later addition to the tree or setting as a property. * \***************************************************************************/ protected override bool ReadElementStartRecord( BamlElementStartRecord bamlElementRecord) { Type elementType = MapTable.GetTypeFromId(bamlElementRecord.TypeId); bool serializerUsed = false; StyleMode mode = _styleModeStack.Mode; // Parsing styled targettype's subobjects, in which // case we want the base behavior for element records. if (_baseParsing || mode == StyleMode.Setters || mode == StyleMode.TriggerSetters) { Debug.Assert(_styleModeStack.Depth > 1); serializerUsed = base.ReadElementStartRecord(bamlElementRecord); // If we used another serializer to handle this element start tag, it will // also handle the element end tag, which will affect our depth // count, so exit now in order to avoid incrementing depth; if (serializerUsed) { return serializerUsed; } } else if (_styleModeStack.Depth == 0) // The very first element encountered when parsing a style block should be the //