// Token: 0x06002260 RID: 8800 RVA: 0x000AACD8 File Offset: 0x000A8ED8
        public virtual object GetService(Type serviceType)
        {
            if (serviceType == typeof(IUriContext))
            {
                return(this._parserContext);
            }
            if (serviceType == typeof(string))
            {
                return(this._attribStringValue);
            }
            ProvideValueServiceProvider provideValueProvider = this._parserContext.ProvideValueProvider;

            return(provideValueProvider.GetService(serviceType));
        }
示例#2
0
        //+----------------------------------------------------------------------------------------------------------------
        //
        //  SetTemplateParentValues
        //
        //  This method takes the "template parent values" (those that look like local values in the template), which
        //  are ordinarily shared, and sets them as local values on the FE/FCE that was just created.  This is used
        //  during serialization.
        //
        //+----------------------------------------------------------------------------------------------------------------

        internal static void SetTemplateParentValues(
                                                          string name,
                                                          object element,
                                                          FrameworkTemplate frameworkTemplate,
                                                          ref ProvideValueServiceProvider provideValueServiceProvider)
        {
            int childIndex;

            // Loop through the shared values, and set them onto the element.

            FrugalStructList<ChildRecord> childRecordFromChildIndex;
            HybridDictionary childIndexFromChildName;

            // Seal the template, and get the name->index and index->ChildRecord mappings

            if (!frameworkTemplate.IsSealed)
            {
                frameworkTemplate.Seal();
            }

            childIndexFromChildName = frameworkTemplate.ChildIndexFromChildName;
            childRecordFromChildIndex = frameworkTemplate.ChildRecordFromChildIndex;


            // Calculate the child index

            childIndex = StyleHelper.QueryChildIndexFromChildName(name, childIndexFromChildName);

            // Do we have a ChildRecord for this index (i.e., there's some property set on it)?

            if (childIndex < childRecordFromChildIndex.Count)
            {
                // Yes, get the record.

                ChildRecord child = (ChildRecord)childRecordFromChildIndex[childIndex];

                // Loop through the properties which are in some way set on this child

                for (int i = 0; i < child.ValueLookupListFromProperty.Count; i++)
                {
                    // And for each of those properties, loop through the potential values specified in the template
                    // for that property on that child.

                    for (int j = 0; j < child.ValueLookupListFromProperty.Entries[i].Value.Count; j++)
                    {
                        // Get this value (in valueLookup)

                        ChildValueLookup valueLookup;
                        valueLookup = (ChildValueLookup)child.ValueLookupListFromProperty.Entries[i].Value.List[j];

                        // See if this value is one that is considered to be locally set on the child element

                        if (valueLookup.LookupType == ValueLookupType.Simple
                            ||
                            valueLookup.LookupType == ValueLookupType.Resource
                            ||
                            valueLookup.LookupType == ValueLookupType.TemplateBinding)
                        {

                            // This shared value is for this element, so we'll set it.

                            object value = valueLookup.Value;

                            // If this is a TemplateBinding, put on an expression for it, so that it can
                            // be represented correctly (e.g. for serialization).  Otherwise, keep it as an ME.

                            if (valueLookup.LookupType == ValueLookupType.TemplateBinding)
                            {
                                value = new TemplateBindingExpression(value as TemplateBindingExtension);

                            }

                            // Dynamic resources need to be converted to an expression also.

                            else if (valueLookup.LookupType == ValueLookupType.Resource)
                            {
                                value = new ResourceReferenceExpression(value);
                            }

                            // Bindings are handled as just an ME

                            // Set the value directly onto the element.

                            MarkupExtension me = value as MarkupExtension;

                            if (me != null)
                            {
                                // This is provided for completeness, but really there's only a few
                                // MEs that survive TemplateBamlRecordReader.  E.g. NullExtension would
                                // have been converted to a null by now.  There's only a few MEs that
                                // are preserved, e.g. Binding and DynamicResource.  Other MEs, such as
                                // StaticResource, wouldn't be able to ProvideValue here, because we don't
                                // have a ParserContext.

                                if (provideValueServiceProvider == null)
                                {
                                    provideValueServiceProvider = new ProvideValueServiceProvider();
                                }

                                provideValueServiceProvider.SetData(element, valueLookup.Property);
                                value = me.ProvideValue(provideValueServiceProvider);
                                provideValueServiceProvider.ClearData();
                            }

                            (element as DependencyObject).SetValue(valueLookup.Property, value); //sharedDp.Dp, value );

                        }
                    }
                }
            }
        }
        // Instantiate a tree.  This is a recursive routine that will build the
        //  subtree via calls to itself.  The root node being instantiated will
        //  have identical references for the "container" and "parent" parameters.
        // The "affectedChildren" and "noChildIndexChildren" parameters refer to the children
        //  chain for the "container" object.  This chain will have all the
        //  children - not just the immediate children.  The node being
        //  instantiated here will be added to this chain.
        // The tree is instantiated in a depth-first traversal, so children nodes
        //  are added to the chain in depth-first order as well.
        //[CodeAnalysis("AptcaMethodsShouldOnlyCallAptcaMethods")] //Tracking Bug: 29647
        internal DependencyObject InstantiateTree(
                UncommonField<HybridDictionary[]>           dataField,
                DependencyObject                            container,
                DependencyObject                            parent,
                List<DependencyObject>                      affectedChildren,
            ref List<DependencyObject>                      noChildIndexChildren,
            ref FrugalStructList<ChildPropertyDependent>    resourceDependents)
        {
            EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordXamlBaml, EventTrace.Level.Verbose, EventTrace.Event.WClientParseFefCrInstBegin);

            FrameworkElement containerAsFE = container as FrameworkElement;
            bool isContainerAnFE = containerAsFE != null;

            DependencyObject treeNode = null;
            // If we have text, just add it to the parent.  Otherwise create the child
            // subtree
            if (_text != null)
            {
                // of FrameworkContentElement parent.  This is the logical equivalent
                // to what happens when adding a child to a visual collection.
                IAddChild addChildParent = parent as IAddChild;

                if (addChildParent == null)
                {
                    throw new InvalidOperationException(SR.Get(SRID.TypeMustImplementIAddChild,
                                                         parent.GetType().Name));
                }
                else
                {
                    addChildParent.AddText(_text);
                }
            }
            else
            {
                // Factory create instance
                treeNode = CreateDependencyObject();

                EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordXamlBaml, EventTrace.Level.Verbose, EventTrace.Event.WClientParseFefCrInstEnd);

                // The tree node is either a FrameworkElement or a FrameworkContentElement.
                //  we'll deal with one or the other...
                FrameworkObject treeNodeFO = new FrameworkObject(treeNode);

                Visual3D treeNodeVisual3D = null;
                bool treeNodeIsVisual3D = false;

                if (!treeNodeFO.IsValid)
                {
                    // If it's neither of those, we have special support for Visual3D

                    treeNodeVisual3D = treeNode as Visual3D;
                    if (treeNodeVisual3D != null)
                        treeNodeIsVisual3D = true;
                }

                Debug.Assert( treeNodeFO.IsValid || (treeNodeVisual3D != null),
                    "We should not be trying to instantiate a node that is neither FrameworkElement nor FrameworkContentElement.  A type check should have been done when Type is set");

                // And here's the bool we'll use to make the decision.
                bool treeNodeIsFE = treeNodeFO.IsFE;

                // Handle FE/FCE-specific optimizations

                if (!treeNodeIsVisual3D)
                {
                    // Postpone "Initialized" event
                    NewNodeBeginInit( treeNodeIsFE, treeNodeFO.FE, treeNodeFO.FCE );

                    // Set the resource reference flags
                    if (StyleHelper.HasResourceDependentsForChild(_childIndex, ref resourceDependents))
                    {
                        treeNodeFO.HasResourceReference = true;
                    }

                    // Update the two chains that tracks all the nodes created
                    //  from all the FrameworkElementFactory of this Style.
                    UpdateChildChains( _childName, _childIndex,
                        treeNodeIsFE, treeNodeFO.FE, treeNodeFO.FCE,
                        affectedChildren, ref noChildIndexChildren );

                    // All FrameworkElementFactory-created elements point to the object
                    //  whose Style.VisualTree definition caused all this to occur
                    NewNodeStyledParentProperty( container, isContainerAnFE, treeNodeIsFE, treeNodeFO.FE, treeNodeFO.FCE );

                    // Initialize the per-instance data for the new element.  This
                    // needs to be done before any properties are invalidated.
                    if (_childIndex != -1)
                    {
                        Debug.Assert( _frameworkTemplate != null );

                        StyleHelper.CreateInstanceDataForChild(dataField, container, treeNode, _childIndex,
                            _frameworkTemplate.HasInstanceValues, ref _frameworkTemplate.ChildRecordFromChildIndex);
                    }

                    // If this element needs to know about the Loaded or Unloaded events, set the optimization
                    // bit in the element

                    if (HasLoadedChangeHandler)
                    {
                        BroadcastEventHelper.AddHasLoadedChangeHandlerFlagInAncestry(treeNode);
                    }
                }
                else
                {
                    if (_childName != null)
                    {
                        // Add this instance to the child index chain so that it may
                        // be tracked by the style

                        affectedChildren.Add(treeNode);
                    }
                    else
                    {
                        // Child nodes with no _childID (hence no _childIndex) are
                        //  tracked on a separate chain that will be appended to the
                        //  main chain for cleanup purposes.
                        if (noChildIndexChildren == null)
                        {
                            noChildIndexChildren = new List<DependencyObject>(4);
                        }

                        noChildIndexChildren.Add(treeNode);
                    }
                }


                // New node is initialized, build tree top down
                // (Node added before children of node)
                if (container == parent)
                {
                    // Set the NameScope on the root of the Template generated tree
                    TemplateNameScope templateNameScope = new TemplateNameScope(container);
                    NameScope.SetNameScope(treeNode, templateNameScope);

                    // This is the root of the tree
                    if (isContainerAnFE)
                    {
                        // The root is added to the Visual tree (not logical) for the
                        // case of FrameworkElement parents
                        containerAsFE.TemplateChild = treeNodeFO.FE;
                    }
                    else
                    {
                        // The root is added to the logical tree for the case
                        // of FrameworkContentElement parent.  This is the logical equivalent
                        // to what happens when adding a child to a visual collection.
                        AddNodeToLogicalTree( (FrameworkContentElement)parent, _type,
                            treeNodeIsFE, treeNodeFO.FE, treeNodeFO.FCE );
                    }
                }
                else
                {
                    // Call parent IAddChild to add treeNodeFO
                    AddNodeToParent( parent, treeNodeFO );
                }

                // Either set properties or invalidate them, depending on the type

                if (!treeNodeIsVisual3D)
                {
                    // For non-3D content, we need to invalidate any properties that
                    // came from FrameworkElementFactory.SetValue or VisulaTrigger.SetValue
                    // so that they can get picked up.

                    Debug.Assert( _frameworkTemplate != null );
                    StyleHelper.InvalidatePropertiesOnTemplateNode(
                                container,
                                treeNodeFO,
                                _childIndex,
                                ref _frameworkTemplate.ChildRecordFromChildIndex,
                                false /*isDetach*/,
                                this);

                }
                else
                {
                    // For 3D, which doesn't understand templates, we set the properties directly
                    // onto the newly-instantiated element.

                    for (int i = 0; i < PropertyValues.Count; i++)
                    {
                        if (PropertyValues[i].ValueType == PropertyValueType.Set)
                        {
                            // Get the value out of the table.
                            object o = PropertyValues[i].ValueInternal;


                            // If it's a freezable that can't be frozen, it's probably not sharable,
                            // so we make a copy of it.
                            Freezable freezableValue = o as Freezable;
                            if (freezableValue != null && !freezableValue.CanFreeze)
                            {
                                o = freezableValue.Clone();
                            }

                            // Or, if it's a markup extension, get the value
                            // to set on this property from the MarkupExtension itself.
                            MarkupExtension me = o as MarkupExtension;
                            if (me != null)
                            {
                                ProvideValueServiceProvider serviceProvider = new ProvideValueServiceProvider();
                                serviceProvider.SetData( treeNodeVisual3D, PropertyValues[i].Property );
                                o = me.ProvideValue( serviceProvider );
                            }

                            // Finally, set the value onto the object.
                            treeNodeVisual3D.SetValue(PropertyValues[i].Property, o);

                        }

                        else
                        {
                            // We don't support resource references, triggers, etc within the 3D content
                            throw new NotSupportedException(SR.Get(SRID.Template3DValueOnly, PropertyValues[i].Property) );

                        }

                    }
                }


                // Build child tree from factories
                FrameworkElementFactory childFactory = _firstChild;
                while (childFactory != null)
                {
                    childFactory.InstantiateTree(
                        dataField,
                        container,
                        treeNode,
                        affectedChildren,
                        ref noChildIndexChildren,
                        ref resourceDependents);

                    childFactory = childFactory._nextSibling;
                }

                if (!treeNodeIsVisual3D)
                {
                    // Fire "Initialized" event
                    NewNodeEndInit( treeNodeIsFE, treeNodeFO.FE, treeNodeFO.FCE );
                }
            }
            return treeNode;
        }
        //
        //  This method
        //  1. Retrieves an instance value from per-instance StyleData.
        //  2. Creates the StyleData if this is the first request.
        //
        internal static object GetInstanceValue(
            UncommonField<HybridDictionary []>  dataField,
            DependencyObject            container,
            FrameworkElement            feChild,
            FrameworkContentElement     fceChild,
            int                         childIndex,
            DependencyProperty          dp,
            int                         i,
            ref EffectiveValueEntry     entry)
        {
            object rawValue = entry.Value;
            DependencyObject child = null;

            FrameworkElement feContainer;
            FrameworkContentElement fceContainer;
            Helper.DowncastToFEorFCE(container, out feContainer, out fceContainer, true);

            HybridDictionary[] styleData = (dataField != null) ? dataField.GetValue(container) : null;
            HybridDictionary instanceValues = (styleData != null) ? styleData[(int)InstanceStyleData.InstanceValues] : null;
            InstanceValueKey key = new InstanceValueKey(childIndex, dp.GlobalIndex, i);

            object value = (instanceValues != null)? instanceValues[key] : null;
            bool isRequestingExpression = (feChild != null) ? feChild.IsRequestingExpression : fceChild.IsRequestingExpression;

            if (value == null)
            {
                value = NotYetApplied;
            }

            // if the value is a detached expression, replace it with a new one
            Expression expr = value as Expression;
            if (expr != null && expr.HasBeenDetached)
            {
                value = NotYetApplied;
            }

            // if this is the first request, create the value
            if (value == NotYetApplied)
            {
                child = feChild;
                if (child == null)
                    child = fceChild;

                MarkupExtension me;
                Freezable freezable;

                if ((me = rawValue as MarkupExtension) != null)
                {
                    // exception:  if the child is not yet initialized and the request
                    // is for an expression, don't create the value.  This gives the parser
                    // a chance to set local values, to override the style-defined values.
                    if (isRequestingExpression)
                    {
                        bool isInitialized = (feChild != null) ? feChild.IsInitialized : fceChild.IsInitialized;
                        if (!isInitialized)
                        {
                            return DependencyProperty.UnsetValue;
                        }
                    }

                    ProvideValueServiceProvider provideValueServiceProvider = new ProvideValueServiceProvider();
                    provideValueServiceProvider.SetData( child, dp );
                    value = me.ProvideValue(provideValueServiceProvider);
                }
                else if ((freezable = rawValue as Freezable) != null)
                {
                    value = freezable.Clone();
                    child.ProvideSelfAsInheritanceContext(value, dp);
                }

                // store it in per-instance StyleData (even if it's DependencyProperty.UnsetValue)
                Debug.Assert(value != NotYetApplied, "attempt to retrieve instance value that was never set");
                instanceValues[key] = value;

                if (value != DependencyProperty.UnsetValue)
                {
                    expr = value as Expression;
                    // if the instance value is an expression, attach it
                    if (expr != null)
                    {
                        expr.OnAttach(child, dp);
                    }
                }
            }

            // if the value is an Expression (and we're being asked for the real value),
            // delegate to the expression.
            if (expr != null)
            {
                if (!isRequestingExpression)
                {
                    if (child == null)
                    {
                        child = feChild;
                        if (child == null)
                            child = fceChild;
                    }

                    entry.ResetValue(DependencyObject.ExpressionInAlternativeStore, true);
                    entry.SetExpressionValue(expr.GetValue(child, dp), DependencyObject.ExpressionInAlternativeStore);
                }
                else
                {
                    entry.Value = value;
                }
            }
            else
            {
                entry.Value = value;
            }

            return value;
        }