// Token: 0x060021BA RID: 8634 RVA: 0x000A8248 File Offset: 0x000A6448 internal void CompileAttribute(ArrayList xamlNodes, AttributeData data) { string fullName = data.DeclaringType.Assembly.FullName; string fullName2 = data.DeclaringType.FullName; Type propertyType; bool propertyCanWrite; XamlTypeMapper.GetPropertyType(data.Info, out propertyType, out propertyCanWrite); XamlNode value; XamlNode value2; switch (BamlRecordManager.GetPropertyStartRecordType(propertyType, propertyCanWrite)) { case BamlRecordType.PropertyArrayStart: value = new XamlPropertyArrayStartNode(data.LineNumber, data.LinePosition, data.Depth, data.Info, fullName, fullName2, data.PropertyName); value2 = new XamlPropertyArrayEndNode(data.LineNumber, data.LinePosition, data.Depth); goto IL_164; case BamlRecordType.PropertyIListStart: value = new XamlPropertyIListStartNode(data.LineNumber, data.LinePosition, data.Depth, data.Info, fullName, fullName2, data.PropertyName); value2 = new XamlPropertyIListEndNode(data.LineNumber, data.LinePosition, data.Depth); goto IL_164; case BamlRecordType.PropertyIDictionaryStart: value = new XamlPropertyIDictionaryStartNode(data.LineNumber, data.LinePosition, data.Depth, data.Info, fullName, fullName2, data.PropertyName); value2 = new XamlPropertyIDictionaryEndNode(data.LineNumber, data.LinePosition, data.Depth); goto IL_164; } value = new XamlPropertyComplexStartNode(data.LineNumber, data.LinePosition, data.Depth, data.Info, fullName, fullName2, data.PropertyName); value2 = new XamlPropertyComplexEndNode(data.LineNumber, data.LinePosition, data.Depth); IL_164: xamlNodes.Add(value); this.CompileAttributeCore(xamlNodes, data); xamlNodes.Add(value2); }
// Initialize the collection holder, by setting its property definition and default value (retrieved // from the property definition). internal void InitDefaultValue() { if (AttributeName == "Resources" && Parent is IHaveResources) { // "Fast Path" handling of Resources non-DP property _resourcesParent = ((IHaveResources)Parent); _defaultCollection = _resourcesParent.Resources; } // the order of precedence according to the spec is DP, then attached property, then PropertyInfo else if (PropertyDefinition.DependencyProperty != null) { _defaultCollection = ((DependencyObject)Parent).GetValue(PropertyDefinition.DependencyProperty); } else if (PropertyDefinition.AttachedPropertyGetter != null) { _defaultCollection = PropertyDefinition.AttachedPropertyGetter.Invoke(null, new object[] { Parent }); } else if (PropertyDefinition.PropertyInfo != null) { if (PropertyDefinition.IsInternal) { _defaultCollection = XamlTypeMapper.GetInternalPropertyValue(_reader.ParserContext, _reader.ParserContext.RootElement, PropertyDefinition.PropertyInfo, Parent); if (_defaultCollection == null) { _reader.ThrowException(SRID.ParserCantGetProperty, PropertyDefinition.Name); } } else { _defaultCollection = PropertyDefinition.PropertyInfo.GetValue( Parent, BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy, null, null, TypeConverterHelper.InvariantEnglishUS); } } else { _reader.ThrowException(SRID.ParserCantGetDPOrPi, AttributeName); } }
// Token: 0x06001D22 RID: 7458 RVA: 0x00087C30 File Offset: 0x00085E30 internal void InitDefaultValue() { if (this.AttributeName == "Resources" && this.Parent is IHaveResources) { this._resourcesParent = (IHaveResources)this.Parent; this._defaultCollection = this._resourcesParent.Resources; return; } if (this.PropertyDefinition.DependencyProperty != null) { this._defaultCollection = ((DependencyObject)this.Parent).GetValue(this.PropertyDefinition.DependencyProperty); return; } if (this.PropertyDefinition.AttachedPropertyGetter != null) { this._defaultCollection = this.PropertyDefinition.AttachedPropertyGetter.Invoke(null, new object[] { this.Parent }); return; } if (this.PropertyDefinition.PropertyInfo != null) { if (!this.PropertyDefinition.IsInternal) { this._defaultCollection = this.PropertyDefinition.PropertyInfo.GetValue(this.Parent, BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy, null, null, TypeConverterHelper.InvariantEnglishUS); return; } this._defaultCollection = XamlTypeMapper.GetInternalPropertyValue(this._reader.ParserContext, this._reader.ParserContext.RootElement, this.PropertyDefinition.PropertyInfo, this.Parent); if (this._defaultCollection == null) { this._reader.ThrowException("ParserCantGetProperty", this.PropertyDefinition.Name); return; } } else { this._reader.ThrowException("ParserCantGetDPOrPi", this.AttributeName); } }
internal XamlTypeMapperSchemaContext(XamlTypeMapper typeMapper) : base() { _typeMapper = typeMapper; _sharedSchemaContext = (WpfSharedXamlSchemaContext)XamlReader.GetWpfSchemaContext(); // Copy all the NamespaceMapEntrys from our parent into _nsDefinitions if (typeMapper._namespaceMaps != null) { _nsDefinitions = new Dictionary <string, FrugalObjectList <string> >(); foreach (NamespaceMapEntry mapEntry in _typeMapper._namespaceMaps) { FrugalObjectList <string> clrNsList; if (!_nsDefinitions.TryGetValue(mapEntry.XmlNamespace, out clrNsList)) { clrNsList = new FrugalObjectList <string>(1); _nsDefinitions.Add(mapEntry.XmlNamespace, clrNsList); } string clrNs = GetClrNsUri(mapEntry.ClrNamespace, mapEntry.AssemblyName); clrNsList.Add(clrNs); } } // Copy all the PIs from our parent into _piNamespaces if (typeMapper.PITable.Count > 0) { _piNamespaces = new Dictionary <string, string>(typeMapper.PITable.Count); foreach (DictionaryEntry entry in typeMapper.PITable) { ClrNamespaceAssemblyPair pair = (ClrNamespaceAssemblyPair)entry.Value; string clrNs = GetClrNsUri(pair.ClrNamespace, pair.AssemblyName); _piNamespaces.Add((string)entry.Key, clrNs); } } _clrNamespaces = new HashSet <string>(); }
// Write columns related to the given table cell range. private static void WriteTableColumnsInformation(ITextRange range, Table table, XmlWriter xmlWriter, XamlTypeMapper xamlTypeMapper) { TableColumnCollection columns = table.Columns; int startColumn; int endColumn; if (!TextRangeEditTables.GetColumnRange(range, table, out startColumn, out endColumn)) { startColumn = 0; endColumn = columns.Count - 1; } Invariant.Assert(startColumn >= 0, "startColumn index is supposed to be non-negative"); if(columns.Count > 0) { // Build an appropriate name for the complex property string complexPropertyName = table.GetType().Name + ".Columns"; // Write the start element for the complex property. xmlWriter.WriteStartElement(complexPropertyName); for (int i = startColumn; i <= endColumn && i < columns.Count; i++) { WriteXamlAtomicElement(columns[i], xmlWriter, /*reduceElement:*/false); } // Close the element for the complex property xmlWriter.WriteEndElement(); } }
/// <summary> /// Writes an opening tag of an element together with all attributes /// representing Avalon properties. /// </summary> /// <param name="range"> /// Parameter used for top-level Table element - to decide what columns to output. /// For all other elements it's ignored. /// </param> /// <param name="textReader"> /// TextPointer positioned in the scope of element whose /// start tag is going to be written. /// </param> /// <param name="xmlWriter"> /// XmlWriter to output element opening tag. /// </param> /// <param name="xamlTypeMapper"></param> /// <param name="reduceElement"> /// True value of this parameter indicates that /// serialization goes into XamlPackage, so all elements /// can be preserved as is; otherwise some of them must be /// reduced into simpler representations (such as InlineUIContainer -> Run /// and BlockUIContainer -> Paragraph). /// </param> /// <param name="preserveTextElements"> /// If TRUE, TextElements are serialized as-is. If FALSE, they're upcast /// to their base types. /// </param> private static void WriteStartXamlElement(ITextRange range, ITextPointer textReader, XmlWriter xmlWriter, XamlTypeMapper xamlTypeMapper, bool reduceElement, bool preserveTextElements) { Type elementType = textReader.ParentType; Type elementTypeStandardized = TextSchema.GetStandardElementType(elementType, reduceElement); // Get rid f UIContainers when their child is not an image if (elementTypeStandardized == typeof(InlineUIContainer) || elementTypeStandardized == typeof(BlockUIContainer)) { Invariant.Assert(!reduceElement); InlineUIContainer inlineUIContainer = textReader.GetAdjacentElement(LogicalDirection.Backward) as InlineUIContainer; BlockUIContainer blockUIContainer = textReader.GetAdjacentElement(LogicalDirection.Backward) as BlockUIContainer; if ((inlineUIContainer == null || !(inlineUIContainer.Child is Image)) && (blockUIContainer == null || !(blockUIContainer.Child is Image))) { // Even when we serialize for DataFormats.XamlPackage we strip out UIElement // different from Images. // Note that this condition is consistent with the one in WriteEmbeddedObject - // so that when we reduce the element type fromm UIContainer to Run/Paragraph // we also output just a space instead of the embedded object conntained in it. elementTypeStandardized = TextSchema.GetStandardElementType(elementType, /*reduceElement:*/true); } } else if (preserveTextElements) { elementTypeStandardized = elementType; } bool customTextElement = preserveTextElements && !TextSchema.IsKnownType(elementType); if (customTextElement) { // If the element is not from PresentationFramework, we'll need to serialize a namespace // int index = elementTypeStandardized.Module.Name.LastIndexOf('.'); string assembly = (index == -1 ? elementTypeStandardized.Module.Name : elementTypeStandardized.Module.Name.Substring(0, index)); string nameSpace = "clr-namespace:" + elementTypeStandardized.Namespace + ";" + "assembly=" + assembly; string prefix = elementTypeStandardized.Namespace; xmlWriter.WriteStartElement(prefix, elementTypeStandardized.Name, nameSpace); } else { xmlWriter.WriteStartElement(elementTypeStandardized.Name); } // Write properties DependencyObject complexProperties = new DependencyObject(); WriteInheritableProperties(elementTypeStandardized, textReader, xmlWriter, /*onlyAffected:*/true, complexProperties); WriteNoninheritableProperties(elementTypeStandardized, textReader, xmlWriter, /*onlyAffected:*/true, complexProperties); if (customTextElement) { WriteLocallySetProperties(elementTypeStandardized, textReader, xmlWriter, complexProperties); } WriteComplexProperties(xmlWriter, complexProperties, elementTypeStandardized); // Special case for Table element serialization if (elementTypeStandardized == typeof(Table) && textReader is TextPointer) { // Write the columns text. WriteTableColumnsInformation(range, (Table)((TextPointer)textReader).Parent, xmlWriter, xamlTypeMapper); } }
/// <summary> /// Walks the tree up from current position and writes all scoping tags /// in their natural order - from root to leafs. /// </summary> /// <param name="range"> /// Range identifying the whole selection. /// Needed for /// - table cell range case: proper column processing: to output only columns related to the selection /// - text segement case: hyperlink serialization heuristics /// </param> /// <param name="thisElement"> /// ITextPointer identifying an element. /// </param> /// <param name="scope"> /// A position identifying the scope which should be used for serialization. /// All tags outside of this scope will be ignored. /// </param> /// <param name="xmlWriter"> /// XmlWriter to write element tags. /// </param> /// <param name="xamlTypeMapper"></param> /// <param name="reduceElement"> /// <see cref="WriteStartXamlElement"/> /// </param> /// <param name="ignoreWriteHyperlinkEnd"></param> /// <param name="ignoreList"></param> /// <param name="preserveTextElements"></param> /// /// <returns> /// Number of opening tags written into XmlWriter. /// This number should be used afterwards to close all opened tags. /// </returns> private static int WriteOpeningTags(ITextRange range, ITextPointer thisElement, ITextPointer scope, XmlWriter xmlWriter, XamlTypeMapper xamlTypeMapper, bool reduceElement, out bool ignoreWriteHyperlinkEnd, ref List<int> ignoreList, bool preserveTextElements) { ignoreWriteHyperlinkEnd = false; // Recursion ends when we reach the scope level. We will write tags on returing path from the recursion if (thisElement.HasEqualScope(scope)) { return 0; // no elements have opened at this level. Return elementCount==0. } Invariant.Assert(typeof(TextElement).IsAssignableFrom(thisElement.ParentType), "thisElement is expected to be a TextElement"); ITextPointer previousLevel = thisElement.CreatePointer(); previousLevel.MoveToElementEdge(ElementEdge.BeforeStart); // Recurse into the parent element int elementLevel = WriteOpeningTags(range, previousLevel, scope, xmlWriter, xamlTypeMapper, reduceElement, out ignoreWriteHyperlinkEnd, ref ignoreList, preserveTextElements); // After returning from the recursion - when all parent tags have been written, // write the opening tag for this element // Hyperlink open tag will be skipped since the range selection of Hyperlink is the partial // of Hyperlink range or Hyperlink include invalid UIElement except Image. bool ignoreHyperlink = false; bool isPartialNonTypographic = false; if (thisElement.ParentType == typeof(Hyperlink)) { if (TextPointerBase.IsAtNonMergeableInlineStart(range.Start)) { ITextPointer position = thisElement.CreatePointer(); position.MoveToElementEdge(ElementEdge.BeforeStart); ignoreHyperlink = IsHyperlinkInvalid(position, range.End); } else { ignoreHyperlink = true; } } else { // TextElementEditingBehaviorAttribute att = (TextElementEditingBehaviorAttribute)Attribute.GetCustomAttribute(thisElement.ParentType, typeof(TextElementEditingBehaviorAttribute)); if (att != null && !att.IsTypographicOnly) { if (TextPointerBase.IsAtNonMergeableInlineStart(range.Start)) { ITextPointer position = thisElement.CreatePointer(); position.MoveToElementEdge(ElementEdge.BeforeStart); isPartialNonTypographic = IsPartialNonTypographic(position, range.End); } else { isPartialNonTypographic = true; } } } int count; if (ignoreHyperlink) { // Ignore writing Hyperlink opening tag ignoreWriteHyperlinkEnd = true; // Set elementLevel without adding it count = elementLevel; } else if (isPartialNonTypographic) { // Add the end pointer to the list ITextPointer position = thisElement.CreatePointer(); position.MoveToElementEdge(ElementEdge.BeforeEnd); ignoreList.Add(position.Offset); // Set elementLevel without adding to it count = elementLevel; } else { // Write the opening tag WriteStartXamlElement(range, thisElement, xmlWriter, xamlTypeMapper, reduceElement, preserveTextElements); // Each opening tag adds one to the level count count = elementLevel + 1; } // Return the opening tag count return count; }
/// <summary> /// Serializes a rectagular table range /// </summary> private static void WriteXamlTableCellRange(XmlWriter xmlWriter, ITextRange range, XamlTypeMapper xamlTypeMapper, ref int elementLevel, WpfPayload wpfPayload, bool preserveTextElements) { Invariant.Assert(range.IsTableCellRange, "range is expected to be in IsTableCellRange state"); List<TextSegment> textSegments = range.TextSegments; int checkElementLevel = -1; // negative value as an indicator that it is not yet initialized // Set ignoreWriteHyperlinkEnd as false initially bool ignoreWriteHyperlinkEnd = false; List<int> ignoreList = new List<int>(); for (int i = 0; i < textSegments.Count; i++) { TextSegment textSegment = textSegments[i]; // Open a row for this segment (except for the very first one, for which we opened a row in a WriteOpeningTags method) if (i > 0) { ITextPointer pointer = textSegment.Start.CreatePointer(); while (!typeof(TableRow).IsAssignableFrom(pointer.ParentType)) { Invariant.Assert(typeof(TextElement).IsAssignableFrom(pointer.ParentType), "pointer must be still in a scope of TextElement"); pointer.MoveToElementEdge(ElementEdge.BeforeStart); } Invariant.Assert(typeof(TableRow).IsAssignableFrom(pointer.ParentType), "pointer must be in a scope of TableRow"); pointer.MoveToElementEdge(ElementEdge.BeforeStart); ITextRange textRange = new TextRange(textSegment.Start, textSegment.End); elementLevel += WriteOpeningTags(textRange, textSegment.Start, pointer, xmlWriter, xamlTypeMapper, /*reduceElement:*/wpfPayload == null, out ignoreWriteHyperlinkEnd, ref ignoreList, preserveTextElements); } // Output the cell segment for one row WriteXamlTextSegment(xmlWriter, textSegment.Start, textSegment.End, xamlTypeMapper, ref elementLevel, wpfPayload, ignoreWriteHyperlinkEnd, ignoreList, preserveTextElements); Invariant.Assert(elementLevel >= 4, "At the minimun we expected to stay within four elements: Section(wrapper),Table,TableRowGroup,TableRow"); if (checkElementLevel < 0) checkElementLevel = elementLevel; // initialize level checking variable Invariant.Assert(checkElementLevel == elementLevel, "elementLevel is supposed to be unchanged between segments of table cell range"); // Assuming that the element is TableRow - close it. // NOTE: Such assumption is valid because WriteXamlTextSegment moves end pointer out of all opening tags, // so it ends serialization immediately after the last cell's closing tag. // This means that we only need to close one level - for TableRow. // elementLevel--; xmlWriter.WriteFullEndElement(); } }
// ------------------------------------------------------------- // // Private Methods // // ------------------------------------------------------------- #region Private Methods // ............................................................. // // Serialization // // ............................................................. /// <summary> /// This function serializes text segment formed by rangeStart and rangeEnd to valid xml using xmlWriter. /// </summary> /// <SecurityNote> /// To mask the security exception from XamlWriter.Save in partial trust case, /// this function checks if the current call stack has the all clipboard permission. /// </SecurityNote> private static void WriteXamlTextSegment(XmlWriter xmlWriter, ITextPointer rangeStart, ITextPointer rangeEnd, XamlTypeMapper xamlTypeMapper, ref int elementLevel, WpfPayload wpfPayload, bool ignoreWriteHyperlinkEnd, List<int> ignoreList, bool preserveTextElements) { // Special case for pure text selection - we need a Run wrapper for it. if (elementLevel == EmptyDocumentDepth && typeof(Run).IsAssignableFrom(rangeStart.ParentType)) { elementLevel++; xmlWriter.WriteStartElement(typeof(Run).Name); } // Create text navigator for reading the range's content ITextPointer textReader = rangeStart.CreatePointer(); // Exclude last opening tag from serialization - we don't need to create extra element // is cases when we have whole paragraphs/cells selected. // NOTE: We do this slightly differently than in TextRangeEdit.AdjustRangeEnd, where we use normalization for adjusted position. // In this case normalized position does not work, because we need to keep information about crossed paragraph boundary. while (rangeEnd.GetPointerContext(LogicalDirection.Backward) == TextPointerContext.ElementStart) { rangeEnd = rangeEnd.GetNextContextPosition(LogicalDirection.Backward); } // Write the range internal contents while (textReader.CompareTo(rangeEnd) < 0) { TextPointerContext runType = textReader.GetPointerContext(LogicalDirection.Forward); switch (runType) { case TextPointerContext.ElementStart: TextElement nextElement = (TextElement)textReader.GetAdjacentElement(LogicalDirection.Forward); if (nextElement is Hyperlink) { // Don't write Hyperlink start element if Hyperlink is invalid // in case of having a UiElement except Image or stated the range end // position before the end position of the Hyperlink. if (IsHyperlinkInvalid(textReader, rangeEnd)) { ignoreWriteHyperlinkEnd = true; textReader.MoveToNextContextPosition(LogicalDirection.Forward); continue; } } else if (nextElement != null) { // TextElementEditingBehaviorAttribute att = (TextElementEditingBehaviorAttribute)Attribute.GetCustomAttribute(nextElement.GetType(), typeof(TextElementEditingBehaviorAttribute)); if (att != null && !att.IsTypographicOnly) { if (IsPartialNonTypographic(textReader, rangeEnd)) { // Add pointer to ignore list ITextPointer ptr = textReader.CreatePointer(); ptr.MoveToElementEdge(ElementEdge.BeforeEnd); ignoreList.Add(ptr.Offset); textReader.MoveToNextContextPosition(LogicalDirection.Forward); continue; } } } elementLevel++; textReader.MoveToNextContextPosition(LogicalDirection.Forward); WriteStartXamlElement(/*range:*/null, textReader, xmlWriter, xamlTypeMapper, /*reduceElement:*/wpfPayload == null, preserveTextElements); break; case TextPointerContext.ElementEnd: // Don't write Hyperlink end element if Hyperlink include the invalid // in case of having a UiElement except Image or stated the range end // before the end position of the Hyperlink or Hyperlink opening tag is // skipped from WriteOpeningTags by selecting of the partial of Hyperlink. if (ignoreWriteHyperlinkEnd && (textReader.GetAdjacentElement(LogicalDirection.Forward) is Hyperlink)) { // Reset the flag to keep walk up the next Hyperlink tag ignoreWriteHyperlinkEnd = false; textReader.MoveToNextContextPosition(LogicalDirection.Forward); continue; } // Check the ignore list ITextPointer endPointer = textReader.CreatePointer(); endPointer.MoveToElementEdge(ElementEdge.BeforeEnd); // if (ignoreList.Contains(endPointer.Offset)) { ignoreList.Remove(endPointer.Offset); textReader.MoveToNextContextPosition(LogicalDirection.Forward); continue; } elementLevel--; if (TextSchema.IsBreak(textReader.ParentType)) { // For LineBreak, etc. use empty element syntax xmlWriter.WriteEndElement(); } else { // // For all other textelements use explicit closing tag. xmlWriter.WriteFullEndElement(); } textReader.MoveToNextContextPosition(LogicalDirection.Forward); break; case TextPointerContext.Text: int textLength = textReader.GetTextRunLength(LogicalDirection.Forward); char[] text = new Char[textLength]; textLength = TextPointerBase.GetTextWithLimit(textReader, LogicalDirection.Forward, text, 0, textLength, rangeEnd); // XmlWriter will throw an ArgumentException if text contains // any invalid surrogates, so strip them out now. textLength = StripInvalidSurrogateChars(text, textLength); xmlWriter.WriteChars(text, 0, textLength); textReader.MoveToNextContextPosition(LogicalDirection.Forward); break; case TextPointerContext.EmbeddedElement: object embeddedObject = textReader.GetAdjacentElement(LogicalDirection.Forward); textReader.MoveToNextContextPosition(LogicalDirection.Forward); WriteEmbeddedObject(embeddedObject, xmlWriter, wpfPayload); break; default: Invariant.Assert(false, "unexpected value of runType"); textReader.MoveToNextContextPosition(LogicalDirection.Forward); break; } } }
// Token: 0x060020F0 RID: 8432 RVA: 0x000975CC File Offset: 0x000957CC public void WriteStartComplexProperty(string assemblyName, string ownerTypeFullName, string propName) { this.VerifyWriteState(); this._parserContext.PushScope(); this.ProcessMarkupExtensionNodes(); Type type = null; bool propertyCanWrite = true; object obj; Type type2; this.GetDpOrPi(assemblyName, ownerTypeFullName, propName, out obj, out type2); if (obj == null) { MethodInfo mi = this.GetMi(assemblyName, ownerTypeFullName, propName, out type2); if (mi != null) { XamlTypeMapper.GetPropertyType(mi, out type, out propertyCanWrite); } } else { type = XamlTypeMapper.GetPropertyType(obj); PropertyInfo propertyInfo = obj as PropertyInfo; if (propertyInfo != null) { propertyCanWrite = propertyInfo.CanWrite; } else { DependencyProperty dependencyProperty = obj as DependencyProperty; if (dependencyProperty != null) { propertyCanWrite = !dependencyProperty.ReadOnly; } } } int depth; if (type == null) { this.Push(BamlRecordType.PropertyComplexStart); int lineNumber = 0; int linePosition = 0; depth = this._depth; this._depth = depth + 1; XamlPropertyComplexStartNode xamlComplexPropertyNode = new XamlPropertyComplexStartNode(lineNumber, linePosition, depth, null, assemblyName, ownerTypeFullName, propName); this._bamlRecordWriter.WritePropertyComplexStart(xamlComplexPropertyNode); return; } BamlRecordType propertyStartRecordType = BamlRecordManager.GetPropertyStartRecordType(type, propertyCanWrite); this.Push(propertyStartRecordType); switch (propertyStartRecordType) { case BamlRecordType.PropertyArrayStart: { int lineNumber2 = 0; int linePosition2 = 0; depth = this._depth; this._depth = depth + 1; XamlPropertyArrayStartNode xamlPropertyArrayStartNode = new XamlPropertyArrayStartNode(lineNumber2, linePosition2, depth, obj, assemblyName, ownerTypeFullName, propName); this._bamlRecordWriter.WritePropertyArrayStart(xamlPropertyArrayStartNode); return; } case BamlRecordType.PropertyIListStart: { int lineNumber3 = 0; int linePosition3 = 0; depth = this._depth; this._depth = depth + 1; XamlPropertyIListStartNode xamlPropertyIListStart = new XamlPropertyIListStartNode(lineNumber3, linePosition3, depth, obj, assemblyName, ownerTypeFullName, propName); this._bamlRecordWriter.WritePropertyIListStart(xamlPropertyIListStart); return; } case BamlRecordType.PropertyIDictionaryStart: { int lineNumber4 = 0; int linePosition4 = 0; depth = this._depth; this._depth = depth + 1; XamlPropertyIDictionaryStartNode xamlPropertyIDictionaryStartNode = new XamlPropertyIDictionaryStartNode(lineNumber4, linePosition4, depth, obj, assemblyName, ownerTypeFullName, propName); this._bamlRecordWriter.WritePropertyIDictionaryStart(xamlPropertyIDictionaryStartNode); return; } } int lineNumber5 = 0; int linePosition5 = 0; depth = this._depth; this._depth = depth + 1; XamlPropertyComplexStartNode xamlComplexPropertyNode2 = new XamlPropertyComplexStartNode(lineNumber5, linePosition5, depth, obj, assemblyName, ownerTypeFullName, propName); this._bamlRecordWriter.WritePropertyComplexStart(xamlComplexPropertyNode2); }
internal BamlMapTable(XamlTypeMapper xamlTypeMapper) { Debug.Assert(null != xamlTypeMapper); _xamlTypeMapper = xamlTypeMapper; }
// Return a new XamlTypeMapper that has the same instance variables as this instance, // will all complex properties deep copied. #if !PBTCOMPILER internal XamlTypeMapper Clone() { XamlTypeMapper newMapper = new XamlTypeMapper(_assemblyNames.Clone() as string[]); newMapper._mapTable = _mapTable; newMapper._referenceAssembliesLoaded = _referenceAssembliesLoaded; newMapper._lineNumber = _lineNumber; newMapper._linePosition = _linePosition; newMapper._namespaceMaps = _namespaceMaps.Clone() as NamespaceMapEntry[]; newMapper._typeLookupFromXmlHashtable = _typeLookupFromXmlHashtable.Clone() as Hashtable; newMapper._namespaceMapHashList = _namespaceMapHashList.Clone() as Hashtable; newMapper._typeInformationCache = CloneHybridDictionary(_typeInformationCache); newMapper._piTable = CloneHybridDictionary(_piTable); newMapper._piReverseTable = CloneStringDictionary(_piReverseTable); newMapper._assemblyPathTable = CloneHybridDictionary(_assemblyPathTable); return newMapper; }
/// <summary> /// Finds the <see cref="FrameworkElement"/> a specific style is based on. /// </summary> /// <param name="resourceDictionaryUri">The resource dictionary URI.</param> /// <param name="styleKey">The style key.</param> /// <returns> /// <see cref="Type"/> or <c>null</c> if the style is not based on a <see cref="FrameworkElement"/>. /// </returns> /// <exception cref="ArgumentNullException">The <paramref name="resourceDictionaryUri"/> is <c>null</c>.</exception> /// <exception cref="ArgumentNullException">The <paramref name="styleKey"/> is <c>null</c>.</exception> /// <remarks> /// This method is introduced due to the lack of the ability to use DynamicResource for the BasedOn property when /// defining styles inside a derived theme. /// Should be used in combination with the <see cref="RecreateDefaultStylesBasedOnTheme"/> method. /// </remarks> private static Type FindFrameworkElementStyleIsBasedOn(Uri resourceDictionaryUri, string styleKey) { Argument.IsNotNull("resourceDictionaryUri", resourceDictionaryUri); Argument.IsNotNull("styleKey", styleKey); if (_styleToFrameworkElementTypeCache.ContainsKey(styleKey)) { return _styleToFrameworkElementTypeCache[styleKey]; } try { XmlDocument doc; if (_resourceDictionaryCache.ContainsKey(resourceDictionaryUri)) { doc = _resourceDictionaryCache[resourceDictionaryUri]; } else { StreamResourceInfo streamResourceInfo = Application.GetResourceStream(resourceDictionaryUri); var reader = new XmlBamlReader(streamResourceInfo.Stream); doc = new XmlDocument(); doc.Load(reader); _resourceDictionaryCache.Add(resourceDictionaryUri, doc); } #region Create xml namespace manager // Create namespace manager (all namespaces are required) var xmlNamespaceManager = new XmlNamespaceManager(doc.NameTable); foreach (XmlAttribute namespaceAttribute in doc.DocumentElement.Attributes) { // Clean up namespace (remove xmlns prefix) string xmlNamespace = namespaceAttribute.Name.Replace("xmlns", "").TrimStart(new char[] { ':' }); xmlNamespaceManager.AddNamespace(xmlNamespace, namespaceAttribute.Value); } // Add a dummy node xmlNamespaceManager.AddNamespace("x", "http://schemas.microsoft.com/winfx/2006/xaml"); xmlNamespaceManager.AddNamespace("ctl", "http://schemas.microsoft.com/winfx/2006/xaml/presentation"); #endregion string xpath = string.Format("/ctl:ResourceDictionary/ctl:Style[@x:Key='{0}']/@BasedOn", styleKey); var xmlAttribute = doc.SelectSingleNode(xpath, xmlNamespaceManager) as XmlAttribute; if (xmlAttribute == null) { Log.Warning("Style '{0}' does not have the 'BasedOn' attribute defined", styleKey); _styleToFrameworkElementTypeCache.Add(styleKey, null); return null; } string basedOnValue = xmlAttribute.Value; basedOnValue = basedOnValue.Replace("StaticResource", ""); basedOnValue = basedOnValue.Replace("x:Type", "").Trim(new[] { ' ', '{', '}' }); #region Create xml type mapper var xamlTypeMapper = new XamlTypeMapper(new[] { "PresentationFramework" }); foreach (XmlAttribute namespaceAttribute in doc.DocumentElement.Attributes) { string xmlNamespace = namespaceAttribute.Name.Replace("xmlns", "").TrimStart(new char[] { ':' }); string value = namespaceAttribute.Value; string clrNamespace = value; string assemblyName = string.Empty; if (clrNamespace.StartsWith("clr-namespace:")) { // We have a hit (formatting is normally one of the 2 below): // * clr-namespace:[NAMESPACE] // * clr-namespace:[NAMESPACE];assembly=[ASSEMBLY] if (clrNamespace.Contains(";")) { clrNamespace = clrNamespace.Split(new char[] { ';' })[0]; } clrNamespace = clrNamespace.Replace("clr-namespace:", ""); if (value.Contains(";")) { assemblyName = value.Split(new char[] { ';' })[1].Replace("assembly:", ""); } xamlTypeMapper.AddMappingProcessingInstruction(xmlNamespace, clrNamespace, assemblyName); } } #endregion string[] splittedType = basedOnValue.Split(new[] { ':' }); string typeNamespace = (splittedType.Length == 2) ? splittedType[0] : "http://schemas.microsoft.com/winfx/2006/xaml/presentation"; string typeName = (splittedType.Length == 2) ? splittedType[1] : splittedType[0]; var type = xamlTypeMapper.GetType(typeNamespace, typeName); if (type == null) { _styleToFrameworkElementTypeCache.Add(styleKey, null); return null; } Log.Debug("Style '{0}' is based on type '{1}'", styleKey, type); if ((type == typeof(FrameworkElement)) || type.IsSubclassOf(typeof(FrameworkElement))) { _styleToFrameworkElementTypeCache.Add(styleKey, type); return type; } _styleToFrameworkElementTypeCache.Add(styleKey, null); return null; } catch (Exception ex) { Log.Error(ex, "Failed to find the framework element where style '{0}' is based on", styleKey); return null; } }
/// <summary> /// Finds the <see cref="FrameworkElement"/> a specific style is based on. /// </summary> /// <param name="resourceDictionaryUri">The resource dictionary URI.</param> /// <param name="styleKey">The style key.</param> /// <returns> /// <see cref="Type"/> or <c>null</c> if the style is not based on a <see cref="FrameworkElement"/>. /// </returns> /// <exception cref="ArgumentNullException">The <paramref name="resourceDictionaryUri"/> is <c>null</c>.</exception> /// <exception cref="ArgumentNullException">The <paramref name="styleKey"/> is <c>null</c>.</exception> /// <remarks> /// This method is introduced due to the lack of the ability to use DynamicResource for the BasedOn property when /// defining styles inside a derived theme. /// Should be used in combination with the <see cref="RecreateDefaultStylesBasedOnTheme"/> method. /// </remarks> private static Type FindFrameworkElementStyleIsBasedOn(Uri resourceDictionaryUri, string styleKey) { Argument.IsNotNull("resourceDictionaryUri", resourceDictionaryUri); Argument.IsNotNull("styleKey", styleKey); return _styleToFrameworkElementTypeCache.GetFromCacheOrFetch(styleKey, () => { try { var xmlDocInfo = GetResourceXmlDocument(resourceDictionaryUri); var doc = xmlDocInfo.Item1; var xmlNamespaceManager = xmlDocInfo.Item2; string xpath = string.Format("/ctl:ResourceDictionary/ctl:Style[@x:Key='{0}']/@BasedOn", styleKey); var xmlAttribute = doc.SelectSingleNode(xpath, xmlNamespaceManager) as XmlAttribute; if (xmlAttribute == null) { Log.Warning("Style '{0}' does not have the 'BasedOn' attribute defined", styleKey); return null; } string basedOnValue = xmlAttribute.Value; basedOnValue = basedOnValue.Replace("StaticResource", ""); basedOnValue = basedOnValue.Replace("x:Type", "").Trim(new[] { ' ', '{', '}' }); #region Create xml type mapper var xamlTypeMapper = new XamlTypeMapper(new[] { "PresentationFramework" }); foreach (XmlAttribute namespaceAttribute in doc.DocumentElement.Attributes) { string xmlNamespace = namespaceAttribute.Name.Replace("xmlns", string.Empty).TrimStart(new[] { ':' }); string value = namespaceAttribute.Value; string clrNamespace = value; string assemblyName = string.Empty; if (clrNamespace.StartsWith("clr-namespace:")) { // We have a hit (formatting is normally one of the 2 below): // * clr-namespace:[NAMESPACE] // * clr-namespace:[NAMESPACE];assembly=[ASSEMBLY] if (clrNamespace.Contains(";")) { clrNamespace = clrNamespace.Split(new[] { ';' })[0]; } clrNamespace = clrNamespace.Replace("clr-namespace:", string.Empty); if (value.Contains(";")) { assemblyName = value.Split(new[] { ';' })[1].Replace("assembly:", string.Empty); } xamlTypeMapper.AddMappingProcessingInstruction(xmlNamespace, clrNamespace, assemblyName); } } #endregion string[] splittedType = basedOnValue.Split(new[] { ':' }); string typeNamespace = (splittedType.Length == 2) ? splittedType[0] : "http://schemas.microsoft.com/winfx/2006/xaml/presentation"; string typeName = (splittedType.Length == 2) ? splittedType[1] : splittedType[0]; var type = xamlTypeMapper.GetType(typeNamespace, typeName); if (type == null) { return null; } Log.Debug("Style '{0}' is based on type '{1}'", styleKey, type); if ((type == typeof(FrameworkElement)) || type.IsSubclassOf(typeof(FrameworkElement))) { return type; } return null; } catch (Exception ex) { Log.Error(ex, "Failed to find the framework element where style '{0}' is based on", styleKey); return null; } }); }
/// <summary> /// Creates a FlowDocument element wrapping copied content and storing its contextual properties. /// </summary> /// <param name="range"></param> /// <param name="context"></param> /// <param name="xmlWriter"></param> /// <param name="xamlTypeMapper"></param> /// <param name="lastParagraphMustBeMerged"></param> /// <param name="useFlowDocumentAsRoot"> /// true means that we need to serialize the whole FlowDocument - used in FileSave scenario; /// false means that we are in copy-paste scenario and will use Section or Span as a root - depending on context. /// </param> private static void WriteRootFlowDocument(ITextRange range, ITextPointer context, XmlWriter xmlWriter, XamlTypeMapper xamlTypeMapper, bool lastParagraphMustBeMerged, bool useFlowDocumentAsRoot) { Type rootType; const string xmlNamespace = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"; const string xmlns = "xmlns"; // Decide what root element to use if (useFlowDocumentAsRoot) { rootType = typeof(FlowDocument); } else { Type contextType = context.ParentType; if (contextType == null || typeof(Paragraph).IsAssignableFrom(contextType) || typeof(Inline).IsAssignableFrom(contextType) && !typeof(AnchoredBlock).IsAssignableFrom(contextType)) { rootType = typeof(Span); } else { rootType = typeof(Section); } } // Create a root element FlowDocument xmlWriter.WriteStartElement(rootType.Name, xmlNamespace); // Define default namespace as Avalon namespace xmlWriter.WriteAttributeString(xmlns, xmlNamespace); // Set the value of xml:space to "preserve" to consider all spaces as significant // Note that Xml treats whitespaces as significant if they belong to some nonempty line // (neighbored by non-whitespace characters at least from one side) // That's why we only loose whitespaces if they occupy the whole textrun in xml. // So alternative solution for whitespace preservation could be setting xml:space="preserve" // attribute to only empty runs - this would make our whitespace preservation more // narrowed... // xmlWriter.WriteAttributeString("xml:space", "preserve"); // Write all contextual properties as attributes of root fragment DependencyObject complexProperties = new DependencyObject(); if (useFlowDocumentAsRoot) { WriteInheritablePropertiesForFlowDocument((DependencyObject)((TextPointer)context).Parent, xmlWriter, complexProperties); } else { WriteInheritableProperties(rootType, context, xmlWriter, /*onlyAffected:*/false, complexProperties); } if (rootType == typeof(Span)) { // Root element is not real element to paste. It is just a property bag for contextual properties. // So we collect non-inheritable properties only for inline content; not needing it for block one. WriteNoninheritableProperties(typeof(Span), context, xmlWriter, /*onlyAffected:*/false, complexProperties); } // Write an indicator that last paragraph must be merged on paste if (rootType == typeof(Section) && lastParagraphMustBeMerged) { xmlWriter.WriteAttributeString(Section.HasTrailingParagraphBreakOnPastePropertyName, "False"); } // Note that we are skipping background property, because we only want to transfer it for the whole document. // WriteComplexProperties(xmlWriter, complexProperties, rootType); }
//[CodeAnalysis("AptcaMethodsShouldOnlyCallAptcaMethods")] //Tracking Bug: 29647 internal static object LoadBaml( Stream stream, ParserContext parserContext, object parent, bool closeStream) { object root = null; #if DEBUG_CLR_MEM bool clrTracingEnabled = false; // Use local pass variable to correctly log nested parses. int pass = 0; if (CLRProfilerControl.ProcessIsUnderCLRProfiler && (CLRProfilerControl.CLRLoggingLevel >= CLRProfilerControl.CLRLogState.Performance)) { clrTracingEnabled = true; pass = ++_CLRBamlPass; CLRProfilerControl.CLRLogWriteLine("Begin_BamlParse_{0}", pass); } #endif // DEBUG_CLR_MEM EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordXamlBaml | EventTrace.Keyword.KeywordPerf, EventTrace.Event.WClientParseBamlBegin, parserContext.BaseUri); if (TraceMarkup.IsEnabled) { TraceMarkup.Trace(TraceEventType.Start, TraceMarkup.Load); } try { // // If the stream contains info about the Assembly that created it, // set StreamCreatedAssembly from the stream instance. // IStreamInfo streamInfo = stream as IStreamInfo; if (streamInfo != null) { parserContext.StreamCreatedAssembly = streamInfo.Assembly; } Baml2006ReaderSettings readerSettings = XamlReader.CreateBamlReaderSettings(); readerSettings.BaseUri = parserContext.BaseUri; readerSettings.LocalAssembly = streamInfo.Assembly; // We do not set OwnsStream = true so the Baml2006Reader will not close the stream. // Calling code is responsible for disposing the stream if (readerSettings.BaseUri == null || String.IsNullOrEmpty(readerSettings.BaseUri.ToString())) { readerSettings.BaseUri = BaseUriHelper.PackAppBaseUri; } var reader = new Baml2006ReaderInternal(stream, new Baml2006SchemaContext(readerSettings.LocalAssembly), readerSettings, parent); // We don't actually use the GeneratedInternalTypeHelper any more. // But for v3 compat, don't allow loading of internals in PT unless there is one. Type internalTypeHelper = null; if (streamInfo.Assembly != null) { try { internalTypeHelper = XamlTypeMapper.GetInternalTypeHelperTypeFromAssembly(parserContext); } // This can perform attribute reflection which will fail if the assembly has unresolvable // attributes. If that happens, just assume there is no helper. catch (Exception e) { if (MS.Internal.CriticalExceptions.IsCriticalException(e)) { throw; } } } if (internalTypeHelper != null) { XamlAccessLevel accessLevel = XamlAccessLevel.AssemblyAccessTo(streamInfo.Assembly); XamlLoadPermission loadPermission = new XamlLoadPermission(accessLevel); loadPermission.Assert(); try { root = WpfXamlLoader.LoadBaml(reader, parserContext.SkipJournaledProperties, parent, accessLevel, parserContext.BaseUri); } finally { CodeAccessPermission.RevertAssert(); } } else { root = WpfXamlLoader.LoadBaml(reader, parserContext.SkipJournaledProperties, parent, null, parserContext.BaseUri); } DependencyObject dObject = root as DependencyObject; if (dObject != null) { dObject.SetValue(BaseUriHelper.BaseUriProperty, readerSettings.BaseUri); } Application app = root as Application; if (app != null) { app.ApplicationMarkupBaseUri = GetBaseUri(readerSettings.BaseUri); } Debug.Assert(parent == null || root == parent); } finally { if (TraceMarkup.IsEnabled) { TraceMarkup.Trace(TraceEventType.Stop, TraceMarkup.Load, root); } EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordXamlBaml | EventTrace.Keyword.KeywordPerf, EventTrace.Event.WClientParseBamlEnd, parserContext.BaseUri); if (closeStream && stream != null) { stream.Close(); } #if DEBUG_CLR_MEM if (clrTracingEnabled && (CLRProfilerControl.CLRLoggingLevel >= CLRProfilerControl.CLRLogState.Performance)) { CLRProfilerControl.CLRLogWriteLine("End_BamlParse_{0}", pass); } #endif // DEBUG_CLR_MEM } return(root); }
// Token: 0x060020EB RID: 8427 RVA: 0x000970C0 File Offset: 0x000952C0 public void WriteProperty(string assemblyName, string ownerTypeFullName, string propName, string value, BamlAttributeUsage propUsage) { this.VerifyWriteState(); BamlRecordType bamlRecordType = this.PeekRecordType(); if (bamlRecordType != BamlRecordType.ElementStart) { throw new InvalidOperationException(SR.Get("BamlWriterNoInElement", new object[] { "WriteProperty", bamlRecordType.ToString() })); } object obj; Type declaringType; this.GetDpOrPi(assemblyName, ownerTypeFullName, propName, out obj, out declaringType); AttributeData attributeData = this._extensionParser.IsMarkupExtensionAttribute(declaringType, propName, ref value, 0, 0, 0, obj); if (attributeData == null) { XamlPropertyNode xamlPropertyNode = new XamlPropertyNode(0, 0, this._depth, obj, assemblyName, ownerTypeFullName, propName, value, propUsage, false); Type propertyType = XamlTypeMapper.GetPropertyType(obj); if (propertyType == typeof(DependencyProperty)) { Type declaringType2 = null; this._dpProperty = XamlTypeMapper.ParsePropertyName(this._parserContext, value, ref declaringType2); if (this._bamlRecordWriter != null && this._dpProperty != null) { short valueId; short attributeOrTypeId = this._parserContext.MapTable.GetAttributeOrTypeId(this._bamlRecordWriter.BinaryWriter, declaringType2, this._dpProperty.Name, out valueId); if (attributeOrTypeId < 0) { xamlPropertyNode.ValueId = attributeOrTypeId; xamlPropertyNode.MemberName = null; } else { xamlPropertyNode.ValueId = valueId; xamlPropertyNode.MemberName = this._dpProperty.Name; } } } else if (this._dpProperty != null) { xamlPropertyNode.ValuePropertyType = this._dpProperty.PropertyType; xamlPropertyNode.ValuePropertyMember = this._dpProperty; xamlPropertyNode.ValuePropertyName = this._dpProperty.Name; xamlPropertyNode.ValueDeclaringType = this._dpProperty.OwnerType; string fullName = this._dpProperty.OwnerType.Assembly.FullName; this._dpProperty = null; } this._bamlRecordWriter.WriteProperty(xamlPropertyNode); return; } if (!attributeData.IsSimple) { this._extensionParser.CompileAttribute(this._markupExtensionNodes, attributeData); return; } if (attributeData.IsTypeExtension) { Type typeFromBaseString = this._xamlTypeMapper.GetTypeFromBaseString(attributeData.Args, this._parserContext, true); XamlPropertyWithTypeNode xamlPropertyWithType = new XamlPropertyWithTypeNode(0, 0, this._depth, obj, assemblyName, ownerTypeFullName, propName, typeFromBaseString.FullName, typeFromBaseString.Assembly.FullName, typeFromBaseString, string.Empty, string.Empty); this._bamlRecordWriter.WritePropertyWithType(xamlPropertyWithType); return; } XamlPropertyWithExtensionNode xamlPropertyNode2 = new XamlPropertyWithExtensionNode(0, 0, this._depth, obj, assemblyName, ownerTypeFullName, propName, attributeData.Args, attributeData.ExtensionTypeId, attributeData.IsValueNestedExtension, attributeData.IsValueTypeExtension); this._bamlRecordWriter.WritePropertyWithExtension(xamlPropertyNode2); }