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
//