Exemple #1
0
        // The ordering of how things are created and which methods are called are ABSOLUTELY critical
        // Getting this order slightly off will result in several issues that are very hard to debug.
        //
        // The order must be:
        //      Register name to the TemplateNameScope (Either the real name specified by x:Name or
        //              RuntimeNameProperty or a fake name that we have to generate to call
        //              RegisterName.  This is CRUCIAL since RegisterName sets the TemplatedParent
        //              and the TemplateChildIndex on the object
        //      If we're dealing with the root, wire the object to the parent (via FE.TemplateChild
        //          if we're dealing with an FE as the container or using FEF if it's not an FE)
        //      Invalidate properties on the object
        private DependencyObject LoadOptimizedTemplateContent(DependencyObject container,
            IComponentConnector componentConnector,
            IStyleConnector styleConnector, List<DependencyObject> affectedChildren, UncommonField<Hashtable> templatedNonFeChildrenField)
        {
            if (Names == null)
            {
                Names = new XamlContextStack<Frame>(() => new Frame());
            }
            DependencyObject rootObject = null;

            if (TraceMarkup.IsEnabled)
            {
                TraceMarkup.Trace(TraceEventType.Start, TraceMarkup.Load);
            }

            FrameworkElement feContainer = container as FrameworkElement;
            bool isTemplatedParentAnFE = feContainer != null;

            TemplateNameScope nameScope = new TemplateNameScope(container, affectedChildren, this);
            XamlObjectWriterSettings settings = System.Windows.Markup.XamlReader.CreateObjectWriterSettings(_templateHolder.ObjectWriterParentSettings);
            settings.ExternalNameScope = nameScope;
            settings.RegisterNamesOnExternalNamescope = true;

            IEnumerator<String> nameEnumerator = ChildNames.GetEnumerator();

            // Delegate for AfterBeginInit event
            settings.AfterBeginInitHandler =
                delegate(object sender, System.Xaml.XamlObjectEventArgs args)
                {
                    HandleAfterBeginInit(args.Instance, ref rootObject, container, feContainer, nameScope, nameEnumerator);
                    if (XamlSourceInfoHelper.IsXamlSourceInfoEnabled)
                    {
                        XamlSourceInfoHelper.SetXamlSourceInfo(args.Instance, args, null);
                    }
                };
            // Delegate for BeforeProperties event
            settings.BeforePropertiesHandler =
                delegate(object sender, System.Xaml.XamlObjectEventArgs args)
                {
                    HandleBeforeProperties(args.Instance, ref rootObject, container, feContainer, nameScope);
                };
            // Delegate for XamlSetValue event
            settings.XamlSetValueHandler =
                delegate(object sender, System.Windows.Markup.XamlSetValueEventArgs setArgs)
            {
                setArgs.Handled = ReceivePropertySet(sender, setArgs.Member, setArgs.Value, container);
            };

            XamlObjectWriter objectWriter = _templateHolder.ObjectWriterFactory.GetXamlObjectWriter(settings);

            try
            {
                LoadTemplateXaml(objectWriter);
            }
            finally
            {
                if (TraceMarkup.IsEnabled)
                {
                    TraceMarkup.Trace(TraceEventType.Stop, TraceMarkup.Load, rootObject);
                }
            }
            return rootObject;
        }
        // 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;
        }
