internal SpanVector( object?defaultObject, FrugalStructList <Span> spans = new FrugalStructList <Span>()) { Default = defaultObject; _spans = spans; }
protected DescendentsWalkerBase(TreeWalkPriority priority) { _startNode = null; _priority = priority; _recursionDepth = 0; _nodes = new FrugalStructList <DependencyObject>(); }
protected DescendentsWalkerBase(TreeWalkPriority priority) { _startNode = null; _priority = priority; _recursionDepth = 0; _nodes = new FrugalStructList<DependencyObject>(); }
/// <summary> /// Removes all elements from the list /// </summary> public void Clear() { WritePreamble(); // As part of Clear()'ing the collection, we will iterate it and call // OnFreezablePropertyChanged and OnRemove for each item. // However, OnRemove assumes that the item to be removed has already been // pulled from the underlying collection. To statisfy this condition, // we store the old collection and clear _collection before we call these methods. // As Clear() semantics do not include TrimToFit behavior, we create the new // collection storage at the same size as the previous. This is to provide // as close as possible the same perf characteristics as less complicated collections. FrugalStructList <Geometry> oldCollection = _collection; _collection = new FrugalStructList <Geometry>(_collection.Capacity); for (int i = oldCollection.Count - 1; i >= 0; i--) { OnFreezablePropertyChanged(/* oldValue = */ oldCollection[i], /* newValue = */ null); // Fire the OnRemove handlers for each item. We're not ensuring that // all OnRemove's get called if a resumable exception is thrown. // At this time, these call-outs are not public, so we do not handle exceptions. OnRemove(/* oldValue */ oldCollection[i]); } ++_version; WritePostscript(); }
/// <summary> /// ShrinkToFit - Shrink the data to fit in exactly one chunk /// </summary> internal void ShrinkToFit() { Debug.Assert(_chunkList.Count != 0); if (_chunkList.Count > 1 || _chunkList[0].Length != _currOffset) { byte [] buffer = new byte[_currOffset]; unsafe { fixed(byte *pbData = buffer) { ReadData(pbData, 0, _currOffset); } } ByteStreamGeometryContext.ReturnChunkToPool(_chunkList[0]); // The common case is a single chunk in a SingleItemList held by the FrugalStructList. // Avoid tearing down and recreating the SingleItemList by updating the lone element in-place, // especially since ShrinkToFit is called from DisposeCore when this object is about to die. if (_chunkList.Count == 1) { _chunkList[0] = buffer; } else { _chunkList = new FrugalStructList <byte[]>(); _chunkList.Add(buffer); } } }
private SpanVector( T defaultValue, FrugalStructList <Span <T> > spanList ) { _defaultValue = defaultValue; _spanList = spanList; }
internal SpanVector( object defaultObject, FrugalStructList <Span> spans ) { _defaultObject = defaultObject; _spans = spans; }
internal SpanVector( object defaultObject, FrugalStructList<Span> spans ) { _defaultObject = defaultObject; _spans = spans; }
/// <summary> /// Implementation of Freezable.CloneCurrentValueCore() /// </summary> protected override void CloneCurrentValueCore(Freezable source) { PointCollection sourcePointCollection = (PointCollection)source; base.CloneCurrentValueCore(source); int count = sourcePointCollection._collection.Count; _collection = new FrugalStructList <Point>(count); for (int i = 0; i < count; i++) { _collection.Add(sourcePointCollection._collection[i]); } }
/// <summary> /// Implementation of Freezable.GetAsFrozenCore() /// </summary> protected override void GetAsFrozenCore(Freezable source) { Point3DCollection sourcePoint3DCollection = (Point3DCollection)source; base.GetAsFrozenCore(source); int count = sourcePoint3DCollection._collection.Count; _collection = new FrugalStructList <Point3D>(count); for (int i = 0; i < count; i++) { _collection.Add(sourcePoint3DCollection._collection[i]); } }
/// <summary> /// Constructor for <see cref="EventRoute"/> given /// the associated <see cref="RoutedEvent"/> /// </summary> /// <param name="routedEvent"> /// Non-null <see cref="RoutedEvent"/> to be associated with /// this <see cref="EventRoute"/> /// </param> public EventRoute(RoutedEvent routedEvent) { if (routedEvent == null) { throw new ArgumentNullException("routedEvent"); } _routedEvent = routedEvent; // Changed the initialization size to 16 // to achieve performance gain based // on standard app behavior _routeItemList = new FrugalStructList <RouteItem>(16); _sourceItemList = new FrugalStructList <SourceItem>(16); }
/// <summary> /// Implementation of Freezable.GetCurrentValueAsFrozenCore() /// </summary> protected override void GetCurrentValueAsFrozenCore(Freezable source) { Vector3DCollection sourceVector3DCollection = (Vector3DCollection)source; base.GetCurrentValueAsFrozenCore(source); int count = sourceVector3DCollection._collection.Count; _collection = new FrugalStructList <Vector3D>(count); for (int i = 0; i < count; i++) { _collection.Add(sourceVector3DCollection._collection[i]); } }
/// <summary> /// Constructor for <see cref="EventRoute"/> given /// the associated <see cref="RoutedEvent"/> /// </summary> /// <param name="routedEvent"> /// Non-null <see cref="RoutedEvent"/> to be associated with /// this <see cref="EventRoute"/> /// </param> public EventRoute(RoutedEvent routedEvent) { if (routedEvent == null) { throw new ArgumentNullException("routedEvent"); } _routedEvent = routedEvent; // Changed the initialization size to 16 // to achieve performance gain based // on standard app behavior _routeItemList = new FrugalStructList<RouteItem>(16); _sourceItemList = new FrugalStructList<SourceItem>(16); }
/// <summary> /// Implementation of Freezable.CloneCore() /// </summary> protected override void CloneCore(Freezable source) { DoubleCollection sourceDoubleCollection = (DoubleCollection)source; base.CloneCore(source); int count = sourceDoubleCollection._collection.Count; _collection = new FrugalStructList <double>(count); for (int i = 0; i < count; i++) { _collection.Add(sourceDoubleCollection._collection[i]); } }
/// <summary> /// Implementation of Freezable.GetCurrentValueAsFrozenCore() /// </summary> protected override void GetCurrentValueAsFrozenCore(Freezable source) { TextEffectCollection sourceTextEffectCollection = (TextEffectCollection)source; base.GetCurrentValueAsFrozenCore(source); int count = sourceTextEffectCollection._collection.Count; _collection = new FrugalStructList <TextEffect>(count); for (int i = 0; i < count; i++) { TextEffect newValue = (TextEffect)sourceTextEffectCollection._collection[i].GetCurrentValueAsFrozen(); OnFreezablePropertyChanged(/* oldValue = */ null, newValue); _collection.Add(newValue); } }
/// <summary> /// Implementation of Freezable.CloneCore() /// </summary> protected override void CloneCore(Freezable source) { PathSegmentCollection sourcePathSegmentCollection = (PathSegmentCollection)source; base.CloneCore(source); int count = sourcePathSegmentCollection._collection.Count; _collection = new FrugalStructList <PathSegment>(count); for (int i = 0; i < count; i++) { PathSegment newValue = (PathSegment)sourcePathSegmentCollection._collection[i].Clone(); OnFreezablePropertyChanged(/* oldValue = */ null, newValue); _collection.Add(newValue); } }
/// <summary> /// Implementation of Freezable.CloneCurrentValueCore() /// </summary> protected override void CloneCurrentValueCore(Freezable source) { GradientStopCollection sourceGradientStopCollection = (GradientStopCollection)source; base.CloneCurrentValueCore(source); int count = sourceGradientStopCollection._collection.Count; _collection = new FrugalStructList <GradientStop>(count); for (int i = 0; i < count; i++) { GradientStop newValue = (GradientStop)sourceGradientStopCollection._collection[i].CloneCurrentValue(); OnFreezablePropertyChanged(/* oldValue = */ null, newValue); _collection.Add(newValue); } }
/// <summary> /// Implementation of Freezable.GetAsFrozenCore() /// </summary> protected override void GetAsFrozenCore(Freezable source) { GeneralTransformCollection sourceGeneralTransformCollection = (GeneralTransformCollection)source; base.GetAsFrozenCore(source); int count = sourceGeneralTransformCollection._collection.Count; _collection = new FrugalStructList <GeneralTransform>(count); for (int i = 0; i < count; i++) { GeneralTransform newValue = (GeneralTransform)sourceGeneralTransformCollection._collection[i].GetAsFrozen(); OnFreezablePropertyChanged(/* oldValue = */ null, newValue); _collection.Add(newValue); } }
// Token: 0x06002482 RID: 9346 RVA: 0x000B0F42 File Offset: 0x000AF142 internal override IEnumerable <MarkupProperty> GetProperties(bool mapToConstructorArgs) { if (this._factory.Type == null) { if (this._factory.Text != null) { yield return(new FrameworkElementFactoryStringContent(this._factory, this)); } } else { FrugalStructList <PropertyValue> propertyValues = this._factory.PropertyValues; int num; for (int i = 0; i < propertyValues.Count; i = num + 1) { if (propertyValues[i].Property != XmlAttributeProperties.XmlnsDictionaryProperty) { yield return(new FrameworkElementFactoryProperty(propertyValues[i], this)); } num = i; } ElementMarkupObject elementMarkupObject = new ElementMarkupObject(this._factory, this.Manager); foreach (MarkupProperty markupProperty in elementMarkupObject.Properties) { if (markupProperty.Name == "Triggers" && markupProperty.Name == "Storyboard") { yield return(markupProperty); } } IEnumerator <MarkupProperty> enumerator = null; if (this._factory.FirstChild != null) { if (this._factory.FirstChild.Type == null) { yield return(new FrameworkElementFactoryStringContent(this._factory.FirstChild, this)); } else { yield return(new FrameworkElementFactoryContent(this._factory, this)); } } propertyValues = default(FrugalStructList <PropertyValue>); } yield break; yield break; }
/// <summary> /// Implementation of Freezable.CloneCore() /// </summary> protected override void CloneCore(Freezable source) { GeometryCollection sourceGeometryCollection = (GeometryCollection)source; base.CloneCore(source); int count = sourceGeometryCollection._collection.Count; _collection = new FrugalStructList <Geometry>(count); for (int i = 0; i < count; i++) { Geometry newValue = (Geometry)sourceGeometryCollection._collection[i].Clone(); OnFreezablePropertyChanged(/* oldValue = */ null, newValue); _collection.Add(newValue); OnInsert(newValue); } }
/// <summary> /// Implementation of Freezable.GetAsFrozenCore() /// </summary> protected override void GetAsFrozenCore(Freezable source) { MaterialCollection sourceMaterialCollection = (MaterialCollection)source; base.GetAsFrozenCore(source); int count = sourceMaterialCollection._collection.Count; _collection = new FrugalStructList <Material>(count); for (int i = 0; i < count; i++) { Material newValue = (Material)sourceMaterialCollection._collection[i].GetAsFrozen(); OnFreezablePropertyChanged(/* oldValue = */ null, newValue); _collection.Add(newValue); OnInsert(newValue); } }
/// <summary> /// Implementation of Freezable.CloneCurrentValueCore() /// </summary> protected override void CloneCurrentValueCore(Freezable source) { Transform3DCollection sourceTransform3DCollection = (Transform3DCollection)source; base.CloneCurrentValueCore(source); int count = sourceTransform3DCollection._collection.Count; _collection = new FrugalStructList <Transform3D>(count); for (int i = 0; i < count; i++) { Transform3D newValue = (Transform3D)sourceTransform3DCollection._collection[i].CloneCurrentValue(); OnFreezablePropertyChanged(/* oldValue = */ null, newValue); _collection.Add(newValue); OnInsert(newValue); } }
internal override IEnumerable <MarkupProperty> GetProperties(bool mapToConstructorArgs) { // This #if is included to make this implementation easier to test outside the assembly. // This is the only place in ElementItem and FrameworkElementItem where internal members // are accessed that cannot be easily copied by the host. if (_factory.Type == null) { if (_factory.Text != null) { yield return(new FrameworkElementFactoryStringContent(_factory, this)); } } else { FrugalStructList <PropertyValue> propertyValues = _factory.PropertyValues; for (int i = 0; i < propertyValues.Count; i++) { if (propertyValues[i].Property != XmlAttributeProperties.XmlnsDictionaryProperty) { yield return(new FrameworkElementFactoryProperty(propertyValues[i], this)); } } ElementMarkupObject item = new ElementMarkupObject(_factory, Manager); foreach (MarkupProperty property in item.Properties) { if (property.Name == "Triggers" && property.Name == "Storyboard") { yield return(property); } } if (_factory.FirstChild != null) { if (_factory.FirstChild.Type == null) { yield return(new FrameworkElementFactoryStringContent(_factory.FirstChild, this)); } else { yield return(new FrameworkElementFactoryContent(_factory, this)); } } } }
/// <summary> /// Creates a Vector3DCollection with all of the same elements as collection /// </summary> public Vector3DCollection(IEnumerable <Vector3D> collection) { // The WritePreamble and WritePostscript aren't technically necessary // in the constructor as of 1/20/05 but they are put here in case // their behavior changes at a later date WritePreamble(); if (collection != null) { ICollection <Vector3D> icollectionOfT = collection as ICollection <Vector3D>; if (icollectionOfT != null) { _collection = new FrugalStructList <Vector3D>(icollectionOfT); } else { ICollection icollection = collection as ICollection; if (icollection != null) // an IC but not and IC<T> { _collection = new FrugalStructList <Vector3D>(icollection); } else // not a IC or IC<T> so fall back to the slower Add { _collection = new FrugalStructList <Vector3D>(); foreach (Vector3D item in collection) { _collection.Add(item); } } } WritePostscript(); } else { throw new ArgumentNullException("collection"); } }
/// <summary> /// Removes all IElements from the collection. /// </summary> public void Clear() { VerifyAPIReadWrite(); // Rather than clear, we swap out the FrugalStructList because // we need to keep the old values around to notify the parent // they were removed. FrugalStructList <Visual3D> oldCollection = _collection; _collection = new FrugalStructList <Visual3D>(); InvalidateEnumerators(); // NOTE: The collection must be updated before notifying the Visual. for (int i = oldCollection.Count - 1; i >= 0; i--) { _owner.RemoveChild(oldCollection[i]); } Debug_ICC(); }
// Computes an axis aligned bounding box that contains the given set of points. internal static Rect3D ComputeAxisAlignedBoundingBox(Point3DCollection positions) { if (positions != null) { FrugalStructList <Point3D> points = positions._collection; if (points.Count != 0) { Point3D p = points[0]; Rect3D newBounds = new Rect3D(p.X, p.Y, p.Z, 0, 0, 0); for (int i = 1; i < points.Count; i++) { p = points[i]; M3DUtil.AddPointToBounds(ref p, ref newBounds); } return(newBounds); } } return(Rect3D.Empty); }
// 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. Adds the new TemplateNode's information to the container's per-instance // StyleData/TemplateData. (This only makes sense for children created via // FrameworkElementFactory. Children acquired via BuildVisualTree don't use // any property-related funtionality of the Style/Template.) // internal static void CreateInstanceDataForChild( UncommonField<HybridDictionary[]> dataField, DependencyObject container, DependencyObject child, int childIndex, bool hasInstanceValues, ref FrugalStructList<ChildRecord> childRecordFromChildIndex) { if (hasInstanceValues) { HybridDictionary instanceValues = EnsureInstanceData(dataField, container, InstanceStyleData.InstanceValues); StyleHelper.ProcessInstanceValuesForChild( container, child, childIndex, instanceValues, true, ref childRecordFromChildIndex); } }
// // This method // 1. Adds a ChildPropertyDependent entry to the given // ResourceDependents list. This is used when invalidating // resource references // private static void AddResourceDependent( int childIndex, DependencyProperty dp, object name, ref FrugalStructList<ChildPropertyDependent> resourceDependents) { bool add = true; for (int i = 0; i < resourceDependents.Count; i++) { // Check for duplicate entry ChildPropertyDependent resourceDependent = resourceDependents[i]; if ((resourceDependent.ChildIndex == childIndex) && (resourceDependent.Property == dp) && (resourceDependent.Name == name)) { add = false; break; } } if (add) { // Since there isn't a duplicate entry, // create and add a new one ChildPropertyDependent resourceDependent = new ChildPropertyDependent(); resourceDependent.ChildIndex = childIndex; resourceDependent.Property = dp; resourceDependent.Name = name; resourceDependents.Add(resourceDependent); } }
// =========================================================================== // These methods are invoked when a Property is being // invalidated via a Style/Template // =========================================================================== #region InvalidateMethods // // This method // 1. Is invoked when the StyleProperty is invalidated on a FrameworkElement or // FrameworkContentElement or a sub-class thereof. // internal static void DoStyleInvalidations( FrameworkElement fe, FrameworkContentElement fce, Style oldStyle, Style newStyle) { Debug.Assert(fe != null || fce != null); if (oldStyle != newStyle) { // // Style is changing // DependencyObject container = (fe != null) ? (DependencyObject)fe : (DependencyObject)fce; // If the style wants to watch for the Loaded and/or Unloaded events, set the // flag that says we want to receive it. Otherwise, if it was set in the old style, clear it. StyleHelper.UpdateLoadedFlag( container, oldStyle, newStyle ); // Set up any per-instance state relating to the new Style // We do this here instead of OnStyleInvalidated because // this needs to happen for the *first* Style. StyleHelper.UpdateInstanceData( StyleHelper.StyleDataField, fe, fce, oldStyle, newStyle, null /* oldFrameworkTemplate */, null /* newFrameworkTemplate */, (InternalFlags)0); // If this new style has resource references (either for the container // or for children in the visual tree), then, mark it so that it will // not be ignored during resource change invalidations if ((newStyle != null) && (newStyle.HasResourceReferences)) { if (fe != null) { fe.HasResourceReference = true; } else { fce.HasResourceReference = true; } } FrugalStructList<ContainerDependent> oldContainerDependents = oldStyle != null ? oldStyle.ContainerDependents : StyleHelper.EmptyContainerDependents; FrugalStructList<ContainerDependent> newContainerDependents = newStyle != null ? newStyle.ContainerDependents : StyleHelper.EmptyContainerDependents; // Propagate invalidation for Style dependents FrugalStructList<ContainerDependent> exclusionContainerDependents = new FrugalStructList<ContainerDependent>(); StyleHelper.InvalidateContainerDependents(container, ref exclusionContainerDependents, ref oldContainerDependents, ref newContainerDependents); // Propagate invalidation for resource references that may be // picking stuff from the style's ResourceDictionary DoStyleResourcesInvalidations(container, fe, fce, oldStyle, newStyle); // Notify Style has changed // CALLBACK if (fe != null) { fe.OnStyleChanged(oldStyle, newStyle); } else { fce.OnStyleChanged(oldStyle, newStyle); } } }
// // This method // 1. Invalidates all the properties set on the container's style. // The value could have been set directly on the Style or via Trigger. // internal static void InvalidateContainerDependents( DependencyObject container, ref FrugalStructList<ContainerDependent> exclusionContainerDependents, ref FrugalStructList<ContainerDependent> oldContainerDependents, ref FrugalStructList<ContainerDependent> newContainerDependents) { // Invalidate all properties on the container that were being driven via the oldStyle int count = oldContainerDependents.Count; for (int i = 0; i < count; i++) { DependencyProperty dp = oldContainerDependents[i].Property; // Invalidate the property only if it is not locally set if (!IsSetOnContainer(dp, ref exclusionContainerDependents, false /*alsoFromTriggers*/)) { // call GetValueCore to get value from Style/Template container.InvalidateProperty(dp); } } // Invalidate all properties on the container that will be driven via the newStyle count = newContainerDependents.Count; if (count > 0) { FrameworkObject fo = new FrameworkObject(container); for (int i = 0; i < count; i++) { DependencyProperty dp = newContainerDependents[i].Property; // Invalidate the property only if it // - is not a part of oldContainerDependents and // - is not locally set if (!IsSetOnContainer(dp, ref exclusionContainerDependents, false /*alsoFromTriggers*/) && !IsSetOnContainer(dp, ref oldContainerDependents, false /*alsoFromTriggers*/)) { ApplyStyleOrTemplateValue(fo, dp); } } } }
//------------------------------------------------------ // // Constructors // //------------------------------------------------------ /// <summary> /// Initializes a new instance that is empty. /// </summary> public GeneralTransformCollection() { _collection = new FrugalStructList <GeneralTransform>(); }
// // This method // 1. Says if the given DP a part of the given ContainerDependents // 2. Is used to skip properties while invalidating the inherited properties for an // ancestor change. If this method returns true the invalidation will be skipped. // If this DP has been set on the container this value will take precedence over the inherited // value. Hence there is no need to invalidate this property as part of ancestor change processing. // // Ancestor changed invalidation for this DP can be skipped if it // - Is in the give ContainerDependents list but // - Is not the result of visual trigger // NOTE: If the style has changed all container dependents including the ones originating // from visual triggers would have been invalidated. Hence they can all be skipped. // internal static bool IsSetOnContainer( DependencyProperty dp, ref FrugalStructList<ContainerDependent> containerDependents, bool alsoFromTriggers) { for (int i = 0; i < containerDependents.Count; i++) { if (dp == containerDependents[i].Property) { return alsoFromTriggers || !containerDependents[i].FromVisualTrigger; } } return false; }
// // This method // 1. Adds shared table entries for property values set via Triggers // private static void ProcessTemplateTriggers( TriggerCollection triggers, FrameworkTemplate frameworkTemplate, ref FrugalStructList<ChildRecord> childRecordFromChildIndex, ref FrugalStructList<ItemStructMap<TriggerSourceRecord>> triggerSourceRecordFromChildIndex, ref FrugalStructList<ContainerDependent> containerDependents, ref FrugalStructList<ChildPropertyDependent> resourceDependents, ref ItemStructList<ChildEventDependent> eventDependents, ref HybridDictionary dataTriggerRecordFromBinding, HybridDictionary childIndexFromChildID, ref bool hasInstanceValues, ref HybridDictionary triggerActions, FrameworkElementFactory templateRoot, ref EventHandlersStore eventHandlersStore, ref FrugalMap propertyTriggersWithActions, ref HybridDictionary dataTriggersWithActions, ref bool hasLoadedChangeHandler) { if (triggers != null) { int triggerCount = triggers.Count; for (int i = 0; i < triggerCount; i++) { TriggerBase triggerBase = triggers[i]; Trigger trigger; MultiTrigger multiTrigger; DataTrigger dataTrigger; MultiDataTrigger multiDataTrigger; EventTrigger eventTrigger; DetermineTriggerType( triggerBase, out trigger, out multiTrigger, out dataTrigger, out multiDataTrigger, out eventTrigger ); if ( trigger != null || multiTrigger != null|| dataTrigger != null || multiDataTrigger != null ) { // Update the SourceChildIndex for each of the conditions for this trigger TriggerCondition[] conditions = triggerBase.TriggerConditions; for (int k=0; k<conditions.Length; k++) { conditions[k].SourceChildIndex = StyleHelper.QueryChildIndexFromChildName(conditions[k].SourceName, childIndexFromChildID); } // Set things up to handle Setter values for (int j = 0; j < triggerBase.PropertyValues.Count; j++) { PropertyValue propertyValue = triggerBase.PropertyValues[j]; // Check for trigger rules that act on template children if (propertyValue.ChildName == StyleHelper.SelfName) { // "Self" (container) trigger // Track properties on the container that are being driven by // the Template so that they can be invalidated during Template changes StyleHelper.AddContainerDependent(propertyValue.Property, true /*fromVisualTrigger*/, ref containerDependents); } StyleHelper.UpdateTables(ref propertyValue, ref childRecordFromChildIndex, ref triggerSourceRecordFromChildIndex, ref resourceDependents, ref dataTriggerRecordFromBinding, childIndexFromChildID, ref hasInstanceValues); } // Set things up to handle TriggerActions if( triggerBase.HasEnterActions || triggerBase.HasExitActions ) { if( trigger != null ) { StyleHelper.AddPropertyTriggerWithAction( triggerBase, trigger.Property, ref propertyTriggersWithActions ); } else if( multiTrigger != null ) { for( int k = 0; k < multiTrigger.Conditions.Count; k++ ) { Condition triggerCondition = multiTrigger.Conditions[k]; StyleHelper.AddPropertyTriggerWithAction( triggerBase, triggerCondition.Property, ref propertyTriggersWithActions ); } } else if( dataTrigger != null ) { StyleHelper.AddDataTriggerWithAction( triggerBase, dataTrigger.Binding, ref dataTriggersWithActions ); } else if( multiDataTrigger != null ) { for( int k = 0; k < multiDataTrigger.Conditions.Count; k++ ) { Condition dataCondition = multiDataTrigger.Conditions[k]; StyleHelper.AddDataTriggerWithAction( triggerBase, dataCondition.Binding, ref dataTriggersWithActions ); } } else { throw new InvalidOperationException(SR.Get(SRID.UnsupportedTriggerInTemplate, triggerBase.GetType().Name)); } } } else if( eventTrigger != null ) { StyleHelper.ProcessEventTrigger(eventTrigger, childIndexFromChildID, ref triggerActions, ref eventDependents, templateRoot, frameworkTemplate, ref eventHandlersStore, ref hasLoadedChangeHandler); } else { throw new InvalidOperationException(SR.Get(SRID.UnsupportedTriggerInTemplate, triggerBase.GetType().Name)); } } } }
// // This method // 1. Is invoked when Styled/Templated container property invalidation // is propagated to its dependent properties from Style/Template. // internal static void OnTriggerSourcePropertyInvalidated( Style ownerStyle, FrameworkTemplate frameworkTemplate, DependencyObject container, DependencyProperty dp, DependencyPropertyChangedEventArgs changedArgs, bool invalidateOnlyContainer, ref FrugalStructList<ItemStructMap<TriggerSourceRecord>> triggerSourceRecordFromChildIndex, ref FrugalMap propertyTriggersWithActions, int sourceChildIndex) { Debug.Assert(ownerStyle != null || frameworkTemplate != null ); /////////////////////////////////////////////////////////////////// // Update all values affected by property trigger Setters // Check if this Child Index is represented in given data-structure if ((0 <= sourceChildIndex) && (sourceChildIndex < triggerSourceRecordFromChildIndex.Count)) { // Fetch the triggerSourceRecordMap for the given childIndex ItemStructMap<TriggerSourceRecord> triggerSourceRecordMap = triggerSourceRecordFromChildIndex[sourceChildIndex]; // Check if this Container property is represented in style int mapIndex = triggerSourceRecordMap.Search(dp.GlobalIndex); if (mapIndex >= 0) { // Container's property is represented in style TriggerSourceRecord record = triggerSourceRecordMap.Entries[mapIndex].Value; // Invalidate all Self/Child-Index/Property dependents InvalidateDependents(ownerStyle, frameworkTemplate, container, dp, ref record.ChildPropertyDependents, invalidateOnlyContainer); } } /////////////////////////////////////////////////////////////////// // Find all TriggerActions that may need to execute in response to // the property change. object candidateTrigger = propertyTriggersWithActions[dp.GlobalIndex]; if( candidateTrigger != DependencyProperty.UnsetValue ) { // One or more trigger objects need to be evaluated. The candidateTrigger // object may be a single trigger or a collection of them. TriggerBase triggerBase = candidateTrigger as TriggerBase; if( triggerBase != null ) { InvokePropertyTriggerActions( triggerBase, container, dp, changedArgs, sourceChildIndex, ownerStyle, frameworkTemplate ); } else { Debug.Assert(candidateTrigger is List<TriggerBase>, "Internal data structure error: The FrugalMap [Style/Template].PropertyTriggersWithActions " + "is expected to hold a single TriggerBase or a List<T> of them. An object of type " + candidateTrigger.GetType().ToString() + " is not expected. Where did this object come from?"); List<TriggerBase> triggerList = (List<TriggerBase>)candidateTrigger; for( int i = 0; i < triggerList.Count; i++ ) { InvokePropertyTriggerActions( triggerList[i], container, dp, changedArgs, sourceChildIndex, ownerStyle, frameworkTemplate ); } } } }
internal void ShrinkToFit() { Debug.Assert(_chunkList.Count != 0); if (_chunkList.Count > 1 || _chunkList[0].Length != _currOffset) { byte [] buffer = new byte[_currOffset]; unsafe { fixed (byte *pbData = buffer) { ReadData(pbData, 0, _currOffset); } } ByteStreamGeometryContext.ReturnChunkToPool(_chunkList[0]); // The common case is a single chunk in a SingleItemList held by the FrugalStructList. // Avoid tearing down and recreating the SingleItemList by updating the lone element in-place, // especially since ShrinkToFit is called from DisposeCore when this object is about to die. if (_chunkList.Count == 1) { _chunkList[0] = buffer; } else { _chunkList = new FrugalStructList<byte[]>(); _chunkList.Add(buffer); } } }
internal void ShrinkToFit() { Debug.Assert(_chunkList.Count != 0); if (_chunkList.Count > 1 || _chunkList[0].Length != _currOffset) { byte [] buffer = new byte[_currOffset]; unsafe { fixed (byte *pbData = buffer) { ReadData(pbData, 0, _currOffset); } _chunkList = new FrugalStructList<byte[]>(); _chunkList.Add(buffer); } } }
// // All table datastructures read-lock-free/write-lock // AddContainerDependent writes the datastructures, locks set by callers // // This method // 1. Adds a ContainerDependent to the ContainerDependents list if not // already present. This is used to invalidate container dependents. // internal static void AddContainerDependent( DependencyProperty dp, bool fromVisualTrigger, ref FrugalStructList<ContainerDependent> containerDependents) { ContainerDependent dependent; for (int i = 0; i < containerDependents.Count; i++) { dependent = containerDependents[i]; if (dp == dependent.Property) { // If the dp is set on targetType tag and can be set via TriggerBase it is recorded as coming // from TriggerBase because that way we are pessimistic in invalidating and always invalidate. dependent.FromVisualTrigger |= fromVisualTrigger; return; } } dependent = new ContainerDependent(); dependent.Property = dp; dependent.FromVisualTrigger = fromVisualTrigger; containerDependents.Add(dependent); }
// =========================================================================== // These methods are invoked when a Property // value is fetched from a Style/Template // =========================================================================== #region GetValueMethods // // This method // 1. Computes the value of a template child // (Index is '0' when the styled container is asking) // internal static object GetChildValue( UncommonField<HybridDictionary[]> dataField, DependencyObject container, int childIndex, FrameworkObject child, DependencyProperty dp, ref FrugalStructList<ChildRecord> childRecordFromChildIndex, ref EffectiveValueEntry entry, out ValueLookupType sourceType, FrameworkElementFactory templateRoot) { object value = DependencyProperty.UnsetValue; sourceType = ValueLookupType.Simple; // Check if this Child Index is represented in given data-structure if ((0 <= childIndex) && (childIndex < childRecordFromChildIndex.Count)) { // Fetch the childRecord for the given childIndex ChildRecord childRecord = childRecordFromChildIndex[childIndex]; // Check if this Property is represented in the childRecord int mapIndex = childRecord.ValueLookupListFromProperty.Search(dp.GlobalIndex); if (mapIndex >= 0) { if (childRecord.ValueLookupListFromProperty.Entries[mapIndex].Value.Count > 0) { // Child Index/Property are both represented in this style/template, // continue with value computation // Pass into helper so ValueLookup struct can be accessed by ref value = GetChildValueHelper( dataField, ref childRecord.ValueLookupListFromProperty.Entries[mapIndex].Value, dp, container, child, childIndex, true, ref entry, out sourceType, templateRoot); } } } return value; }
// // This method // 1. Invalidates properties set on a TemplateNode directly or via a Trigger // internal static void InvalidatePropertiesOnTemplateNode( DependencyObject container, FrameworkObject child, int childIndex, ref FrugalStructList<ChildRecord> childRecordFromChildIndex, bool isDetach, FrameworkElementFactory templateRoot) { Debug.Assert(child.FE != null || child.FCE != null); // Check if this Child Index is represented in given data-structure if ((0 <= childIndex) && (childIndex < childRecordFromChildIndex.Count)) { // Fetch the childRecord for the given childIndex ChildRecord childRecord = childRecordFromChildIndex[childIndex]; int count = childRecord.ValueLookupListFromProperty.Count; if (count > 0) { // Iterate through all the properties set on the given childRecord for (int i=0; i< count; i++) { // NOTE: Every entry in the ValueLookupListFromProperty corresponds to // one DependencyProperty. All the items in Entries[i].Value.List // represent values for the same DependencyProperty that might have // originated from different sources such as a direct property set or a // Trigger or a Storyboard value. DependencyProperty dp = childRecord.ValueLookupListFromProperty.Entries[i].Value.List[0].Property; Debug.Assert(dp != null, "dp must not be null"); if (!isDetach) { ApplyTemplatedParentValue( container, child, childIndex, ref childRecordFromChildIndex, dp, templateRoot); } else { // for the detach case, we can skip inherited properties // see comment in ClearTemplateChain // Invalidate only the non-inherited, non-style properties. // Note that I say non-style because StyleProperty is really // a psuedo inherited property, which gets specially handled // during an InvalidateTree call. if (dp != FrameworkElement.StyleProperty) { bool invalidate = true; if (dp.IsPotentiallyInherited) { PropertyMetadata metadata = dp.GetMetadata(child.DO.DependencyObjectType); if ((metadata != null) && metadata.IsInherited) { invalidate = false; } } if (invalidate) { child.DO.InvalidateProperty(dp); } } } } } } }
// // This method // 1. Returns true if any resource references are set on a template for a given child. // internal static bool HasResourceDependentsForChild( int childIndex, ref FrugalStructList<ChildPropertyDependent> resourceDependents) { // Look for properties on the given child that // are being driven via a resource reference in a template for (int i = 0; i < resourceDependents.Count; i++) { if (resourceDependents[i].ChildIndex == childIndex) { return true; } } return false; }
//------------------------------------------------------ // // Constructors // //------------------------------------------------------ /// <summary> /// Initializes a new instance that is empty. /// </summary> public GeometryCollection() { _collection = new FrugalStructList <Geometry>(); }
//+---------------------------------------------------------------------------------------------- // // ProcessTemplateContentFromFEF // // This method walks the FEF tree and builds the shared tables from the property values // in the FEF. // // For the Baml templates (non-FEF), see the ProcessTemplateContent routine. // //+---------------------------------------------------------------------------------------------- internal static void ProcessTemplateContentFromFEF( FrameworkElementFactory factory, ref FrugalStructList<ChildRecord> childRecordFromChildIndex, ref FrugalStructList<ItemStructMap<TriggerSourceRecord>> triggerSourceRecordFromChildIndex, ref FrugalStructList<ChildPropertyDependent> resourceDependents, ref ItemStructList<ChildEventDependent> eventDependents, ref HybridDictionary dataTriggerRecordFromBinding, HybridDictionary childIndexFromChildID, ref bool hasInstanceValues) { // Process the PropertyValues on the current node for (int i = 0; i < factory.PropertyValues.Count; i++) { PropertyValue propertyValue = factory.PropertyValues[i]; StyleHelper.UpdateTables(ref propertyValue, ref childRecordFromChildIndex, ref triggerSourceRecordFromChildIndex, ref resourceDependents, ref dataTriggerRecordFromBinding, childIndexFromChildID, ref hasInstanceValues); } // Add an entry in the EventDependents list for // the current TemplateNode's EventHandlersStore. StyleHelper.AddEventDependent(factory._childIndex, factory.EventHandlersStore, ref eventDependents); // Traverse the children of this TemplateNode factory = factory.FirstChild; while (factory != null) { ProcessTemplateContentFromFEF(factory, ref childRecordFromChildIndex, ref triggerSourceRecordFromChildIndex, ref resourceDependents, ref eventDependents, ref dataTriggerRecordFromBinding, childIndexFromChildID, ref hasInstanceValues); factory = factory.NextSibling; } }
// Iterates through the setters collection and adds the EventSetter information into // an EventHandlersStore for easy and fast retrieval during event routing. Also adds // an entry in the EventDependents list for EventhandlersStore holding the TargetType's // events. private void ProcessSetters(Style style) { // Walk down to bottom of based-on chain if (style == null) { return; } style.Setters.Seal(); // Does not mark individual setters as sealed, that's up to the loop below. // On-demand create the PropertyValues list, so that we can specify the right size. if(PropertyValues.Count == 0) { PropertyValues = new FrugalStructList<System.Windows.PropertyValue>(style.Setters.Count); } // Add EventSetters to local EventHandlersStore for (int i = 0; i < style.Setters.Count; i++) { SetterBase setterBase = style.Setters[i]; Debug.Assert(setterBase != null, "Setter collection must contain non-null instances of SetterBase"); // Setters are folded into the PropertyValues table only for the current style. The // processing of BasedOn Style properties will occur in subsequent call to ProcessSelfStyle Setter setter = setterBase as Setter; if (setter != null) { // Style Setters are not allowed to have a child target name - since there are no child nodes in a Style. if( setter.TargetName != null ) { throw new InvalidOperationException(SR.Get(SRID.SetterOnStyleNotAllowedToHaveTarget, setter.TargetName)); } if (style == this) { DynamicResourceExtension dynamicResource = setter.ValueInternal as DynamicResourceExtension; if (dynamicResource == null) { UpdatePropertyValueList( setter.Property, PropertyValueType.Set, setter.ValueInternal ); } else { UpdatePropertyValueList( setter.Property, PropertyValueType.Resource, dynamicResource.ResourceKey ); } } } else { Debug.Assert(setterBase is EventSetter, "Unsupported SetterBase subclass in style triggers ({0})", setterBase.GetType().ToString()); // Add this to the _eventHandlersStore EventSetter eventSetter = (EventSetter)setterBase; if (_eventHandlersStore == null) { _eventHandlersStore = new EventHandlersStore(); } _eventHandlersStore.AddRoutedEventHandler(eventSetter.Event, eventSetter.Handler, eventSetter.HandledEventsToo); SetModified(HasEventSetter); // If this event setter watches the loaded/unloaded events, set the optimization // flag. if (eventSetter.Event == FrameworkElement.LoadedEvent || eventSetter.Event == FrameworkElement.UnloadedEvent) { _hasLoadedChangeHandler = true; } } } // Process EventSetters on based on style so they get merged // into the EventHandlersStore for the current style. ProcessSetters(style._basedOn); }
// // All table datastructures read-lock-free/write-lock // UpdateTables writes the datastructures, locks set by callers // // This method // 1. Adds a ChildValueLookup entry to the given ChildRecord. // This is used in value computation. // 2. Optionally adds a ChildPropertyDependent entry to the given // ContainerRecordFromProperty list. This is used to invalidate // container dependents. // 3. Optionally adds a ChildPropertyDependent entry to the given // ResourceDependents list. This is used when invalidating resource // references // internal static void UpdateTables( ref PropertyValue propertyValue, ref FrugalStructList<ChildRecord> childRecordFromChildIndex, ref FrugalStructList<ItemStructMap<TriggerSourceRecord>> triggerSourceRecordFromChildIndex, ref FrugalStructList<ChildPropertyDependent> resourceDependents, ref HybridDictionary dataTriggerRecordFromBinding, HybridDictionary childIndexFromChildName, ref bool hasInstanceValues) { // // Record instructions for Child/Self value computation // // Query for child index (may be 0 if "self") int childIndex = QueryChildIndexFromChildName(propertyValue.ChildName, childIndexFromChildName); if (childIndex == -1) { throw new InvalidOperationException(SR.Get(SRID.NameNotFound, propertyValue.ChildName)); } object value = propertyValue.ValueInternal; bool requiresInstanceStorage = RequiresInstanceStorage(ref value); propertyValue.ValueInternal = value; childRecordFromChildIndex.EnsureIndex(childIndex); ChildRecord childRecord = childRecordFromChildIndex[childIndex]; int mapIndex = childRecord.ValueLookupListFromProperty.EnsureEntry(propertyValue.Property.GlobalIndex); ChildValueLookup valueLookup = new ChildValueLookup(); valueLookup.LookupType = (ValueLookupType)propertyValue.ValueType; // Maps directly to ValueLookupType for applicable values valueLookup.Conditions = propertyValue.Conditions; valueLookup.Property = propertyValue.Property; valueLookup.Value = propertyValue.ValueInternal; childRecord.ValueLookupListFromProperty.Entries[mapIndex].Value.Add(ref valueLookup); // Put back modified struct childRecordFromChildIndex[childIndex] = childRecord; // // Container property invalidation // switch ((ValueLookupType)propertyValue.ValueType) { case ValueLookupType.Simple: { hasInstanceValues |= requiresInstanceStorage; } break; case ValueLookupType.Trigger: case ValueLookupType.PropertyTriggerResource: { if( propertyValue.Conditions != null ) { // Record the current property as a dependent to each on of the // properties in the condition. This is to facilitate the invalidation // of the current property in the event that any one of the properties // in the condition change. This will allow the current property to get // re-evaluated. for (int i = 0; i < propertyValue.Conditions.Length; i++) { int sourceChildIndex = propertyValue.Conditions[i].SourceChildIndex; triggerSourceRecordFromChildIndex.EnsureIndex(sourceChildIndex); ItemStructMap<TriggerSourceRecord> triggerSourceRecordMap = triggerSourceRecordFromChildIndex[sourceChildIndex]; if (propertyValue.Conditions[i].Property == null) { throw new InvalidOperationException(SR.Get(SRID.MissingTriggerProperty)); } int index = triggerSourceRecordMap.EnsureEntry(propertyValue.Conditions[i].Property.GlobalIndex); AddPropertyDependent(childIndex, propertyValue.Property, ref triggerSourceRecordMap.Entries[index].Value.ChildPropertyDependents); // Store the triggerSourceRecordMap back into the list after it has been updated triggerSourceRecordFromChildIndex[sourceChildIndex] = triggerSourceRecordMap; } // If value is a resource reference, add dependent on resource changes if ((ValueLookupType)propertyValue.ValueType == ValueLookupType.PropertyTriggerResource) { AddResourceDependent(childIndex, propertyValue.Property, propertyValue.ValueInternal, ref resourceDependents); } } // values in a Trigger may require per-instance storage if ((ValueLookupType)propertyValue.ValueType != ValueLookupType.PropertyTriggerResource) { hasInstanceValues |= requiresInstanceStorage; } } break; case ValueLookupType.DataTrigger: case ValueLookupType.DataTriggerResource: { if( propertyValue.Conditions != null ) { if (dataTriggerRecordFromBinding == null) { dataTriggerRecordFromBinding = new HybridDictionary(); } // Record container conditional child property dependents for (int i = 0; i < propertyValue.Conditions.Length; i++) { DataTriggerRecord record = (DataTriggerRecord)dataTriggerRecordFromBinding[propertyValue.Conditions[i].Binding]; if (record == null) { record = new DataTriggerRecord(); dataTriggerRecordFromBinding[propertyValue.Conditions[i].Binding] = record; } // Add dependent on trigger AddPropertyDependent(childIndex, propertyValue.Property, ref record.Dependents); } // If value is a resource reference, add dependent on resource changes if ((ValueLookupType)propertyValue.ValueType == ValueLookupType.DataTriggerResource) { AddResourceDependent(childIndex, propertyValue.Property, propertyValue.ValueInternal, ref resourceDependents); } } // values in a DataTrigger may require per-instance storage if ((ValueLookupType)propertyValue.ValueType != ValueLookupType.DataTriggerResource) { hasInstanceValues |= requiresInstanceStorage; } } break; case ValueLookupType.TemplateBinding: { TemplateBindingExtension templateBinding = (TemplateBindingExtension)propertyValue.ValueInternal; DependencyProperty destinationProperty = propertyValue.Property; // Child DependencyProperty sourceProperty = templateBinding.Property; // Container // Record the current property as a dependent to the aliased // property on the container. This is to facilitate the // invalidation of the current property in the event that the // aliased container property changes. This will allow the current // property to get re-evaluated. int sourceChildIndex = 0; // TemplateBinding is always sourced off of the container triggerSourceRecordFromChildIndex.EnsureIndex(sourceChildIndex); ItemStructMap<TriggerSourceRecord> triggerSourceRecordMap = triggerSourceRecordFromChildIndex[sourceChildIndex]; int index = triggerSourceRecordMap.EnsureEntry(sourceProperty.GlobalIndex); AddPropertyDependent(childIndex, destinationProperty, ref triggerSourceRecordMap.Entries[index].Value.ChildPropertyDependents); // Store the triggerSourceRecordMap back into the list after it has been updated triggerSourceRecordFromChildIndex[sourceChildIndex] = triggerSourceRecordMap; } break; case ValueLookupType.Resource: { AddResourceDependent(childIndex, propertyValue.Property, propertyValue.ValueInternal, ref resourceDependents); } break; } }
internal static void ApplyTemplatedParentValue( DependencyObject container, FrameworkObject child, int childIndex, ref FrugalStructList<ChildRecord> childRecordFromChildIndex, DependencyProperty dp, FrameworkElementFactory templateRoot) { EffectiveValueEntry newEntry = new EffectiveValueEntry(dp); newEntry.Value = DependencyProperty.UnsetValue; if (GetValueFromTemplatedParent( container, childIndex, child, dp, ref childRecordFromChildIndex, templateRoot, ref newEntry)) { DependencyObject target = child.DO; target.UpdateEffectiveValue( target.LookupEntry(dp.GlobalIndex), dp, dp.GetMetadata(target.DependencyObjectType), new EffectiveValueEntry() /* oldEntry */, ref newEntry, false /* coerceWithDeferredReference */, false /* coerceWithCurrentValue */, OperationType.Unknown); } }
// // This method // 1. Sorts a resource dependent list by (childIndex, dp.GlobalIndex). // This helps to avoid duplicate invalidation. // internal static void SortResourceDependents( ref FrugalStructList<ChildPropertyDependent> resourceDependents) { // Ideally this would be done by having the ChildPropertyDependent // struct implement IComparable<ChildPropertyDependent>, and just // calling resourceDependents.Sort(). Unfortunately, this causes // an unwelcome JIT of mscorlib, to load internal methods // GenericArraySortHelper<T>.Sort and GenericArraySortHelper<T>.QuickSort. // // Instead we implement sort directly. The resource dependent lists // are short and nearly-sorted in practice, so insertion sort is good // enough. int n = resourceDependents.Count; for (int i=1; i<n; ++i) { ChildPropertyDependent current = resourceDependents[i]; int childIndex = current.ChildIndex; int dpIndex = current.Property.GlobalIndex; int j; for (j=i-1; j>=0; --j) { if (childIndex < resourceDependents[j].ChildIndex || (childIndex == resourceDependents[j].ChildIndex && dpIndex < resourceDependents[j].Property.GlobalIndex)) { resourceDependents[j+1] = resourceDependents[j]; } else { break; } } if (j < i-1) { resourceDependents[j+1] = current; } } }
// // This method // 1. Invalidates all the resource references set on a style or a template. // // Note: In the case that the visualtree was not generated from the particular // style in question we will skip past those resource references that haven't // been set on the container. This condition is described by the // invalidateVisualTreeToo flag being false. // internal static void InvalidateResourceDependents( DependencyObject container, ResourcesChangeInfo info, ref FrugalStructList<ChildPropertyDependent> resourceDependents, bool invalidateVisualTreeToo) { List<DependencyObject> styledChildren = TemplatedFeChildrenField.GetValue(container); // Invalidate all properties on this container and its children that // are being driven via a resource reference in a style for (int i = 0; i < resourceDependents.Count; i++) { // Invalidate property // 1. If nothing is known about the data or // 2. If the data tells us the key in the dictionary that was modified and this property is refering to it or // 3. If it tells us info about the changed dictionaries and this property was refering to one of their entries // 4. If this a theme change if (info.Contains(resourceDependents[i].Name, false /*isImplicitStyleKey*/)) { DependencyObject child = null; DependencyProperty invalidProperty = resourceDependents[i].Property; int childIndex = resourceDependents[i].ChildIndex; if (childIndex == 0) { // Index '0' means 'self' (container) child = container; } else if (invalidateVisualTreeToo) { Debug.Assert(styledChildren != null, "Should reach here only if the template tree has already been created"); // Locate child to invalidate child = GetChild(styledChildren, childIndex); if (child == null) { throw new InvalidOperationException(SR.Get(SRID.ChildTemplateInstanceDoesNotExist)); } } if (child != null) { // Invalidate property on child child.InvalidateProperty(invalidProperty); // skip remaining dependents for the same property - we only // need to invalidate once. The list is sorted, so we just need // to skip until we find a new property. int dpIndex = invalidProperty.GlobalIndex; while (++i < resourceDependents.Count) { if (resourceDependents[i].ChildIndex != childIndex || resourceDependents[i].Property.GlobalIndex != dpIndex) { break; } } --i; // back up to let the for-loop do its normal increment } } } }
// // This method // 1. Is common code to invalidate a list of dependents of a property trigger // or data trigger. Returns true if any of the dependents could not // be invalidated because they don't exist yet. // private static void InvalidateDependents( Style ownerStyle, FrameworkTemplate frameworkTemplate, DependencyObject container, DependencyProperty dp, ref FrugalStructList<ChildPropertyDependent> dependents, bool invalidateOnlyContainer) { Debug.Assert(ownerStyle != null || frameworkTemplate != null ); for (int i = 0; i < dependents.Count; i++) { DependencyObject child = null; int childIndex = dependents[i].ChildIndex; if (childIndex == 0) { // Index '0' means 'self' (container) child = container; } else if (!invalidateOnlyContainer) { // Locate child to invalidate // This assumes that at least one node in the // Style.VisualTree is in the child chain, to guarantee // this, the root node is always in the child chain. List<DependencyObject> styledChildren = TemplatedFeChildrenField.GetValue(container); if ((styledChildren != null) && (childIndex <= styledChildren.Count)) { child = GetChild(styledChildren, childIndex); // Notice that we allow GetChildValue to return null because it // could so happen that the dependent properties for the current // trigger source are on nodes that haven't been instantiated yet. // We do not have to bother about deferring these invalidations // because InvalidatePropertiesOnTemplateNode will take care of // these invalidations when the node is instantiated via // FrameworkElementFactory.InstantiateTree. } } // Invalidate property on child DependencyProperty invalidProperty = dependents[i].Property; // Invalidate only if the property is not locally set because local value // has precedence over style acquired value. bool hasModifiers; if (child != null && child.GetValueSource(invalidProperty, null, out hasModifiers) != BaseValueSourceInternal.Local) { child.InvalidateProperty(invalidProperty, preserveCurrentValue:true); // ApplyStyleOrTemplateValue(new FrameworkObject(child), invalidProperty); } } }
/// <summary> /// Initializes a new instance that is empty and has the specified initial capacity. /// </summary> /// <param name="capacity"> int - The number of elements that the new list is initially capable of storing. </param> public GeneralTransformCollection(int capacity) { _collection = new FrugalStructList <GeneralTransform>(capacity); }
// // This method // 1. Adds a ChildPropertyDependent entry to the given // PropertyDependents list. This is used when invalidating // properties dependent upon a certain property on the container. // The dependent properties could have originated from a Trigger // or from a property alias on a TemplateNode. // private static void AddPropertyDependent( int childIndex, DependencyProperty dp, ref FrugalStructList<ChildPropertyDependent> propertyDependents) { ChildPropertyDependent dependent = new ChildPropertyDependent(); dependent.ChildIndex = childIndex; dependent.Property = dp; propertyDependents.Add(dependent); }
/// <summary> /// Initializes a new instance that is empty and has the specified initial capacity. /// </summary> /// <param name="capacity"> int - The number of elements that the new list is initially capable of storing. </param> public TextEffectCollection(int capacity) { _collection = new FrugalStructList <TextEffect>(capacity); }
// =========================================================================== // These methods are invoked when a Style/Template is Sealed // =========================================================================== #region WriteMethods // // This method // 1. Seals a template // internal static void SealTemplate( FrameworkTemplate frameworkTemplate, ref bool isSealed, FrameworkElementFactory templateRoot, TriggerCollection triggers, ResourceDictionary resources, HybridDictionary childIndexFromChildID, ref FrugalStructList<ChildRecord> childRecordFromChildIndex, ref FrugalStructList<ItemStructMap<TriggerSourceRecord>> triggerSourceRecordFromChildIndex, ref FrugalStructList<ContainerDependent> containerDependents, ref FrugalStructList<ChildPropertyDependent> resourceDependents, ref ItemStructList<ChildEventDependent> eventDependents, ref HybridDictionary triggerActions, ref HybridDictionary dataTriggerRecordFromBinding, ref bool hasInstanceValues, ref EventHandlersStore eventHandlersStore) { Debug.Assert(frameworkTemplate != null ); // This template has already been sealed. // There is no more to do. if (isSealed) { return; } // Seal template nodes (if exists) if (frameworkTemplate != null) { frameworkTemplate.ProcessTemplateBeforeSeal(); } if (templateRoot != null) { Debug.Assert( !frameworkTemplate.HasXamlNodeContent ); // Seal the template Debug.Assert(frameworkTemplate != null); //frameworkTemplate.ProcessTemplateBeforeSeal(); templateRoot.Seal(frameworkTemplate); } // Seal triggers if (triggers != null) { triggers.Seal(); } // Seal Resource Dictionary if (resources != null) { resources.IsReadOnly = true; } // Build shared tables if (templateRoot != null) { // This is a FEF-style template. Process the root node, and it will // recurse through the rest of the FEF tree. StyleHelper.ProcessTemplateContentFromFEF( templateRoot, ref childRecordFromChildIndex, ref triggerSourceRecordFromChildIndex, ref resourceDependents, ref eventDependents, ref dataTriggerRecordFromBinding, childIndexFromChildID, ref hasInstanceValues); } // Process Triggers. (Trigger PropertyValues are inserted // last into the Style/Template GetValue chain because they // are the highest priority) bool hasHandler = false; Debug.Assert( frameworkTemplate != null ); StyleHelper.ProcessTemplateTriggers( triggers, frameworkTemplate, ref childRecordFromChildIndex, ref triggerSourceRecordFromChildIndex, ref containerDependents, ref resourceDependents, ref eventDependents, ref dataTriggerRecordFromBinding, childIndexFromChildID, ref hasInstanceValues, ref triggerActions, templateRoot, ref eventHandlersStore, ref frameworkTemplate.PropertyTriggersWithActions, ref frameworkTemplate.DataTriggersWithActions, ref hasHandler ); frameworkTemplate.HasLoadedChangeHandler = hasHandler; frameworkTemplate.SetResourceReferenceState(); // All done, seal self and call it a day. isSealed = true; // Remove thread affinity so it can be accessed across threads frameworkTemplate.DetachFromDispatcher(); // Check if the template has the Template property set on the container via its visual triggers. // It is an error to specify the TemplateProperty in your own Template. if (StyleHelper.IsSetOnContainer(Control.TemplateProperty, ref containerDependents, true) || StyleHelper.IsSetOnContainer(ContentPresenter.TemplateProperty, ref containerDependents, true)) { throw new InvalidOperationException(SR.Get(SRID.CannotHavePropertyInTemplate, Control.TemplateProperty.Name)); } // Check if the template has the Style property set on the container via its visual triggers. // It is an error to specify the StyleProperty in your own Template. if (StyleHelper.IsSetOnContainer(FrameworkElement.StyleProperty, ref containerDependents, true)) { throw new InvalidOperationException(SR.Get(SRID.CannotHavePropertyInTemplate, FrameworkElement.StyleProperty.Name)); } // Check if the template has the DefaultStyleKey property set on the container via its visual triggers. // It is an error to specify the DefaultStyleKeyProperty in your own Template. if (StyleHelper.IsSetOnContainer(FrameworkElement.DefaultStyleKeyProperty, ref containerDependents, true)) { throw new InvalidOperationException(SR.Get(SRID.CannotHavePropertyInTemplate, FrameworkElement.DefaultStyleKeyProperty.Name)); } // Check if the template has the OverridesDefaultStyle property set on the container via its visual triggers. // It is an error to specify the OverridesDefaultStyleProperty in your own Template. if (StyleHelper.IsSetOnContainer(FrameworkElement.OverridesDefaultStyleProperty, ref containerDependents, true)) { throw new InvalidOperationException(SR.Get(SRID.CannotHavePropertyInTemplate, FrameworkElement.OverridesDefaultStyleProperty.Name)); } // Check if the template has the Name property set on the container via its visual triggers. // It is an error to specify the Name in your own Template. if (StyleHelper.IsSetOnContainer(FrameworkElement.NameProperty, ref containerDependents, true)) { throw new InvalidOperationException(SR.Get(SRID.CannotHavePropertyInTemplate, FrameworkElement.NameProperty.Name)); } }
/// <summary> /// Initializes a new instance that is empty and has the specified initial capacity. /// </summary> /// <param name="capacity"> int - The number of elements that the new list is initially capable of storing. </param> public GeometryCollection(int capacity) { _collection = new FrugalStructList <Geometry>(capacity); }
// // This method // 1. Adds or removes per-instance state on the container/child (push model) // 2. Processes values that need per-instance storage // private static void ProcessInstanceValuesForChild( DependencyObject container, DependencyObject child, int childIndex, HybridDictionary instanceValues, bool apply, ref FrugalStructList<ChildRecord> childRecordFromChildIndex) { // If childIndex has not been provided, // fetch it from the given child node if (childIndex == -1) { FrameworkElement feChild; FrameworkContentElement fceChild; Helper.DowncastToFEorFCE(child, out feChild, out fceChild, false); childIndex = (feChild != null) ? feChild.TemplateChildIndex : (fceChild != null) ? fceChild.TemplateChildIndex : -1; } // Check if this Child Index/Property is represented in style if ((0 <= childIndex) && (childIndex < childRecordFromChildIndex.Count)) { int n = childRecordFromChildIndex[childIndex].ValueLookupListFromProperty.Count; for (int i = 0; i < n; ++i) { ProcessInstanceValuesHelper( ref childRecordFromChildIndex[childIndex].ValueLookupListFromProperty.Entries[i].Value, child, childIndex, instanceValues, apply); } } }
//------------------------------------------------------ // // Constructors // //------------------------------------------------------ /// <summary> /// Initializes a new instance that is empty. /// </summary> public TextEffectCollection() { _collection = new FrugalStructList <TextEffect>(); }
internal static bool GetValueFromTemplatedParent( DependencyObject container, int childIndex, FrameworkObject child, DependencyProperty dp, ref FrugalStructList<ChildRecord> childRecordFromChildIndex, FrameworkElementFactory templateRoot, ref EffectiveValueEntry entry) { ValueLookupType sourceType = ValueLookupType.Simple; // entry will be updated to hold the value -- we only need to set the value source object value = StyleHelper.GetChildValue( StyleHelper.TemplateDataField, container, childIndex, child, dp, ref childRecordFromChildIndex, ref entry, out sourceType, templateRoot); if (value != DependencyProperty.UnsetValue) { if (sourceType == ValueLookupType.Trigger || sourceType == ValueLookupType.PropertyTriggerResource || sourceType == ValueLookupType.DataTrigger || sourceType == ValueLookupType.DataTriggerResource) { entry.BaseValueSourceInternal = BaseValueSourceInternal.ParentTemplateTrigger; } else { entry.BaseValueSourceInternal = BaseValueSourceInternal.ParentTemplate; } return true; } else { // If we didn't get a value from GetValueFromTemplatedParent, we know that // the template isn't offering a value from a trigger or from its shared // value table. But we could still have a value from the template, stored // in per-instance storage (e.g. a Freezable with an embedded dynamic binding). if (child.StoresParentTemplateValues) { HybridDictionary parentTemplateValues = StyleHelper.ParentTemplateValuesField.GetValue(child.DO); if(parentTemplateValues.Contains(dp)) { entry.BaseValueSourceInternal = BaseValueSourceInternal.ParentTemplate; value = parentTemplateValues[dp]; entry.Value = value; if (value is MarkupExtension) { // entry will be updated to hold the value StyleHelper.GetInstanceValue( StyleHelper.TemplateDataField, container, child.FE, child.FCE, childIndex, dp, StyleHelper.UnsharedTemplateContentPropertyIndex, ref entry); } return true; } } } return false; }
/// <summary> /// Creates a TextEffectCollection with all of the same elements as collection /// </summary> public TextEffectCollection(IEnumerable <TextEffect> collection) { // The WritePreamble and WritePostscript aren't technically necessary // in the constructor as of 1/20/05 but they are put here in case // their behavior changes at a later date WritePreamble(); if (collection != null) { bool needsItemValidation = true; ICollection <TextEffect> icollectionOfT = collection as ICollection <TextEffect>; if (icollectionOfT != null) { _collection = new FrugalStructList <TextEffect>(icollectionOfT); } else { ICollection icollection = collection as ICollection; if (icollection != null) // an IC but not and IC<T> { _collection = new FrugalStructList <TextEffect>(icollection); } else // not a IC or IC<T> so fall back to the slower Add { _collection = new FrugalStructList <TextEffect>(); foreach (TextEffect item in collection) { if (item == null) { throw new System.ArgumentException(SR.Get(SRID.Collection_NoNull)); } TextEffect newValue = item; OnFreezablePropertyChanged(/* oldValue = */ null, newValue); _collection.Add(newValue); } needsItemValidation = false; } } if (needsItemValidation) { foreach (TextEffect item in collection) { if (item == null) { throw new System.ArgumentException(SR.Get(SRID.Collection_NoNull)); } OnFreezablePropertyChanged(/* oldValue = */ null, item); } } WritePostscript(); } else { throw new ArgumentNullException("collection"); } }
// // This method // 1. Is invoked when the TemplateProperty is invalidated on a Control, // Page, PageFunctionBase, ContentPresenter, or a sub-class thereof. // internal static void DoTemplateInvalidations( FrameworkElement feContainer, FrameworkTemplate oldFrameworkTemplate) { Debug.Assert(feContainer != null); DependencyObject container; HybridDictionary[] oldTemplateData; FrameworkTemplate newFrameworkTemplate = null; object oldTemplate; object newTemplate; bool newTemplateHasResourceReferences; Debug.Assert(feContainer != null); // Fetch the per-instance data before it goes away (during Template_get) oldTemplateData = StyleHelper.TemplateDataField.GetValue(feContainer); // Do immediate pull of Template to refresh the value since the // new Template needs to be known at this time to do accurate // invalidations newFrameworkTemplate = feContainer.TemplateInternal; container = feContainer; oldTemplate = oldFrameworkTemplate; newTemplate = newFrameworkTemplate; newTemplateHasResourceReferences = (newFrameworkTemplate != null) ? newFrameworkTemplate.HasResourceReferences : false; // If the template wants to watch for the Loaded and/or Unloaded events, set the // flag that says we want to receive it. Otherwise, if it was set in the old template, clear it. StyleHelper.UpdateLoadedFlag( container, oldFrameworkTemplate, newFrameworkTemplate ); if (oldTemplate != newTemplate) { // // Template is changing // // Set up any per-instance state relating to the new Template // We do this here instead of OnTemplateInvalidated because // this needs to happen for the *first* Template. StyleHelper.UpdateInstanceData( StyleHelper.TemplateDataField, feContainer /* fe */, null /* fce */, null /*oldStyle */, null /* newStyle */, oldFrameworkTemplate, newFrameworkTemplate, InternalFlags.HasTemplateGeneratedSubTree); // If this new template has resource references (either for the container // or for children in the visual tree), then, mark it so that it will // not be ignored during resource change invalidations if (newTemplate != null && newTemplateHasResourceReferences) { Debug.Assert(feContainer != null); feContainer.HasResourceReference = true; } // If the template wants to watch for the Loaded and/or Unloaded events, set the // flag that says we want to receive it. Otherwise, if it was set in the old template, clear it. UpdateLoadedFlag( container, oldFrameworkTemplate, newFrameworkTemplate ); // Wipe out VisualTree only if VisualTree factories // are changing // // If the factories are null for both new and old, then, the Template // has the opportunity to supply the VisualTree using the "BuildVisualTree" // virtual. FrameworkElementFactory oldFactory; FrameworkElementFactory newFactory; bool canBuildVisualTree; bool hasTemplateGeneratedSubTree; FrugalStructList<ContainerDependent> oldContainerDependents; FrugalStructList<ContainerDependent> newContainerDependents; Debug.Assert(feContainer != null); oldFactory = (oldFrameworkTemplate != null) ? oldFrameworkTemplate.VisualTree : null; newFactory = (newFrameworkTemplate != null) ? newFrameworkTemplate.VisualTree : null; canBuildVisualTree = (oldFrameworkTemplate != null) ? oldFrameworkTemplate.CanBuildVisualTree : false; hasTemplateGeneratedSubTree = feContainer.HasTemplateGeneratedSubTree; oldContainerDependents = (oldFrameworkTemplate != null) ? oldFrameworkTemplate.ContainerDependents : StyleHelper.EmptyContainerDependents; newContainerDependents = (newFrameworkTemplate != null) ? newFrameworkTemplate.ContainerDependents : StyleHelper.EmptyContainerDependents; if (hasTemplateGeneratedSubTree) { StyleHelper.ClearGeneratedSubTree(oldTemplateData, feContainer /* fe */, null /* fce */, oldFrameworkTemplate ); } // Propagate invalidation for template dependents FrugalStructList<ContainerDependent> exclusionContainerDependents = new FrugalStructList<ContainerDependent>(); StyleHelper.InvalidateContainerDependents(container, ref exclusionContainerDependents, ref oldContainerDependents, ref newContainerDependents); // Propagate invalidation for resource references that may be // picking stuff from the style's ResourceDictionary DoTemplateResourcesInvalidations(container, feContainer, null /*fce*/, oldTemplate, newTemplate); Debug.Assert(feContainer != null); feContainer.OnTemplateChangedInternal(oldFrameworkTemplate, newFrameworkTemplate); } else { // // Template is not changing // // Template was invalidated but didn't change. If the Template created the // VisualTree via an override of BuildVisualTree, then, it is // wiped out now so that it may be conditionally rebuilt by the // custom Template if (newFrameworkTemplate != null) { if (feContainer.HasTemplateGeneratedSubTree && newFrameworkTemplate.VisualTree == null && !newFrameworkTemplate.HasXamlNodeContent ) { StyleHelper.ClearGeneratedSubTree(oldTemplateData, feContainer /* fe */, null /* fce */, oldFrameworkTemplate); // Nothing guarantees that ApplyTemplate actually gets // called, so ask for it explicitly (bug 963163). feContainer.InvalidateMeasure(); } } } }