private void Process_OptimizedStaticResource() { byte flags = _binaryReader.ReadByte(); short keyId = _binaryReader.ReadInt16(); var optimizedStaticResource = new OptimizedStaticResource(flags, keyId); if (_isBinaryProvider) { // Compute the Value from the ValueId // This code could/should be in "OptimizedStaticResource.Value", but that class // doesn't have access to the BamlSchemaContext or the GetStaticExtension() // method below. if (optimizedStaticResource.IsKeyTypeExtension) { XamlType xamlType = BamlSchemaContext.GetXamlType(keyId); optimizedStaticResource.KeyValue = xamlType.UnderlyingType; } else if (optimizedStaticResource.IsKeyStaticExtension) { Type memberType; object providedValue; string propertyName = GetStaticExtensionValue(keyId, out memberType, out providedValue); if (providedValue == null) { var staticExtension = new System.Windows.Markup.StaticExtension(propertyName); staticExtension.MemberType = memberType; providedValue = staticExtension.ProvideValue(null); } optimizedStaticResource.KeyValue = providedValue; } else { optimizedStaticResource.KeyValue = _context.SchemaContext.GetString(keyId); } } var staticResources = _context.LastKey.StaticResources; staticResources.Add(optimizedStaticResource); }
// (property, markup extension, value) including the well known WPF TemplateBinding, StaticResource or DynamicResource markup extensions // Writes out a property with a markup extension. However, if there is a x:Static, Type, or TemplateBinding inside the ME, we code that // specially. e.g. Property="{FooExtension {x:Static f:Foo.Bar}}" would be written out as one Baml Record private void Process_PropertyWithExtension() { Common_Process_Property(); short propertyId = _binaryReader.ReadInt16(); Int16 extensionId = _binaryReader.ReadInt16(); Int16 valueId = _binaryReader.ReadInt16(); XamlMember property = GetProperty(propertyId, _context.CurrentFrame.XamlType); Int16 extensionTypeId = (Int16)(extensionId & ExtensionIdMask); XamlType extensionType = BamlSchemaContext.GetXamlType((short)(-extensionTypeId)); bool isValueTypeExtension = (extensionId & TypeExtensionValueMask) == TypeExtensionValueMask; bool isValueStaticExtension = (extensionId & StaticExtensionValueMask) == StaticExtensionValueMask; Type typeExtensionType = null; Type memberType = null; object value = null; // Write out the main Extension {FooExtension _xamlNodesWriter.WriteStartMember(property); // If we're in the binary case, we try to write the value out directly bool handled = false; if (_isBinaryProvider) { object param = null; object providedValue = null; if (isValueStaticExtension) { Type ownerType = null; string staticExParam = GetStaticExtensionValue(valueId, out ownerType, out providedValue); // If it's a Known command or a SystemResourceKey, send the value across directly if (providedValue != null) { param = providedValue; } else { System.Windows.Markup.StaticExtension staticExtension = new System.Windows.Markup.StaticExtension(staticExParam); Debug.Assert(ownerType != null); staticExtension.MemberType = ownerType; param = staticExtension.ProvideValue(null); // if MemberType is set we don't need ITypeResolver } } else if (isValueTypeExtension) { param = BamlSchemaContext.GetXamlType(valueId).UnderlyingType; } else { // For all other scenarios, we want to just write out the type if (extensionTypeId == Baml2006SchemaContext.TemplateBindingTypeId) { param = _context.SchemaContext.GetDependencyProperty(valueId); } else if (extensionTypeId == Baml2006SchemaContext.StaticExtensionTypeId) { param = GetStaticExtensionValue(valueId, out memberType, out providedValue); } else if (extensionTypeId == Baml2006SchemaContext.TypeExtensionTypeId) { param = BamlSchemaContext.GetXamlType(valueId).UnderlyingType; } else { param = BamlSchemaContext.GetString(valueId); } } // Doing == comparison since we only know how to create those quickly here if (extensionTypeId == Baml2006SchemaContext.DynamicResourceTypeId) { value = new DynamicResourceExtension(param); handled = true; } else if (extensionTypeId == Baml2006SchemaContext.StaticResourceTypeId) { value = new StaticResourceExtension(param); handled = true; } else if (extensionTypeId == Baml2006SchemaContext.TemplateBindingTypeId) { value = new TemplateBindingExtension((DependencyProperty)param); handled = true; } else if (extensionTypeId == Baml2006SchemaContext.TypeExtensionTypeId) { value = param; handled = true; } else if (extensionTypeId == Baml2006SchemaContext.StaticExtensionTypeId) { if (providedValue != null) { value = providedValue; } else { System.Windows.Markup.StaticExtension staticExtension = new System.Windows.Markup.StaticExtension((string)param); staticExtension.MemberType = memberType; value = staticExtension; } handled = true; } if (handled) { _xamlNodesWriter.WriteValue(value); _xamlNodesWriter.WriteEndMember(); return; } } if (!handled) { _xamlNodesWriter.WriteStartObject(extensionType); _xamlNodesWriter.WriteStartMember(XamlLanguage.PositionalParameters); if (isValueStaticExtension) { Type ownerType = null; object providedValue; value = GetStaticExtensionValue(valueId, out ownerType, out providedValue); // If it's a Known command or a SystemResourceKey, send the value across directly if (providedValue != null) { _xamlNodesWriter.WriteValue(providedValue); } else { // Special case for {x:Static ...} inside the main extension _xamlNodesWriter.WriteStartObject(XamlLanguage.Static); _xamlNodesWriter.WriteStartMember(XamlLanguage.PositionalParameters); _xamlNodesWriter.WriteValue(value); _xamlNodesWriter.WriteEndMember(); // In BAML scenario, we want to pass MemberType directly along cuz it's optimal if (ownerType != null) { _xamlNodesWriter.WriteStartMember(BamlSchemaContext.StaticExtensionMemberTypeProperty); _xamlNodesWriter.WriteValue(ownerType); _xamlNodesWriter.WriteEndMember(); } _xamlNodesWriter.WriteEndObject(); } } else if (isValueTypeExtension) { // Special case for {x:Type ...} inside the main extension _xamlNodesWriter.WriteStartObject(XamlLanguage.Type); _xamlNodesWriter.WriteStartMember(BamlSchemaContext.TypeExtensionTypeProperty); typeExtensionType = BamlSchemaContext.GetXamlType(valueId).UnderlyingType; if (_isBinaryProvider) { _xamlNodesWriter.WriteValue(typeExtensionType); } else { _xamlNodesWriter.WriteValue(Logic_GetFullyQualifiedNameForType(BamlSchemaContext.GetXamlType(valueId))); } _xamlNodesWriter.WriteEndMember(); _xamlNodesWriter.WriteEndObject(); } else { // For all other scenarios, we want to just write out the type if (extensionTypeId == Baml2006SchemaContext.TemplateBindingTypeId) { if (this._isBinaryProvider) { value = BitConverter.GetBytes(valueId); } else { value = Logic_GetFullyQualifiedNameForMember(valueId); } } else if (extensionTypeId == Baml2006SchemaContext.StaticExtensionTypeId) { // If we're here, that means we're not a binary provider which means we can't // support writing the provided value out directly. object providedValue; value = GetStaticExtensionValue(valueId, out memberType, out providedValue); } else if (extensionTypeId == Baml2006SchemaContext.TypeExtensionTypeId) { value = BamlSchemaContext.GetXamlType(valueId).UnderlyingType; } else { value = BamlSchemaContext.GetString(valueId); } _xamlNodesWriter.WriteValue(value); } _xamlNodesWriter.WriteEndMember(); if (memberType != null) { _xamlNodesWriter.WriteStartMember(BamlSchemaContext.StaticExtensionMemberTypeProperty); _xamlNodesWriter.WriteValue(memberType); _xamlNodesWriter.WriteEndMember(); } } _xamlNodesWriter.WriteEndObject(); _xamlNodesWriter.WriteEndMember(); }