Exemple #3
0
        private void HandleAfterBeginInit(object createdObject,
            ref DependencyObject rootObject,
            DependencyObject container,
            FrameworkElement feContainer,
            TemplateNameScope nameScope,
            IEnumerator<String> nameEnumerator)
        {
            // We need to wire names for all FEs and FCEs.  We do this as soon as the object is
            // initalized since it needs to happen before we assign any properties or wire to the parent
            if (!Names.CurrentFrame.InsideNameScope &&
                (createdObject is FrameworkElement || createdObject is FrameworkContentElement))
            {
                nameEnumerator.MoveNext();
                nameScope.RegisterNameInternal(nameEnumerator.Current, createdObject);
            }

            Names.CurrentFrame.Instance = createdObject;
        }
        // Token: 0x06000691 RID: 1681 RVA: 0x00014908 File Offset: 0x00012B08
        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 frameworkElement = container as FrameworkElement;
            bool             flag             = frameworkElement != null;
            DependencyObject dependencyObject = null;

            if (this._text != null)
            {
                IAddChild addChild = parent as IAddChild;
                if (addChild == null)
                {
                    throw new InvalidOperationException(SR.Get("TypeMustImplementIAddChild", new object[]
                    {
                        parent.GetType().Name
                    }));
                }
                addChild.AddText(this._text);
            }
            else
            {
                dependencyObject = this.CreateDependencyObject();
                EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordXamlBaml, EventTrace.Level.Verbose, EventTrace.Event.WClientParseFefCrInstEnd);
                FrameworkObject frameworkObject = new FrameworkObject(dependencyObject);
                Visual3D        visual3D        = null;
                bool            flag2           = false;
                if (!frameworkObject.IsValid)
                {
                    visual3D = (dependencyObject as Visual3D);
                    if (visual3D != null)
                    {
                        flag2 = true;
                    }
                }
                bool isFE = frameworkObject.IsFE;
                if (!flag2)
                {
                    FrameworkElementFactory.NewNodeBeginInit(isFE, frameworkObject.FE, frameworkObject.FCE);
                    if (StyleHelper.HasResourceDependentsForChild(this._childIndex, ref resourceDependents))
                    {
                        frameworkObject.HasResourceReference = true;
                    }
                    FrameworkElementFactory.UpdateChildChains(this._childName, this._childIndex, isFE, frameworkObject.FE, frameworkObject.FCE, affectedChildren, ref noChildIndexChildren);
                    FrameworkElementFactory.NewNodeStyledParentProperty(container, flag, isFE, frameworkObject.FE, frameworkObject.FCE);
                    if (this._childIndex != -1)
                    {
                        StyleHelper.CreateInstanceDataForChild(dataField, container, dependencyObject, this._childIndex, this._frameworkTemplate.HasInstanceValues, ref this._frameworkTemplate.ChildRecordFromChildIndex);
                    }
                    if (this.HasLoadedChangeHandler)
                    {
                        BroadcastEventHelper.AddHasLoadedChangeHandlerFlagInAncestry(dependencyObject);
                    }
                }
                else if (this._childName != null)
                {
                    affectedChildren.Add(dependencyObject);
                }
                else
                {
                    if (noChildIndexChildren == null)
                    {
                        noChildIndexChildren = new List <DependencyObject>(4);
                    }
                    noChildIndexChildren.Add(dependencyObject);
                }
                if (container == parent)
                {
                    TemplateNameScope value = new TemplateNameScope(container);
                    NameScope.SetNameScope(dependencyObject, value);
                    if (flag)
                    {
                        frameworkElement.TemplateChild = frameworkObject.FE;
                    }
                    else
                    {
                        FrameworkElementFactory.AddNodeToLogicalTree((FrameworkContentElement)parent, this._type, isFE, frameworkObject.FE, frameworkObject.FCE);
                    }
                }
                else
                {
                    this.AddNodeToParent(parent, frameworkObject);
                }
                if (!flag2)
                {
                    StyleHelper.InvalidatePropertiesOnTemplateNode(container, frameworkObject, this._childIndex, ref this._frameworkTemplate.ChildRecordFromChildIndex, false, this);
                }
                else
                {
                    for (int i = 0; i < this.PropertyValues.Count; i++)
                    {
                        if (this.PropertyValues[i].ValueType != PropertyValueType.Set)
                        {
                            throw new NotSupportedException(SR.Get("Template3DValueOnly", new object[]
                            {
                                this.PropertyValues[i].Property
                            }));
                        }
                        object    obj       = this.PropertyValues[i].ValueInternal;
                        Freezable freezable = obj as Freezable;
                        if (freezable != null && !freezable.CanFreeze)
                        {
                            obj = freezable.Clone();
                        }
                        MarkupExtension markupExtension = obj as MarkupExtension;
                        if (markupExtension != null)
                        {
                            ProvideValueServiceProvider provideValueServiceProvider = new ProvideValueServiceProvider();
                            provideValueServiceProvider.SetData(visual3D, this.PropertyValues[i].Property);
                            obj = markupExtension.ProvideValue(provideValueServiceProvider);
                        }
                        visual3D.SetValue(this.PropertyValues[i].Property, obj);
                    }
                }
                for (FrameworkElementFactory frameworkElementFactory = this._firstChild; frameworkElementFactory != null; frameworkElementFactory = frameworkElementFactory._nextSibling)
                {
                    frameworkElementFactory.InstantiateTree(dataField, container, dependencyObject, affectedChildren, ref noChildIndexChildren, ref resourceDependents);
                }
                if (!flag2)
                {
                    FrameworkElementFactory.NewNodeEndInit(isFE, frameworkObject.FE, frameworkObject.FCE);
                }
            }
            return(dependencyObject);
        }