Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / wpf / src / Framework / System / Windows / FrameworkTemplate.cs / 1 / FrameworkTemplate.cs
//------------------------------------------------------------------------------------
//
// File: FrameworkTemplate.cs
//
// Description:
// A generic class that allow instantiation of a tree of Framework[Content]Elements.
//
// Copyright (C) 2005 by Microsoft Corporation. All rights reserved.
//
//-----------------------------------------------------------------------------------
using MS.Internal; // Helper
using MS.Utility; // ChildValueLookupList
using System.ComponentModel; // DesignerSerializationVisibility, DefaultValueAttribute
using System.Collections; // Hashtable
using System.Collections.Generic; // List
using System.Collections.Specialized; // HybridDictionary
using System.Diagnostics; // Debug
using System.Threading; // Interlocked
using System.Windows.Media.Animation; // Timeline
using System.Windows.Markup; // XamlTemplateSerializer, ContentPropertyAttribute
using System.Windows.Media;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Threading; // DispatcherObject
namespace System.Windows
{
///
/// A generic class that allow instantiation of a
/// tree of Framework[Content]Elements.
///
[ContentProperty("VisualTree")]
[Localizability(LocalizationCategory.NeverLocalize)] // All properties on template are not localizable
public abstract class FrameworkTemplate : DispatcherObject, INameScope, ISealable, IHaveResources
{
///
///
protected FrameworkTemplate()
{
#if DEBUG
_debugInstanceCounter = ++_globalDebugInstanceCounter;
#endif
}
#region PublicMethods
///
/// Subclasses must override this method if they need to
/// impose additional rules for the TemplatedParent
///
protected virtual void ValidateTemplatedParent(FrameworkElement templatedParent)
{
Debug.Assert(templatedParent != null,
"Must have a non-null FE TemplatedParent.");
}
#endregion PublicMethods
#region PublicProperties
///
/// Says if this template has been sealed
///
public bool IsSealed
{
get
{
// Verify Context Access
VerifyAccess();
return _sealed;
}
}
///
/// Root node of the template
///
public FrameworkElementFactory VisualTree
{
get
{
// Verify Context Access
VerifyAccess();
return _templateRoot;
}
set
{
// Verify Context Access
VerifyAccess();
CheckSealed();
ValidateVisualTree(value);
_templateRoot = value;
// We have a FEF-based template now, so get rid of any prior
// Baml-based template content.
_optimizedTemplateContent = null;
}
}
///
/// Indicates if the VisualTree property should be serialized.
///
[EditorBrowsable(EditorBrowsableState.Never)]
public bool ShouldSerializeVisualTree()
{
// Verify Context Access
VerifyAccess();
return HasContent || VisualTree != null;
}
/*
///
/// The content of this template. The alternate form of template content is the VisualTree property.
/// One of these two properties may be set, but not both. Note that getting this property can cause
/// the content to created, which could be expensive. So to merely check if Content is set to a non-null
/// value, use the HasContent property.
///
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public FrameworkElement Content
{
get
{
// Verify Context Access
VerifyAccess();
if( HasContent )
{
return LoadTemplateContent() as FrameworkElement;
}
else
{
return null;
}
}
}
///
/// Returns true if the Content property should be serialized
///
[EditorBrowsable(EditorBrowsableState.Never)]
public bool ShouldSerializeContent()
{
// Verify Context Access
VerifyAccess();
return HasContent || VisualTree != null;
}
///
/// Resets the Content property to null;
///
[EditorBrowsable(EditorBrowsableState.Never)]
public void ResetContent()
{
// Verify Context Access
VerifyAccess();
_templateRoot = null;
_optimizedTemplateContent = null;
}
*/
///
/// The collection of resources that can be
/// consumed by the container and its sub-tree.
///
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public ResourceDictionary Resources
{
get
{
// Verify Context Access
VerifyAccess();
if( _resources == null )
{
_resources = new ResourceDictionary();
// A Template ResourceDictionary can be accessed across threads
_resources.CanBeAccessedAcrossThreads = true;
}
if( IsSealed )
{
_resources.IsReadOnly = true;
}
return _resources;
}
set
{
// Verify Context Access
VerifyAccess();
if( IsSealed )
{
throw new InvalidOperationException(SR.Get(SRID.CannotChangeAfterSealed, "Template"));
}
_resources = value;
if (_resources != null)
{
// A Template ResourceDictionary can be accessed across threads
_resources.CanBeAccessedAcrossThreads = true;
}
}
}
ResourceDictionary IHaveResources.Resources
{
get { return Resources; }
set { Resources = value; }
}
///
/// Tries to find a Reosurce for the given resourceKey in the current
/// template's ResourceDictionary.
///
internal object FindResource(object resourceKey, bool allowDeferredResourceReference, bool mustReturnDeferredResourceReference)
{
if ((_resources != null) && _resources.Contains(resourceKey))
{
bool canCache;
return _resources.FetchResource(resourceKey, allowDeferredResourceReference, mustReturnDeferredResourceReference, out canCache);
}
return DependencyProperty.UnsetValue;
}
///
/// FindName - Finds the element associated with the id defined under this control template.
/// Context of the FrameworkElement where this template is applied will be passed
/// as parameter.
///
/// string name
/// context where this template is applied
/// the element associated with the Name
public Object FindName( string name, FrameworkElement templatedParent)
{
// Verify Context Access
VerifyAccess();
if (templatedParent == null)
{
throw new ArgumentNullException("templatedParent");
}
if (this != templatedParent.TemplateInternal)
{
throw new InvalidOperationException(SR.Get(SRID.TemplateFindNameInInvalidElement));
}
return StyleHelper.FindNameInTemplateContent(templatedParent, name, this);
}
#endregion PublicProperties
#region INameScope
///
/// Registers the name - Context combination
///
/// Name to register
/// Element where name is defined
public void RegisterName(string name, object scopedElement)
{
// Verify Context Access
VerifyAccess();
_nameScope.RegisterName(name, scopedElement);
}
///
/// Unregisters the name - element combination
///
/// Name of the element
public void UnregisterName(string name)
{
// Verify Context Access
VerifyAccess();
_nameScope.UnregisterName(name);
}
///
/// Find the element given name
///
/// Name of the element
object INameScope.FindName(string name)
{
// Verify Context Access
VerifyAccess();
return _nameScope.FindName(name);
}
private NameScope _nameScope = new NameScope();
#endregion INameScope
#region NonPublicMethods
// ===========================================================================
// Validation methods
// ===========================================================================
// Validate against the following rules
// 1. The VisualTree's root must be a FrameworkElement.
private void ValidateVisualTree(FrameworkElementFactory templateRoot)
{
// The VisualTree's root must be a FrameworkElement.
if (templateRoot != null &&
typeof(FrameworkContentElement).IsAssignableFrom(templateRoot.Type))
{
throw new ArgumentException(SR.Get(SRID.VisualTreeRootIsFrameworkElement,
typeof(FrameworkElement).Name, templateRoot.Type.Name));
}
}
// ============================================================================
// These methods are invoked when a Template is being sealed
// ===========================================================================
#region Seal
internal virtual void ProcessTemplateBeforeSeal()
{
}
///
/// Seal this FrameworkTemplate
///
public void Seal()
{
// Verify Context Access
VerifyAccess();
StyleHelper.SealTemplate(
this,
ref _sealed,
_templateRoot,
TriggersInternal,
_resources,
_childIndexFromChildName,
ref ChildRecordFromChildIndex,
ref TriggerSourceRecordFromChildIndex,
ref ContainerDependents,
ref ResourceDependents,
ref EventDependents,
ref _triggerActions,
ref _dataTriggerRecordFromBinding,
ref _hasInstanceValues,
ref _eventHandlersStore);
}
// Subclasses need to call this method before any changes to their state.
internal void CheckSealed()
{
if (_sealed)
{
throw new InvalidOperationException(SR.Get(SRID.CannotChangeAfterSealed, "Template"));
}
}
// compute and cache the flags for ResourceReferences
internal void SetResourceReferenceState()
{
Debug.Assert(!_sealed, "call this method before template is sealed");
StyleHelper.SortResourceDependents(ref ResourceDependents);
for (int i=0; i < ResourceDependents.Count; ++i)
{
if (ResourceDependents[i].ChildIndex == 0)
{
WriteInternalFlag(InternalFlags.HasContainerResourceReferences, true);
}
else
{
WriteInternalFlag(InternalFlags.HasChildResourceReferences, true);
}
}
}
#endregion Seal
// ============================================================================
// These methods are invoked to during a call call to
// FE.EnsureVisual or FCE.EnsureLogical
// ============================================================================
#region InstantiateSubTree
//
// This method
// Creates the VisualTree
//
//[CodeAnalysis("AptcaMethodsShouldOnlyCallAptcaMethods")] //Tracking Bug: 29647
internal bool ApplyTemplateContent(
UncommonField templateDataField,
FrameworkElement container)
{
#if STYLE_TRACE
_timer.Begin();
#endif
if( TraceDependencyProperty.IsEnabled )
{
TraceDependencyProperty.Trace(
TraceEventType.Start,
TraceDependencyProperty.ApplyTemplateContent,
container,
this );
}
ValidateTemplatedParent(container);
bool visualsCreated = StyleHelper.ApplyTemplateContent(templateDataField, container,
_templateRoot, _lastChildIndex,
_childIndexFromChildName, this);
if( TraceDependencyProperty.IsEnabled )
{
TraceDependencyProperty.Trace(
TraceEventType.Stop,
TraceDependencyProperty.ApplyTemplateContent,
container,
this );
}
#if STYLE_TRACE
_timer.End();
if (visualsCreated)
{
string label = container.ID;
if (label == null || label.Length == 0)
label = container.GetHashCode().ToString();
Console.WriteLine(" Style.VT created for {0} {1} in {2:f2} msec",
container.GetType().Name, label, _timer.TimeOfLastPeriod);
}
#endif
return visualsCreated;
}
#endregion InstantiateSubTree
//+-----------------------------------------------------------------------------------------------------
//
// LoadContent
//
// Load the content of a template, returning the root element of the content. The second version
// loads the template content for use on an FE (i.e. under FrameworkElement.ApplyTemplate). The
// first version is used by the Content property for serialization, no optimization is
// performed, and TemplateBinding's show up as TemplateBindingExpression's. So it's just a normal
// tree.
//
//+------------------------------------------------------------------------------------------------------
///
/// Load the content of a template as an instance of an object. Calling this multiple times
/// will return separate instances.
///
public DependencyObject LoadContent()
{
// Verify Context Access
VerifyAccess();
if( VisualTree != null )
{
FrameworkObject frameworkObject = VisualTree.InstantiateUnoptimizedTree();
return frameworkObject.DO;
}
else
{
return LoadContent( null, null, null );
}
}
internal DependencyObject LoadContent(
DependencyObject container,
List affectedChildren,
UncommonField templatedNonFeChildrenField )
{
DependencyObject toReturn;
if( !HasContent )
{
return null;
}
// The following call is going to modify the _parserContext,
// so we can't let multiple threads in simultaneously. Also
// notice that we are acquiring the ThemeDictionaryLock. This
// is because the _parserContext used for template expansion
// shares data-structures such as the BamlMapTable and
// XamlTypeMapper with the parent ParserContext that was used
// to build the template in the first place. So if this template
// is from the theme then the ParserContext that is used for
// loading deferred content in the theme dictionary and the
// _parserContext used to load template content share the same
// instances of BamlMapTable and XamlTypeMapper. Hence we acquire
// the ThemeDictionaryLock in order to protect these data-structures
// from improper multi-threaded access.
lock (SystemResources.ThemeDictionaryLock)
{
_parserContext.StaticResourcesStack.Add(_staticResourceValues);
try
{
toReturn = StyleHelper.LoadOptimizedTemplateContent(
container,
_parserContext,
_optimizedTemplateContent,
this,
_componentConnector,
_styleConnector,
affectedChildren,
templatedNonFeChildrenField );
}
finally
{
_parserContext.StaticResourcesStack.RemoveAt(_parserContext.StaticResourcesStack.Count-1);
}
}
return toReturn;
}
///
/// Indicate if this template has optimized content.
///
public bool HasContent
{
get
{
// Verify Context Access
VerifyAccess();
return _optimizedTemplateContent != null && !_optimizedTemplateContent.IsEmpty;
}
}
// ===========================================================================
// These methods are invoked when the template has an alternate
// mechanism of generating a visual tree.
// ===========================================================================
#region BuildVisualTree
//
// This method
// 1. Is an alternative approach to building a visual tree from a FEF
// 2. Is used by ContentPresenter and Hyperlink to host their content
//
//CASRemoval:[StrongNameIdentityPermissionAttribute(SecurityAction.InheritanceDemand, PublicKey=Microsoft.Internal.BuildInfo.WCP_PUBLIC_KEY_STRING)]
internal virtual bool BuildVisualTree(FrameworkElement container)
{
return false;
}
//
// This property
// 1. Says if this Template is meant to use BuildVisualTree mechanism
// to generate a visual tree.
// 2. Is used in the following scenario.
// We need to preserve the treeState cache on a container node
// even after all its logical children have been added. This is so that
// construction of the style visual tree nodes can consume the cache.
// This method helps us know whether we should retain the cache for
// special scenarios when the visual tree is being built via BuildVisualTree
//
internal bool CanBuildVisualTree
{
get { return ReadInternalFlag(InternalFlags.CanBuildVisualTree); }
set { WriteInternalFlag(InternalFlags.CanBuildVisualTree, value); }
}
#endregion BuildVisualTree
///
/// This method is used by TypeDescriptor to determine if this property should
/// be serialized.
///
[EditorBrowsable(EditorBrowsableState.Never)]
public bool ShouldSerializeResources(XamlDesignerSerializationManager manager)
{
// Verify Context Access
VerifyAccess();
bool shouldSerialize = true;
if(manager != null)
{
shouldSerialize = (manager.XmlWriter == null);
}
return shouldSerialize;
}
// Extracts the required flag and returns
// bool to indicate if it is set or unset
private bool ReadInternalFlag(InternalFlags reqFlag)
{
return (_flags & reqFlag) != 0;
}
// Sets or Unsets the required flag based on
// the bool argument
private void WriteInternalFlag(InternalFlags reqFlag, bool set)
{
if (set)
{
_flags |= reqFlag;
}
else
{
_flags &= (~reqFlag);
}
}
#endregion NonPublicMethods
#region NonPublicProperties
//+---------------------------------------------------------------------------------------------------------------
//
// SetTemplateParentValues
//
// This method takes the "template parent values" (those that look like local values in the template), which
// are ordinarily shared, and sets them as local values on the FE/FCE that was just created. This is used
// during serialization.
//
//+----------------------------------------------------------------------------------------------------------------
internal static void SetTemplateParentValues(
string name,
object element,
FrameworkTemplate frameworkTemplate,
ref ProvideValueServiceProvider provideValueServiceProvider )
{
int childIndex;
// Loop through the shared values, and set them onto the element.
FrugalStructList childRecordFromChildIndex;
HybridDictionary childIndexFromChildName;
// Seal the template, and get the name->index and index->ChildRecord mappings
if (!frameworkTemplate.IsSealed)
{
frameworkTemplate.Seal();
}
childIndexFromChildName = frameworkTemplate._childIndexFromChildName;
childRecordFromChildIndex = frameworkTemplate.ChildRecordFromChildIndex;
// Calculate the child index
childIndex = StyleHelper.QueryChildIndexFromChildName(name, childIndexFromChildName);
// Do we have a ChildRecord for this index (i.e., there's some property set on it)?
if (childIndex < childRecordFromChildIndex.Count)
{
// Yes, get the record.
ChildRecord child = (ChildRecord)childRecordFromChildIndex[childIndex];
// Loop through the properties which are in some way set on this child
for (int i = 0; i < child.ValueLookupListFromProperty.Count; i++)
{
// And for each of those properties, loop through the potential values specified in the template
// for that property on that child.
for (int j = 0; j < child.ValueLookupListFromProperty.Entries[i].Value.Count; j++)
{
// Get this value (in valueLookup)
ChildValueLookup valueLookup;
valueLookup = (ChildValueLookup)child.ValueLookupListFromProperty.Entries[i].Value.List[j];
// See if this value is one that is considered to be locally set on the child element
if (valueLookup.LookupType == ValueLookupType.Simple
||
valueLookup.LookupType == ValueLookupType.Resource
||
valueLookup.LookupType == ValueLookupType.TemplateBinding)
{
// This shared value is for this element, so we'll set it.
object value = valueLookup.Value;
// If this is a TemplateBinding, put on an expression for it, so that it can
// be represented correctly (e.g. for serialization). Otherwise, keep it as an ME.
if (valueLookup.LookupType == ValueLookupType.TemplateBinding)
{
value = new TemplateBindingExpression( value as TemplateBindingExtension );
}
// Dynamic resources need to be converted to an expression also.
else if (valueLookup.LookupType == ValueLookupType.Resource)
{
value = new ResourceReferenceExpression(value);
}
// Bindings are handled as just an ME
// Set the value directly onto the element.
MarkupExtension me = value as MarkupExtension;
if (me != null)
{
// This is provided for completeness, but really there's only a few
// MEs that survive TemplateBamlRecordReader. E.g. NullExtension would
// have been converted to a null by now. There's only a few MEs that
// are preserved, e.g. Binding and DynamicResource. Other MEs, such as
// StaticResource, wouldn't be able to ProvideValue here, because we don't
// have a ParserContext.
if (provideValueServiceProvider == null)
{
provideValueServiceProvider = new ProvideValueServiceProvider();
}
provideValueServiceProvider.SetData(element, valueLookup.Property);
value = me.ProvideValue(provideValueServiceProvider);
provideValueServiceProvider.ClearData();
}
(element as DependencyObject).SetValue(valueLookup.Property, value); //sharedDp.Dp, value );
}
}
}
}
}
//
// TargetType for ControlTemplate
//
internal virtual Type TargetTypeInternal
{
get { return null; }
}
// Subclasses must provide a way for the parser to directly set the
// target type.
internal abstract void SetTargetTypeInternal(Type targetType);
//
// DataType for DataTemplate
//
internal virtual object DataTypeInternal
{
get { return null; }
}
#region ISealable
///
/// Can this template be sealed
///
bool ISealable.CanSeal
{
get { return true; }
}
///
/// Is this template sealed
///
bool ISealable.IsSealed
{
get { return IsSealed; }
}
///
/// Seal this template
///
void ISealable.Seal()
{
Seal();
}
#endregion ISealable
//
// Collection of Triggers for a ControlTemplate
//
internal virtual TriggerCollection TriggersInternal
{
get { return null; }
}
//
// Says if this template contains any resource references
//
internal bool HasResourceReferences
{
get { return ResourceDependents.Count > 0; }
}
//
// Says if this template contains any resource references for properties on the container
//
internal bool HasContainerResourceReferences
{
get { return ReadInternalFlag(InternalFlags.HasContainerResourceReferences); }
}
//
// Says if this template contains any resource references for properties on children
//
internal bool HasChildResourceReferences
{
get { return ReadInternalFlag(InternalFlags.HasChildResourceReferences); }
}
//
// Says if this template contains any event handlers
//
internal bool HasEventDependents
{
get { return (EventDependents.Count > 0); }
}
//
// Says if this template contains any per-instance values
//
internal bool HasInstanceValues
{
get { return _hasInstanceValues; }
}
//
// Says if we have anything listening for the Loaded or Unloaded
// event (used for an optimization in FrameworkElement).
//
internal bool HasLoadedChangeHandler
{
get { return ReadInternalFlag(InternalFlags.HasLoadedChangeHandler); }
set { WriteInternalFlag(InternalFlags.HasLoadedChangeHandler, value); }
}
// OptimizedTemplateContent holds the content of a template, in optimized form
// (optimized such that shareable property values are shared across all
// instances of the template). This only exists if the template is defined
// in Baml. If it is defined with FEFs (the less common case), this will
// be null, and the VisualTree property will hold the FEF tree.
internal OptimizedTemplateContent OptimizedTemplateContent
{
get
{
if( _optimizedTemplateContent == null )
{
_optimizedTemplateContent = new OptimizedTemplateContent(this);
}
return _optimizedTemplateContent;
}
}
//
// Give the template its own copy of the parser context. It needs a copy, because it's
// going to use it later on every application.
//
internal void CopyParserContext( ParserContext parserContext )
{
_parserContext = parserContext.ScopedCopy( false /*copyNameScopeStack*/ );
// We need to clear the Journal bit, because we know we won't be able to honor it correctly.
// Journaling journals the properties in the logical tree, so doesn't journal properties in the
// Template/Resources. This shouldn't be hard-coded here, but is an internal solution for V1.
_parserContext.SkipJournaledProperties = false;
}
//
// ParserContext cached with this template.
//
internal ParserContext ParserContext
{
get { return _parserContext; }
}
//
// Store all the event handlers for this Style TargetType
//
internal EventHandlersStore EventHandlersStore
{
get { return _eventHandlersStore; }
}
//
// Style and component connectors used during template
// application.
//
internal IStyleConnector StyleConnector
{
get { return _styleConnector; }
set { _styleConnector = value; }
}
internal IComponentConnector ComponentConnector
{
get { return _componentConnector; }
set { _componentConnector = value; }
}
//
// Prefetched values for static resources
//
internal object[] StaticResourceValues
{
get { return _staticResourceValues; }
set { _staticResourceValues = value; }
}
#endregion NonPublicProperties
#region Data
private InternalFlags _flags;
private bool _sealed; // passed by ref, so cannot use flags
private bool _hasInstanceValues; // passed by ref, so cannot use flags
private ParserContext _parserContext;
private IStyleConnector _styleConnector;
private IComponentConnector _componentConnector;
// If we're a FEF-based template, we'll have a _templateRoot. Otherwise
// we're a baml-based template, and we'll have an _optimizedTemplateContent.
private FrameworkElementFactory _templateRoot;
internal OptimizedTemplateContent _optimizedTemplateContent;
//
// Used to generate childIndex for each TemplateNode
//
internal HybridDictionary _childIndexFromChildName = new HybridDictionary();
internal int _lastChildIndex = 1; // 0 means "self" (container), no instance ever has index 0
//
// Resource dictionary associated with this template.
//
internal ResourceDictionary _resources = null;
//
// Used by EventTrigger: Maps a RoutedEventID to a set of TriggerAction objects
// to be performed.
//
internal HybridDictionary _triggerActions = null;
//
// Shared tables used during GetValue
//
internal FrugalStructList ChildRecordFromChildIndex = new FrugalStructList(); // Indexed by Child.ChildIndex
//
// Shared tables used during OnTriggerSourcePropertyInvalidated
//
internal FrugalStructList> TriggerSourceRecordFromChildIndex = new FrugalStructList>();
// Dictionary of property triggers that have TriggerActions, keyed via DP.GlobalIndex affecting those triggers.
// Each trigger can be listed multiple times, if they are dependent on multiple properties.
internal FrugalMap PropertyTriggersWithActions;
//
// Shared tables used during OnStyleInvalidated/OnTemplateInvalidated/InvalidateTree
//
// Properties driven on the container (by the Style) that should be
// invalidated when the style gets applied/unapplied. These properties
// could have been set via Style.SetValue or VisualTrigger.SetValue
internal FrugalStructList ContainerDependents = new FrugalStructList();
// Properties driven by a resource that should be invalidated
// when a resource dictionary changes or when the tree changes
// or when a Style is Invalidated
internal FrugalStructList ResourceDependents = new FrugalStructList();
// Data trigger information. An entry for each Binding that appears in a
// condition of a data trigger.
// Synchronized: Covered by Style instance
internal HybridDictionary _dataTriggerRecordFromBinding;
// An entry for each Binding that appears in a DataTrigger with EnterAction or ExitAction
// This overlaps but should not be the same as _dataTriggerRecordFromBinding above:
// A DataTrigger can have Setters but no EnterAction/ExitAction. (The reverse can also be true.)
internal HybridDictionary DataTriggersWithActions = null;
// It is possible for trigger events to occur before template expansion has
// taken place. In these cases, we cannot resolve the appropriate target name
// at that time. We defer invoking these actions until template expansion
// is complete.
// The key to the dictionary are the individual object instances that this
// template applies to. (We might be holding deferred actions for multiple
// objects.)
// The value of the dictionary is the trigger object and one of its action
// lists stored in the struct DeferredAction.
internal HybridDictionary DeferredActions = null;
// Keep track of the template children elements for which the template has a Loaded
// or Unloaded listener.
internal class TemplateChildLoadedFlags
{
public bool HasLoadedChangedHandler;
public bool HasUnloadedChangedHandler;
}
internal HybridDictionary _TemplateChildLoadedDictionary = new HybridDictionary();
//
// Shared tables used during Event Routing
//
// Events driven by a this style. An entry for every childIndex that has associated events.
// childIndex '0' is used to represent events set ont he style's TargetType. This data-structure
// will be frequently looked up during event routing.
internal ItemStructList EventDependents = new ItemStructList(1);
// Used to store a private delegate that called back during event
// routing so we can process EventTriggers
private EventHandlersStore _eventHandlersStore = null;
// Prefetched values for StaticResources
private object[] _staticResourceValues = null;
#if STYLE_TRACE
// Time that is used only when style tracing is enabled
private MS.Internal.Utility.HFTimer _timer = new MS.Internal.Utility.HFTimer();
#endif
#if DEBUG
// Debug counter for intelligent breakpoints.
static private int _globalDebugInstanceCounter = 0;
private int _debugInstanceCounter;
#endif
[Flags]
private enum InternalFlags : uint
{
//Sealed = 0x00000001,
//HasInstanceValues = 0x00000002,
CanBuildVisualTree = 0x00000004,
HasLoadedChangeHandler = 0x00000008,
HasContainerResourceReferences = 0x00000010,
HasChildResourceReferences = 0x00000020,
}
#endregion Data
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------------
//
// File: FrameworkTemplate.cs
//
// Description:
// A generic class that allow instantiation of a tree of Framework[Content]Elements.
//
// Copyright (C) 2005 by Microsoft Corporation. All rights reserved.
//
//-----------------------------------------------------------------------------------
using MS.Internal; // Helper
using MS.Utility; // ChildValueLookupList
using System.ComponentModel; // DesignerSerializationVisibility, DefaultValueAttribute
using System.Collections; // Hashtable
using System.Collections.Generic; // List
using System.Collections.Specialized; // HybridDictionary
using System.Diagnostics; // Debug
using System.Threading; // Interlocked
using System.Windows.Media.Animation; // Timeline
using System.Windows.Markup; // XamlTemplateSerializer, ContentPropertyAttribute
using System.Windows.Media;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Threading; // DispatcherObject
namespace System.Windows
{
///
/// A generic class that allow instantiation of a
/// tree of Framework[Content]Elements.
///
[ContentProperty("VisualTree")]
[Localizability(LocalizationCategory.NeverLocalize)] // All properties on template are not localizable
public abstract class FrameworkTemplate : DispatcherObject, INameScope, ISealable, IHaveResources
{
///
///
protected FrameworkTemplate()
{
#if DEBUG
_debugInstanceCounter = ++_globalDebugInstanceCounter;
#endif
}
#region PublicMethods
///
/// Subclasses must override this method if they need to
/// impose additional rules for the TemplatedParent
///
protected virtual void ValidateTemplatedParent(FrameworkElement templatedParent)
{
Debug.Assert(templatedParent != null,
"Must have a non-null FE TemplatedParent.");
}
#endregion PublicMethods
#region PublicProperties
///
/// Says if this template has been sealed
///
public bool IsSealed
{
get
{
// Verify Context Access
VerifyAccess();
return _sealed;
}
}
///
/// Root node of the template
///
public FrameworkElementFactory VisualTree
{
get
{
// Verify Context Access
VerifyAccess();
return _templateRoot;
}
set
{
// Verify Context Access
VerifyAccess();
CheckSealed();
ValidateVisualTree(value);
_templateRoot = value;
// We have a FEF-based template now, so get rid of any prior
// Baml-based template content.
_optimizedTemplateContent = null;
}
}
///
/// Indicates if the VisualTree property should be serialized.
///
[EditorBrowsable(EditorBrowsableState.Never)]
public bool ShouldSerializeVisualTree()
{
// Verify Context Access
VerifyAccess();
return HasContent || VisualTree != null;
}
/*
///
/// The content of this template. The alternate form of template content is the VisualTree property.
/// One of these two properties may be set, but not both. Note that getting this property can cause
/// the content to created, which could be expensive. So to merely check if Content is set to a non-null
/// value, use the HasContent property.
///
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public FrameworkElement Content
{
get
{
// Verify Context Access
VerifyAccess();
if( HasContent )
{
return LoadTemplateContent() as FrameworkElement;
}
else
{
return null;
}
}
}
///
/// Returns true if the Content property should be serialized
///
[EditorBrowsable(EditorBrowsableState.Never)]
public bool ShouldSerializeContent()
{
// Verify Context Access
VerifyAccess();
return HasContent || VisualTree != null;
}
///
/// Resets the Content property to null;
///
[EditorBrowsable(EditorBrowsableState.Never)]
public void ResetContent()
{
// Verify Context Access
VerifyAccess();
_templateRoot = null;
_optimizedTemplateContent = null;
}
*/
///
/// The collection of resources that can be
/// consumed by the container and its sub-tree.
///
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public ResourceDictionary Resources
{
get
{
// Verify Context Access
VerifyAccess();
if( _resources == null )
{
_resources = new ResourceDictionary();
// A Template ResourceDictionary can be accessed across threads
_resources.CanBeAccessedAcrossThreads = true;
}
if( IsSealed )
{
_resources.IsReadOnly = true;
}
return _resources;
}
set
{
// Verify Context Access
VerifyAccess();
if( IsSealed )
{
throw new InvalidOperationException(SR.Get(SRID.CannotChangeAfterSealed, "Template"));
}
_resources = value;
if (_resources != null)
{
// A Template ResourceDictionary can be accessed across threads
_resources.CanBeAccessedAcrossThreads = true;
}
}
}
ResourceDictionary IHaveResources.Resources
{
get { return Resources; }
set { Resources = value; }
}
///
/// Tries to find a Reosurce for the given resourceKey in the current
/// template's ResourceDictionary.
///
internal object FindResource(object resourceKey, bool allowDeferredResourceReference, bool mustReturnDeferredResourceReference)
{
if ((_resources != null) && _resources.Contains(resourceKey))
{
bool canCache;
return _resources.FetchResource(resourceKey, allowDeferredResourceReference, mustReturnDeferredResourceReference, out canCache);
}
return DependencyProperty.UnsetValue;
}
///
/// FindName - Finds the element associated with the id defined under this control template.
/// Context of the FrameworkElement where this template is applied will be passed
/// as parameter.
///
/// string name
/// context where this template is applied
/// the element associated with the Name
public Object FindName( string name, FrameworkElement templatedParent)
{
// Verify Context Access
VerifyAccess();
if (templatedParent == null)
{
throw new ArgumentNullException("templatedParent");
}
if (this != templatedParent.TemplateInternal)
{
throw new InvalidOperationException(SR.Get(SRID.TemplateFindNameInInvalidElement));
}
return StyleHelper.FindNameInTemplateContent(templatedParent, name, this);
}
#endregion PublicProperties
#region INameScope
///
/// Registers the name - Context combination
///
/// Name to register
/// Element where name is defined
public void RegisterName(string name, object scopedElement)
{
// Verify Context Access
VerifyAccess();
_nameScope.RegisterName(name, scopedElement);
}
///
/// Unregisters the name - element combination
///
/// Name of the element
public void UnregisterName(string name)
{
// Verify Context Access
VerifyAccess();
_nameScope.UnregisterName(name);
}
///
/// Find the element given name
///
/// Name of the element
object INameScope.FindName(string name)
{
// Verify Context Access
VerifyAccess();
return _nameScope.FindName(name);
}
private NameScope _nameScope = new NameScope();
#endregion INameScope
#region NonPublicMethods
// ===========================================================================
// Validation methods
// ===========================================================================
// Validate against the following rules
// 1. The VisualTree's root must be a FrameworkElement.
private void ValidateVisualTree(FrameworkElementFactory templateRoot)
{
// The VisualTree's root must be a FrameworkElement.
if (templateRoot != null &&
typeof(FrameworkContentElement).IsAssignableFrom(templateRoot.Type))
{
throw new ArgumentException(SR.Get(SRID.VisualTreeRootIsFrameworkElement,
typeof(FrameworkElement).Name, templateRoot.Type.Name));
}
}
// ============================================================================
// These methods are invoked when a Template is being sealed
// ===========================================================================
#region Seal
internal virtual void ProcessTemplateBeforeSeal()
{
}
///
/// Seal this FrameworkTemplate
///
public void Seal()
{
// Verify Context Access
VerifyAccess();
StyleHelper.SealTemplate(
this,
ref _sealed,
_templateRoot,
TriggersInternal,
_resources,
_childIndexFromChildName,
ref ChildRecordFromChildIndex,
ref TriggerSourceRecordFromChildIndex,
ref ContainerDependents,
ref ResourceDependents,
ref EventDependents,
ref _triggerActions,
ref _dataTriggerRecordFromBinding,
ref _hasInstanceValues,
ref _eventHandlersStore);
}
// Subclasses need to call this method before any changes to their state.
internal void CheckSealed()
{
if (_sealed)
{
throw new InvalidOperationException(SR.Get(SRID.CannotChangeAfterSealed, "Template"));
}
}
// compute and cache the flags for ResourceReferences
internal void SetResourceReferenceState()
{
Debug.Assert(!_sealed, "call this method before template is sealed");
StyleHelper.SortResourceDependents(ref ResourceDependents);
for (int i=0; i < ResourceDependents.Count; ++i)
{
if (ResourceDependents[i].ChildIndex == 0)
{
WriteInternalFlag(InternalFlags.HasContainerResourceReferences, true);
}
else
{
WriteInternalFlag(InternalFlags.HasChildResourceReferences, true);
}
}
}
#endregion Seal
// ============================================================================
// These methods are invoked to during a call call to
// FE.EnsureVisual or FCE.EnsureLogical
// ============================================================================
#region InstantiateSubTree
//
// This method
// Creates the VisualTree
//
//[CodeAnalysis("AptcaMethodsShouldOnlyCallAptcaMethods")] //Tracking Bug: 29647
internal bool ApplyTemplateContent(
UncommonField templateDataField,
FrameworkElement container)
{
#if STYLE_TRACE
_timer.Begin();
#endif
if( TraceDependencyProperty.IsEnabled )
{
TraceDependencyProperty.Trace(
TraceEventType.Start,
TraceDependencyProperty.ApplyTemplateContent,
container,
this );
}
ValidateTemplatedParent(container);
bool visualsCreated = StyleHelper.ApplyTemplateContent(templateDataField, container,
_templateRoot, _lastChildIndex,
_childIndexFromChildName, this);
if( TraceDependencyProperty.IsEnabled )
{
TraceDependencyProperty.Trace(
TraceEventType.Stop,
TraceDependencyProperty.ApplyTemplateContent,
container,
this );
}
#if STYLE_TRACE
_timer.End();
if (visualsCreated)
{
string label = container.ID;
if (label == null || label.Length == 0)
label = container.GetHashCode().ToString();
Console.WriteLine(" Style.VT created for {0} {1} in {2:f2} msec",
container.GetType().Name, label, _timer.TimeOfLastPeriod);
}
#endif
return visualsCreated;
}
#endregion InstantiateSubTree
//+-----------------------------------------------------------------------------------------------------
//
// LoadContent
//
// Load the content of a template, returning the root element of the content. The second version
// loads the template content for use on an FE (i.e. under FrameworkElement.ApplyTemplate). The
// first version is used by the Content property for serialization, no optimization is
// performed, and TemplateBinding's show up as TemplateBindingExpression's. So it's just a normal
// tree.
//
//+------------------------------------------------------------------------------------------------------
///
/// Load the content of a template as an instance of an object. Calling this multiple times
/// will return separate instances.
///
public DependencyObject LoadContent()
{
// Verify Context Access
VerifyAccess();
if( VisualTree != null )
{
FrameworkObject frameworkObject = VisualTree.InstantiateUnoptimizedTree();
return frameworkObject.DO;
}
else
{
return LoadContent( null, null, null );
}
}
internal DependencyObject LoadContent(
DependencyObject container,
List affectedChildren,
UncommonField templatedNonFeChildrenField )
{
DependencyObject toReturn;
if( !HasContent )
{
return null;
}
// The following call is going to modify the _parserContext,
// so we can't let multiple threads in simultaneously. Also
// notice that we are acquiring the ThemeDictionaryLock. This
// is because the _parserContext used for template expansion
// shares data-structures such as the BamlMapTable and
// XamlTypeMapper with the parent ParserContext that was used
// to build the template in the first place. So if this template
// is from the theme then the ParserContext that is used for
// loading deferred content in the theme dictionary and the
// _parserContext used to load template content share the same
// instances of BamlMapTable and XamlTypeMapper. Hence we acquire
// the ThemeDictionaryLock in order to protect these data-structures
// from improper multi-threaded access.
lock (SystemResources.ThemeDictionaryLock)
{
_parserContext.StaticResourcesStack.Add(_staticResourceValues);
try
{
toReturn = StyleHelper.LoadOptimizedTemplateContent(
container,
_parserContext,
_optimizedTemplateContent,
this,
_componentConnector,
_styleConnector,
affectedChildren,
templatedNonFeChildrenField );
}
finally
{
_parserContext.StaticResourcesStack.RemoveAt(_parserContext.StaticResourcesStack.Count-1);
}
}
return toReturn;
}
///
/// Indicate if this template has optimized content.
///
public bool HasContent
{
get
{
// Verify Context Access
VerifyAccess();
return _optimizedTemplateContent != null && !_optimizedTemplateContent.IsEmpty;
}
}
// ===========================================================================
// These methods are invoked when the template has an alternate
// mechanism of generating a visual tree.
// ===========================================================================
#region BuildVisualTree
//
// This method
// 1. Is an alternative approach to building a visual tree from a FEF
// 2. Is used by ContentPresenter and Hyperlink to host their content
//
//CASRemoval:[StrongNameIdentityPermissionAttribute(SecurityAction.InheritanceDemand, PublicKey=Microsoft.Internal.BuildInfo.WCP_PUBLIC_KEY_STRING)]
internal virtual bool BuildVisualTree(FrameworkElement container)
{
return false;
}
//
// This property
// 1. Says if this Template is meant to use BuildVisualTree mechanism
// to generate a visual tree.
// 2. Is used in the following scenario.
// We need to preserve the treeState cache on a container node
// even after all its logical children have been added. This is so that
// construction of the style visual tree nodes can consume the cache.
// This method helps us know whether we should retain the cache for
// special scenarios when the visual tree is being built via BuildVisualTree
//
internal bool CanBuildVisualTree
{
get { return ReadInternalFlag(InternalFlags.CanBuildVisualTree); }
set { WriteInternalFlag(InternalFlags.CanBuildVisualTree, value); }
}
#endregion BuildVisualTree
///
/// This method is used by TypeDescriptor to determine if this property should
/// be serialized.
///
[EditorBrowsable(EditorBrowsableState.Never)]
public bool ShouldSerializeResources(XamlDesignerSerializationManager manager)
{
// Verify Context Access
VerifyAccess();
bool shouldSerialize = true;
if(manager != null)
{
shouldSerialize = (manager.XmlWriter == null);
}
return shouldSerialize;
}
// Extracts the required flag and returns
// bool to indicate if it is set or unset
private bool ReadInternalFlag(InternalFlags reqFlag)
{
return (_flags & reqFlag) != 0;
}
// Sets or Unsets the required flag based on
// the bool argument
private void WriteInternalFlag(InternalFlags reqFlag, bool set)
{
if (set)
{
_flags |= reqFlag;
}
else
{
_flags &= (~reqFlag);
}
}
#endregion NonPublicMethods
#region NonPublicProperties
//+---------------------------------------------------------------------------------------------------------------
//
// SetTemplateParentValues
//
// This method takes the "template parent values" (those that look like local values in the template), which
// are ordinarily shared, and sets them as local values on the FE/FCE that was just created. This is used
// during serialization.
//
//+----------------------------------------------------------------------------------------------------------------
internal static void SetTemplateParentValues(
string name,
object element,
FrameworkTemplate frameworkTemplate,
ref ProvideValueServiceProvider provideValueServiceProvider )
{
int childIndex;
// Loop through the shared values, and set them onto the element.
FrugalStructList childRecordFromChildIndex;
HybridDictionary childIndexFromChildName;
// Seal the template, and get the name->index and index->ChildRecord mappings
if (!frameworkTemplate.IsSealed)
{
frameworkTemplate.Seal();
}
childIndexFromChildName = frameworkTemplate._childIndexFromChildName;
childRecordFromChildIndex = frameworkTemplate.ChildRecordFromChildIndex;
// Calculate the child index
childIndex = StyleHelper.QueryChildIndexFromChildName(name, childIndexFromChildName);
// Do we have a ChildRecord for this index (i.e., there's some property set on it)?
if (childIndex < childRecordFromChildIndex.Count)
{
// Yes, get the record.
ChildRecord child = (ChildRecord)childRecordFromChildIndex[childIndex];
// Loop through the properties which are in some way set on this child
for (int i = 0; i < child.ValueLookupListFromProperty.Count; i++)
{
// And for each of those properties, loop through the potential values specified in the template
// for that property on that child.
for (int j = 0; j < child.ValueLookupListFromProperty.Entries[i].Value.Count; j++)
{
// Get this value (in valueLookup)
ChildValueLookup valueLookup;
valueLookup = (ChildValueLookup)child.ValueLookupListFromProperty.Entries[i].Value.List[j];
// See if this value is one that is considered to be locally set on the child element
if (valueLookup.LookupType == ValueLookupType.Simple
||
valueLookup.LookupType == ValueLookupType.Resource
||
valueLookup.LookupType == ValueLookupType.TemplateBinding)
{
// This shared value is for this element, so we'll set it.
object value = valueLookup.Value;
// If this is a TemplateBinding, put on an expression for it, so that it can
// be represented correctly (e.g. for serialization). Otherwise, keep it as an ME.
if (valueLookup.LookupType == ValueLookupType.TemplateBinding)
{
value = new TemplateBindingExpression( value as TemplateBindingExtension );
}
// Dynamic resources need to be converted to an expression also.
else if (valueLookup.LookupType == ValueLookupType.Resource)
{
value = new ResourceReferenceExpression(value);
}
// Bindings are handled as just an ME
// Set the value directly onto the element.
MarkupExtension me = value as MarkupExtension;
if (me != null)
{
// This is provided for completeness, but really there's only a few
// MEs that survive TemplateBamlRecordReader. E.g. NullExtension would
// have been converted to a null by now. There's only a few MEs that
// are preserved, e.g. Binding and DynamicResource. Other MEs, such as
// StaticResource, wouldn't be able to ProvideValue here, because we don't
// have a ParserContext.
if (provideValueServiceProvider == null)
{
provideValueServiceProvider = new ProvideValueServiceProvider();
}
provideValueServiceProvider.SetData(element, valueLookup.Property);
value = me.ProvideValue(provideValueServiceProvider);
provideValueServiceProvider.ClearData();
}
(element as DependencyObject).SetValue(valueLookup.Property, value); //sharedDp.Dp, value );
}
}
}
}
}
//
// TargetType for ControlTemplate
//
internal virtual Type TargetTypeInternal
{
get { return null; }
}
// Subclasses must provide a way for the parser to directly set the
// target type.
internal abstract void SetTargetTypeInternal(Type targetType);
//
// DataType for DataTemplate
//
internal virtual object DataTypeInternal
{
get { return null; }
}
#region ISealable
///
/// Can this template be sealed
///
bool ISealable.CanSeal
{
get { return true; }
}
///
/// Is this template sealed
///
bool ISealable.IsSealed
{
get { return IsSealed; }
}
///
/// Seal this template
///
void ISealable.Seal()
{
Seal();
}
#endregion ISealable
//
// Collection of Triggers for a ControlTemplate
//
internal virtual TriggerCollection TriggersInternal
{
get { return null; }
}
//
// Says if this template contains any resource references
//
internal bool HasResourceReferences
{
get { return ResourceDependents.Count > 0; }
}
//
// Says if this template contains any resource references for properties on the container
//
internal bool HasContainerResourceReferences
{
get { return ReadInternalFlag(InternalFlags.HasContainerResourceReferences); }
}
//
// Says if this template contains any resource references for properties on children
//
internal bool HasChildResourceReferences
{
get { return ReadInternalFlag(InternalFlags.HasChildResourceReferences); }
}
//
// Says if this template contains any event handlers
//
internal bool HasEventDependents
{
get { return (EventDependents.Count > 0); }
}
//
// Says if this template contains any per-instance values
//
internal bool HasInstanceValues
{
get { return _hasInstanceValues; }
}
//
// Says if we have anything listening for the Loaded or Unloaded
// event (used for an optimization in FrameworkElement).
//
internal bool HasLoadedChangeHandler
{
get { return ReadInternalFlag(InternalFlags.HasLoadedChangeHandler); }
set { WriteInternalFlag(InternalFlags.HasLoadedChangeHandler, value); }
}
// OptimizedTemplateContent holds the content of a template, in optimized form
// (optimized such that shareable property values are shared across all
// instances of the template). This only exists if the template is defined
// in Baml. If it is defined with FEFs (the less common case), this will
// be null, and the VisualTree property will hold the FEF tree.
internal OptimizedTemplateContent OptimizedTemplateContent
{
get
{
if( _optimizedTemplateContent == null )
{
_optimizedTemplateContent = new OptimizedTemplateContent(this);
}
return _optimizedTemplateContent;
}
}
//
// Give the template its own copy of the parser context. It needs a copy, because it's
// going to use it later on every application.
//
internal void CopyParserContext( ParserContext parserContext )
{
_parserContext = parserContext.ScopedCopy( false /*copyNameScopeStack*/ );
// We need to clear the Journal bit, because we know we won't be able to honor it correctly.
// Journaling journals the properties in the logical tree, so doesn't journal properties in the
// Template/Resources. This shouldn't be hard-coded here, but is an internal solution for V1.
_parserContext.SkipJournaledProperties = false;
}
//
// ParserContext cached with this template.
//
internal ParserContext ParserContext
{
get { return _parserContext; }
}
//
// Store all the event handlers for this Style TargetType
//
internal EventHandlersStore EventHandlersStore
{
get { return _eventHandlersStore; }
}
//
// Style and component connectors used during template
// application.
//
internal IStyleConnector StyleConnector
{
get { return _styleConnector; }
set { _styleConnector = value; }
}
internal IComponentConnector ComponentConnector
{
get { return _componentConnector; }
set { _componentConnector = value; }
}
//
// Prefetched values for static resources
//
internal object[] StaticResourceValues
{
get { return _staticResourceValues; }
set { _staticResourceValues = value; }
}
#endregion NonPublicProperties
#region Data
private InternalFlags _flags;
private bool _sealed; // passed by ref, so cannot use flags
private bool _hasInstanceValues; // passed by ref, so cannot use flags
private ParserContext _parserContext;
private IStyleConnector _styleConnector;
private IComponentConnector _componentConnector;
// If we're a FEF-based template, we'll have a _templateRoot. Otherwise
// we're a baml-based template, and we'll have an _optimizedTemplateContent.
private FrameworkElementFactory _templateRoot;
internal OptimizedTemplateContent _optimizedTemplateContent;
//
// Used to generate childIndex for each TemplateNode
//
internal HybridDictionary _childIndexFromChildName = new HybridDictionary();
internal int _lastChildIndex = 1; // 0 means "self" (container), no instance ever has index 0
//
// Resource dictionary associated with this template.
//
internal ResourceDictionary _resources = null;
//
// Used by EventTrigger: Maps a RoutedEventID to a set of TriggerAction objects
// to be performed.
//
internal HybridDictionary _triggerActions = null;
//
// Shared tables used during GetValue
//
internal FrugalStructList ChildRecordFromChildIndex = new FrugalStructList(); // Indexed by Child.ChildIndex
//
// Shared tables used during OnTriggerSourcePropertyInvalidated
//
internal FrugalStructList> TriggerSourceRecordFromChildIndex = new FrugalStructList>();
// Dictionary of property triggers that have TriggerActions, keyed via DP.GlobalIndex affecting those triggers.
// Each trigger can be listed multiple times, if they are dependent on multiple properties.
internal FrugalMap PropertyTriggersWithActions;
//
// Shared tables used during OnStyleInvalidated/OnTemplateInvalidated/InvalidateTree
//
// Properties driven on the container (by the Style) that should be
// invalidated when the style gets applied/unapplied. These properties
// could have been set via Style.SetValue or VisualTrigger.SetValue
internal FrugalStructList ContainerDependents = new FrugalStructList();
// Properties driven by a resource that should be invalidated
// when a resource dictionary changes or when the tree changes
// or when a Style is Invalidated
internal FrugalStructList ResourceDependents = new FrugalStructList();
// Data trigger information. An entry for each Binding that appears in a
// condition of a data trigger.
// Synchronized: Covered by Style instance
internal HybridDictionary _dataTriggerRecordFromBinding;
// An entry for each Binding that appears in a DataTrigger with EnterAction or ExitAction
// This overlaps but should not be the same as _dataTriggerRecordFromBinding above:
// A DataTrigger can have Setters but no EnterAction/ExitAction. (The reverse can also be true.)
internal HybridDictionary DataTriggersWithActions = null;
// It is possible for trigger events to occur before template expansion has
// taken place. In these cases, we cannot resolve the appropriate target name
// at that time. We defer invoking these actions until template expansion
// is complete.
// The key to the dictionary are the individual object instances that this
// template applies to. (We might be holding deferred actions for multiple
// objects.)
// The value of the dictionary is the trigger object and one of its action
// lists stored in the struct DeferredAction.
internal HybridDictionary DeferredActions = null;
// Keep track of the template children elements for which the template has a Loaded
// or Unloaded listener.
internal class TemplateChildLoadedFlags
{
public bool HasLoadedChangedHandler;
public bool HasUnloadedChangedHandler;
}
internal HybridDictionary _TemplateChildLoadedDictionary = new HybridDictionary();
//
// Shared tables used during Event Routing
//
// Events driven by a this style. An entry for every childIndex that has associated events.
// childIndex '0' is used to represent events set ont he style's TargetType. This data-structure
// will be frequently looked up during event routing.
internal ItemStructList EventDependents = new ItemStructList(1);
// Used to store a private delegate that called back during event
// routing so we can process EventTriggers
private EventHandlersStore _eventHandlersStore = null;
// Prefetched values for StaticResources
private object[] _staticResourceValues = null;
#if STYLE_TRACE
// Time that is used only when style tracing is enabled
private MS.Internal.Utility.HFTimer _timer = new MS.Internal.Utility.HFTimer();
#endif
#if DEBUG
// Debug counter for intelligent breakpoints.
static private int _globalDebugInstanceCounter = 0;
private int _debugInstanceCounter;
#endif
[Flags]
private enum InternalFlags : uint
{
//Sealed = 0x00000001,
//HasInstanceValues = 0x00000002,
CanBuildVisualTree = 0x00000004,
HasLoadedChangeHandler = 0x00000008,
HasContainerResourceReferences = 0x00000010,
HasChildResourceReferences = 0x00000020,
}
#endregion Data
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- SchemaImporter.cs
- Type.cs
- DateTimeOffsetConverter.cs
- SystemTcpStatistics.cs
- NonVisualControlAttribute.cs
- XmlAttributeCollection.cs
- WebAdminConfigurationHelper.cs
- TraceSection.cs
- AccessKeyManager.cs
- CodeCatchClause.cs
- CompilationAssemblyInstallComponent.cs
- ElapsedEventArgs.cs
- StylusCaptureWithinProperty.cs
- XPathBinder.cs
- MachineSettingsSection.cs
- AllMembershipCondition.cs
- SurrogateChar.cs
- TransformConverter.cs
- FixedSOMLineCollection.cs
- MessageAction.cs
- PriorityQueue.cs
- VectorAnimation.cs
- TransformationRules.cs
- PrivateFontCollection.cs
- Guid.cs
- CodeRemoveEventStatement.cs
- CoTaskMemSafeHandle.cs
- TextRangeEditTables.cs
- ProcessActivityTreeOptions.cs
- SemanticResultValue.cs
- RtType.cs
- DocumentAutomationPeer.cs
- CodeCompiler.cs
- util.cs
- Guid.cs
- SqlTypeSystemProvider.cs
- FullTextLine.cs
- ToolStripItemRenderEventArgs.cs
- WindowsTab.cs
- CompressedStack.cs
- TextServicesProperty.cs
- ZipArchive.cs
- AxHost.cs
- DataServiceQueryOfT.cs
- ProfileGroupSettingsCollection.cs
- BrowserCapabilitiesFactory.cs
- ContentType.cs
- XmlILOptimizerVisitor.cs
- QueryResult.cs
- controlskin.cs
- ZipIOCentralDirectoryBlock.cs
- CustomSignedXml.cs
- AjaxFrameworkAssemblyAttribute.cs
- Converter.cs
- MediaPlayer.cs
- NestedContainer.cs
- NgenServicingAttributes.cs
- StorageSetMapping.cs
- ListSortDescriptionCollection.cs
- ObjectReferenceStack.cs
- SystemUdpStatistics.cs
- basemetadatamappingvisitor.cs
- ViewStateException.cs
- InputBinding.cs
- PropertyGridCommands.cs
- Transform3DGroup.cs
- rsa.cs
- InvalidOperationException.cs
- SiteMapDesignerDataSourceView.cs
- MissingFieldException.cs
- FileRecordSequenceHelper.cs
- WhitespaceRuleLookup.cs
- PerformanceCountersElement.cs
- EncryptedXml.cs
- TypeDependencyAttribute.cs
- TextFormatterContext.cs
- MemberInfoSerializationHolder.cs
- XmlDataLoader.cs
- BookmarkInfo.cs
- SerializationHelper.cs
- WinInet.cs
- TextMetrics.cs
- StateItem.cs
- FeatureAttribute.cs
- InkSerializer.cs
- AssemblyLoader.cs
- WasAdminWrapper.cs
- EventDescriptor.cs
- DataGridViewRowPrePaintEventArgs.cs
- QilSortKey.cs
- CertificateManager.cs
- KnownBoxes.cs
- WsatServiceCertificate.cs
- SqlOuterApplyReducer.cs
- QilLoop.cs
- CompModSwitches.cs
- Socket.cs
- SignedXml.cs
- SmtpCommands.cs
- MultiTrigger.cs