Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Core / CSharp / System / Windows / Media / Animation / Timeline.cs / 1305600 / Timeline.cs
//------------------------------------------------------------------------------
// Microsoft Windows Client Platform
// Copyright (c) Microsoft Corporation, 2003
//
// File: Timeline.cs
//-----------------------------------------------------------------------------
#if DEBUG
#define TRACE
#endif // DEBUG
using MS.Internal;
using MS.Utility;
using System;
using System.Collections;
using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Threading;
using System.Windows;
using System.Windows.Markup;
using SR=MS.Internal.PresentationCore.SR;
using SRID=MS.Internal.PresentationCore.SRID;
namespace System.Windows.Media.Animation
{
///
/// Describes run-time timing behavior for timed objects.
///
///
/// A Timeline object defines the run-time behavior of a Clock
/// object. Clock objects are arranged in trees. Correspondingly,
/// Timeline objects are also arranged in trees. When a tree of clocks is
/// created, its structure follows that of the tree of Timeline objects.
///
[RuntimeNameProperty("Name")]
[Localizability(LocalizationCategory.None, Readability=Readability.Unreadable)] // cannnot be read & localized as string
public abstract partial class Timeline : Animatable
{
#region External interface
#region Construction
///
/// Creates a Timeline with default properties.
///
protected Timeline()
{
#if DEBUG
lock (_debugLockObject)
{
_debugIdentity = ++_nextIdentity;
WeakReference weakRef = new WeakReference(this);
_objectTable[_debugIdentity] = weakRef;
}
#endif // DEBUG
}
///
/// Creates a Timeline with the specified BeginTime.
///
///
/// The scheduled BeginTime for this timeline.
///
protected Timeline(Nullable beginTime)
: this()
{
BeginTime = beginTime;
}
///
/// Creates a Timeline with the specified begin time and duration.
///
///
/// The scheduled BeginTime for this timeline.
///
///
/// The simple Duration of this timeline.
///
protected Timeline(Nullable beginTime, Duration duration)
: this()
{
BeginTime = beginTime;
Duration = duration;
}
///
/// Creates a Timeline with the specified BeginTime, Duration and RepeatBehavior.
///
///
/// The scheduled BeginTime for this Timeline.
///
///
/// The simple Duration of this Timeline.
///
///
/// The RepeatBehavior for this Timeline.
///
protected Timeline(Nullable beginTime, Duration duration, RepeatBehavior repeatBehavior)
: this()
{
BeginTime = beginTime;
Duration = duration;
RepeatBehavior = repeatBehavior;
}
#endregion // Construction
#region Freezable
///
/// Override of FreezeCore. We need to validate the timeline
/// before Freezing it.
///
///
protected override bool FreezeCore(bool isChecking)
{
ValidateTimeline();
return base.FreezeCore(isChecking);
}
//
// Overrides for GetAsFrozenCore and GetCurrentValueAsFrozenCore
// Timeline does not need to overide CloneCore and CloneCurrentValueCore
// See the comment in CopyCommon
//
///
/// Creates a frozen base value clone of another Timeline.
///
///
/// The timeline to copy properties from. If this parameter is null,
/// this timeline is constructed with default property values.
///
///
/// This method should be used by implementations of Freezable.CloneCommonCore.
///
protected override void GetAsFrozenCore(Freezable sourceFreezable)
{
Timeline sourceTimeline = (Timeline)sourceFreezable;
base.GetAsFrozenCore(sourceFreezable);
CopyCommon(sourceTimeline);
}
///
/// Creates a frozen current value clone of another Timeline.
///
///
/// The timeline to copy properties from. If this parameter is null,
/// this timeline is constructed with default property values.
///
///
/// This method should be used by implementations of CopyCommonCore.
///
protected override void GetCurrentValueAsFrozenCore(Freezable sourceFreezable)
{
Timeline sourceTimeline = (Timeline)sourceFreezable;
base.GetCurrentValueAsFrozenCore(sourceFreezable);
CopyCommon(sourceTimeline);
}
#endregion
#region Properties
private static void Timeline_PropertyChangedFunction(DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
((Timeline)d).PropertyChanged(e.Property);
}
#region AccelerationRatio Property
///
/// AccelerationRatio Property
///
public static readonly DependencyProperty AccelerationRatioProperty =
DependencyProperty.Register(
"AccelerationRatio",
typeof(double),
typeof(Timeline),
new PropertyMetadata(
(double)0.0,
new PropertyChangedCallback(Timeline_PropertyChangedFunction)),
new ValidateValueCallback(ValidateAccelerationDecelerationRatio));
///
/// Gets or sets a value indicating the percentage of the duration of
/// an active period spent accelerating the passage of time from zero
/// to its maximum rate.
///
///
/// The percentage of the duration of an active period spent
/// accelerating the passage of time from zero to its maximum rate.
///
///
/// This property must be set to a value between 0 and 1, inclusive,
/// or it raises an InvalidArgumentException exception. This property
/// has a default value of zero.
///
public double AccelerationRatio
{
get
{
return (double)GetValue(AccelerationRatioProperty);
}
set
{
SetValue(AccelerationRatioProperty, value);
}
}
private static bool ValidateAccelerationDecelerationRatio(object value)
{
double newValue = (double)value;
if (newValue < 0 || newValue > 1 || double.IsNaN(newValue))
{
throw new ArgumentException(SR.Get(SRID.Timing_InvalidArgAccelAndDecel), "value");
}
return true;
}
#endregion // AccelerationRatio Property
#region AutoReverse Property
///
/// AutoReverseProperty
///
public static readonly DependencyProperty AutoReverseProperty =
DependencyProperty.Register(
"AutoReverse",
typeof(bool),
typeof(Timeline),
new PropertyMetadata(
false,
new PropertyChangedCallback(Timeline_PropertyChangedFunction)));
///
/// Gets or sets a value indicating whether a normal
/// forward-progressing activation period should be succeeded by a
/// backward-progressing activation period.
///
///
/// true if a normal forward-progressing activation period should be
/// succeeded by a backward-progressing activation period; otherwise,
/// false.
///
///
/// This property has a default value of false.
///
[DefaultValue(false)]
public bool AutoReverse
{
get
{
return (bool)GetValue(AutoReverseProperty);
}
set
{
SetValue(AutoReverseProperty, value);
}
}
#endregion
#region BeginTime Property
///
/// BeginTimeProperty
///
public static readonly DependencyProperty BeginTimeProperty =
DependencyProperty.Register(
"BeginTime",
typeof(TimeSpan?),
typeof(Timeline),
new PropertyMetadata(
(TimeSpan?)TimeSpan.Zero,
new PropertyChangedCallback(Timeline_PropertyChangedFunction)));
///
/// Gets or sets the scheduled time at which this Timeline should
/// begin, relative to its parents begin time, in local coordinates.
///
///
/// The scheduled time at which this Timeline should begin, relative
/// to its parents begin time, in local coordinates.
///
///
/// This property has a default value of zero.
///
public TimeSpan? BeginTime
{
get
{
return (TimeSpan?)GetValue(BeginTimeProperty);
}
set
{
SetValue(BeginTimeProperty, value);
}
}
#endregion // BeginTime Property
#region DecelerationRatio Property
///
/// DecelerationRatioProperty
///
public static readonly DependencyProperty DecelerationRatioProperty =
DependencyProperty.Register(
"DecelerationRatio",
typeof(double),
typeof(Timeline),
new PropertyMetadata(
(double)0.0,
new PropertyChangedCallback(Timeline_PropertyChangedFunction)),
new ValidateValueCallback(ValidateAccelerationDecelerationRatio));
///
/// Gets or sets a value indicating the percentage of the duration
/// of an active period spent decelerating the passage of time its
/// maximum rate to from zero.
///
///
/// The percentage of the duration of an active period spent
/// decelerating the passage of time its maximum rate to from zero.
///
///
/// This property must be set to a value between 0 and 1, inclusive,
/// or it raises an InvalidArgumentException exception. This
/// property has a default value of zero.
///
public double DecelerationRatio
{
get
{
return (double)GetValue(DecelerationRatioProperty);
}
set
{
SetValue(DecelerationRatioProperty, value);
}
}
#endregion // DecelerationRatio Property
#region DesiredFrameRate Property
///
/// DesiredFrameRateProperty
///
public static readonly DependencyProperty DesiredFrameRateProperty =
DependencyProperty.RegisterAttached(
"DesiredFrameRate",
typeof(Int32?),
typeof(Timeline),
new PropertyMetadata(
(Int32?)null,
new PropertyChangedCallback(Timeline_PropertyChangedFunction)),
new ValidateValueCallback(ValidateDesiredFrameRate));
private static bool ValidateDesiredFrameRate(object value)
{
Int32? desiredFrameRate = (Int32?)value;
return (!desiredFrameRate.HasValue || desiredFrameRate.Value > 0);
}
///
/// Reads the attached property DesiredFrameRate from the given Timeline.
///
/// Timeline from which to read the attached property.
/// The property's value.
///
public static Int32? GetDesiredFrameRate(Timeline timeline)
{
if (timeline == null) { throw new ArgumentNullException("timeline"); }
return (Int32?)timeline.GetValue(DesiredFrameRateProperty);
}
///
/// Writes the attached property DesiredFrameRate to the given Timeline.
///
/// Timeline to which to write the attached property.
/// The property value to set
///
public static void SetDesiredFrameRate(Timeline timeline, Int32? desiredFrameRate)
{
if (timeline == null) { throw new ArgumentNullException("timeline"); }
timeline.SetValue(DesiredFrameRateProperty, desiredFrameRate);
}
#endregion // DesiredFrameRate Property
#region Duration Property
///
/// DurationProperty
///
public static readonly DependencyProperty DurationProperty =
DependencyProperty.Register(
"Duration",
typeof(Duration),
typeof(Timeline),
new PropertyMetadata(
Duration.Automatic,
new PropertyChangedCallback(Timeline_PropertyChangedFunction)));
///
/// Gets or sets a value indicating the natural length of an
/// activation period, in local coordinates.
///
///
/// The natural length of an activation period, in local coordinates.
///
///
/// This length represents a single forward or backward section of a
/// single repeat iteration. This property has a default value of
/// Duration.Automatic.
///
public Duration Duration
{
get
{
return (Duration)GetValue(DurationProperty);
}
set
{
SetValue(DurationProperty, value);
}
}
#endregion // Duration Property
#region FillBehavior Property
///
/// FillBehavior Property
///
public static readonly DependencyProperty FillBehaviorProperty =
DependencyProperty.Register(
"FillBehavior",
typeof(FillBehavior),
typeof(Timeline),
new PropertyMetadata(
FillBehavior.HoldEnd,
new PropertyChangedCallback(Timeline_PropertyChangedFunction)),
new ValidateValueCallback(ValidateFillBehavior));
private static bool ValidateFillBehavior(object value)
{
return TimeEnumHelper.IsValidFillBehavior((FillBehavior)value);
}
///
/// This property indicates how a Timeline will behave when it is outside
/// of its active period but its parent is in its active or hold period.
///
///
public FillBehavior FillBehavior
{
get
{
return (FillBehavior)GetValue(FillBehaviorProperty);
}
set
{
SetValue(FillBehaviorProperty, value);
}
}
#endregion // FillBehavior Property
#region Name Property
///
/// Name Property
///
public static readonly DependencyProperty NameProperty =
DependencyProperty.Register(
"Name",
typeof(string),
typeof(Timeline),
new PropertyMetadata(
(string)null,
new PropertyChangedCallback(Timeline_PropertyChangedFunction)),
new ValidateValueCallback(System.Windows.Markup.NameValidationHelper.NameValidationCallback));
///
/// Gets or sets the Name of this Timeline.
///
///
/// The Name of this Timeline.
///
///
/// This property can be used to set up [....]-arcs between sibling
/// Timeline objects. A [....]-arc is established when the
/// property of one Timeline
/// corresponds to the Name of another Timeline.
///
[DefaultValue((string)null)]
[MergableProperty(false)]
public string Name
{
get
{
return (string)GetValue(NameProperty);
}
set
{
SetValue(NameProperty, value);
}
}
#endregion // Name Property
#region RepeatBehavior Property
///
/// RepeatBehaviorProperty
///
public static readonly DependencyProperty RepeatBehaviorProperty =
DependencyProperty.Register(
"RepeatBehavior",
typeof(RepeatBehavior),
typeof(Timeline),
new PropertyMetadata(
new RepeatBehavior(1.0),
new PropertyChangedCallback(Timeline_PropertyChangedFunction)));
///
/// Gets or sets the a RepeatBehavior structure which specifies the way this Timeline will
/// repeat its simple duration.
///
/// A RepeatBehavior structure which specifies the way this Timeline will repeat its
/// simple duration.
public RepeatBehavior RepeatBehavior
{
get
{
return (RepeatBehavior)GetValue(RepeatBehaviorProperty);
}
set
{
SetValue(RepeatBehaviorProperty, value);
}
}
#endregion // RepeatBehavior Property
#region SpeedRatio Property
///
/// SpeedRatioProperty
///
public static readonly DependencyProperty SpeedRatioProperty =
DependencyProperty.Register(
"SpeedRatio",
typeof(double),
typeof(Timeline),
new PropertyMetadata(
(double)1.0,
new PropertyChangedCallback(Timeline_PropertyChangedFunction)),
new ValidateValueCallback(ValidateSpeedRatio));
///
/// Gets or sets the ratio at which time progresses on this Timeline,
/// relative to its parent.
///
///
/// The ratio at which time progresses on this Timeline, relative to
/// its parent.
///
///
/// If Acceleration or Deceleration are specified, this ratio is the
/// average ratio over the natural length of the Timeline. This
/// property has a default value of 1.0.
///
[DefaultValue((double)1.0)]
public double SpeedRatio
{
get
{
return (double)GetValue(SpeedRatioProperty);
}
set
{
SetValue(SpeedRatioProperty, value);
}
}
private static bool ValidateSpeedRatio(object value)
{
double newValue = (double)value;
if (newValue <= 0 || newValue > double.MaxValue || double.IsNaN(newValue))
{
throw new ArgumentException(SR.Get(SRID.Timing_InvalidArgFinitePositive), "value");
}
return true;
}
#endregion // SpeedRatio Property
#endregion // Properties
#region Methods
///
/// Called by the method to
/// create a type-specific clock for this Timeline.
///
///
/// A clock for this Timeline.
///
///
/// If a derived class overrides this method, it should only create
/// and return an object of a class inheriting from Clock.
///
protected internal virtual Clock AllocateClock()
{
return new Clock(this);
}
///
/// Creates a new Clock using this Timeline as the root. If this
/// Timeline has children, a tree of clocks will be created.
///
///
/// Although this Timeline may be included as a child of one or more
/// TimelineGroups, this information will be ignored. For the purposes
/// of this method this Timeline will be treated as a root Timeline.
///
///
/// A new Clock or tree of Clocks depending on whether
/// or not this Timeline is a TimelineGroup that contains children.
///
public Clock CreateClock()
{
return CreateClock(true);
}
///
/// Creates a new Clock using this Timeline as the root. If this
/// Timeline has children, a tree of clocks will be created.
///
/// True if the root Clock returned should
/// return a ClockController from its Controller property so that
/// the Clock tree can be interactively controlled.
///
/// Although this Timeline may be included as a child of one or more
/// TimelineGroups, this information will be ignored. For the purposes
/// of this method this Timeline will be treated as a root Timeline.
///
///
/// A new Clock or tree of Clocks depending on whether
/// or not this Timeline is a TimelineGroup that contains children.
///
public Clock CreateClock(bool hasControllableRoot)
{
// Create the tree of clocks from this timeline
return Clock.BuildClockTreeFromTimeline(this, hasControllableRoot);
}
///
/// Returns the period of a single iteration. This will only be called when
/// the Duration property is set to Automatic. If Duration is Automatic,
/// the natural duration is determined by the nature of the specific timeline class,
/// as determined by its author. If GetNaturalDuration returns Automatic, it means
/// that the natural duration is unknown, which temporarily implies Forever.
/// Streaming media would fit this case.
///
///
/// The Clock whose natural duration is desired.
///
///
/// A Duration quantity representing the natural duration.
///
internal protected Duration GetNaturalDuration(Clock clock)
{
return GetNaturalDurationCore(clock);
}
///
/// Implemented by the class author to provide a custom natural Duration
/// in the case that the Duration property is set to Automatic. If the author
/// cannot determine the Duration, this method should return Automatic.
///
///
/// The Clock whose natural duration is desired.
///
///
/// A Duration quantity representing the natural duration.
///
protected virtual Duration GetNaturalDurationCore(Clock clock)
{
return Duration.Automatic;
}
///
/// This method will throw an exception if a timeline has been incorrectly
/// constructed. Currently we validate all possible values when they are
/// set, but it is not possible to do this for Acceleration/DecelerationRatio.
///
/// The reason is when a timeline is instantiated in xaml the properties are
/// set with direct calls to DependencyObject.SetValue. This means our only
/// chance to validate the value is in the ValidateValue callback, which does
/// not allow querying of other DPs. Acceleration/DecelerationRatio are invalid
/// if their sum is > 1. This can't be verified in the ValidateValue callback,
/// so is done here.
///
private void ValidateTimeline()
{
if (AccelerationRatio + DecelerationRatio > 1)
{
throw new InvalidOperationException(SR.Get(SRID.Timing_AccelAndDecelGreaterThanOne));
}
}
#endregion // Methods
#region Events
///
/// Raised whenever the value of the CurrentStateInvalidated property changes.
///
public event EventHandler CurrentStateInvalidated
{
add
{
AddEventHandler(CurrentStateInvalidatedKey, value);
}
remove
{
RemoveEventHandler(CurrentStateInvalidatedKey, value);
}
}
///
/// Raised whenever the value of the CurrentTimeInvalidated property changes.
///
public event EventHandler CurrentTimeInvalidated
{
add
{
AddEventHandler(CurrentTimeInvalidatedKey, value);
}
remove
{
RemoveEventHandler(CurrentTimeInvalidatedKey, value);
}
}
///
/// Raised whenever the value of the CurrentGlobalSpeed property changes.
///
public event EventHandler CurrentGlobalSpeedInvalidated
{
add
{
AddEventHandler(CurrentGlobalSpeedInvalidatedKey, value);
}
remove
{
RemoveEventHandler(CurrentGlobalSpeedInvalidatedKey, value);
}
}
///
/// Raised whenever the value of the Completed property changes.
///
public event EventHandler Completed
{
add
{
AddEventHandler(CompletedKey, value);
}
remove
{
RemoveEventHandler(CompletedKey, value);
}
}
///
/// Raised whenever the value of the RemoveRequested property changes.
///
public event EventHandler RemoveRequested
{
add
{
AddEventHandler(RemoveRequestedKey, value);
}
remove
{
RemoveEventHandler(RemoveRequestedKey, value);
}
}
#endregion // Events
#endregion // External interface
#region Internal implementation
#region Properties
///
/// Read-only access to the EventHandlerStore. Used by
/// Clock to copy the Timeline's events
///
internal EventHandlersStore InternalEventHandlersStore
{
get
{
return EventHandlersStoreField.GetValue(this);
}
}
#endregion // Properties
#region Methods
///
/// Exposes the OnFreezablePropertyChanged protected method for use
/// by the TimelineCollection class.
///
///
/// The previous value of the timeline.
///
///
/// The new value of the timeline.
///
internal void InternalOnFreezablePropertyChanged(Timeline originalTimeline, Timeline newTimeline)
{
OnFreezablePropertyChanged(originalTimeline, newTimeline);
}
///
/// Called by the TimelineCollection class to propagate the
/// Freezable.FreezeCore call to this object.
///
internal bool InternalFreeze(bool isChecking)
{
return Freeze(this, isChecking);
}
///
/// Asks this timeline to perform read verification.
///
internal void InternalReadPreamble()
{
ReadPreamble();
}
///
/// Notifies this timeline that a change has been made.
///
internal void InternalWritePostscript()
{
WritePostscript();
}
///
/// Adds a delegate to the list of event handlers on this object.
///
///
/// A unique identifier for the event handler.
///
/// The delegate to add.
private void AddEventHandler(EventPrivateKey key, Delegate handler)
{
WritePreamble();
EventHandlersStore store = EventHandlersStoreField.GetValue(this);
if (store == null)
{
store = new EventHandlersStore();
EventHandlersStoreField.SetValue(this, store);
}
store.Add(key, handler);
WritePostscript();
}
///
/// Implements copy functionalty for GetAsFrozenCore and GetCurrentValueAsFrozenCore
/// Timeline does not need to override CloneCore and CloneCurrentValueCore.
///
///
private void CopyCommon(Timeline sourceTimeline)
{
// When creating a frozen copy of a Timeline we want to copy the
// event handlers. This is for two reasons
//
// 1.) Internally when creating a clock tree we use
// a frozen copy of the timing tree. If that frozen
// copy does not preserve the event handlers then
// any callbacks registered on the Timelines will be lost.
//
// 2.) GetAsFrozen and GetCurrentValueAsFrozen don't always clone.
// If any object in the tree is frozen it'll simply return it.
// If we did not copy the event handlers GetAsFrozen
// would return different results depending on whether a
// Timeline was frozen before the call.
//
//
// The other two clone methods make unfrozen clones, so it's consisent
// to not copy the event handlers for those methods. Cloning an object
// is basically the only way to get a 'fresh' copy without event handlers
// attached. If someone wants a frozen clone they probably want an exact
// copy of the original.
EventHandlersStore sourceStore = EventHandlersStoreField.GetValue(sourceTimeline);
if (sourceStore != null)
{
Debug.Assert(sourceStore.Count > 0);
EventHandlersStoreField.SetValue(this, new EventHandlersStore(sourceStore));
}
}
///
/// Removes a delegate from the list of event handlers on this object.
///
///
/// A unique identifier for the event handler.
///
/// The delegate to remove.
private void RemoveEventHandler(EventPrivateKey key, Delegate handler)
{
WritePreamble();
EventHandlersStore store = EventHandlersStoreField.GetValue(this);
if (store != null)
{
store.Remove(key, handler);
if (store.Count == 0)
{
// last event handler was removed -- throw away underlying EventHandlersStore
EventHandlersStoreField.ClearValue(this);
}
WritePostscript();
}
}
#endregion // Methods
#region Debugging instrumentation
#if DEBUG
///
/// Dumps the description of the subtree rooted at this timeline.
///
internal void Dump()
{
System.Text.StringBuilder builder = new System.Text.StringBuilder();
builder.Capacity = 1024;
builder.Append("========================================\n");
builder.Append("Timelines rooted at Timeline ");
builder.Append(_debugIdentity);
builder.Append('\n');
builder.Append("----------------------------------------\n");
BuildInfoRecursive(builder, 0);
builder.Append("----------------------------------------\n");
Trace.Write(builder.ToString());
}
///
/// Dumps the description of all timelines in the known timeline table.
///
internal static void DumpAll()
{
System.Text.StringBuilder builder = new System.Text.StringBuilder();
int timelineCount = 0;
builder.Capacity = 1024;
builder.Append("========================================\n");
builder.Append("Timelines in the GC heap\n");
builder.Append("----------------------------------------\n");
lock (_debugLockObject)
{
if (_objectTable.Count > 0)
{
// Output the timelines sorted by Name
int[] idTable = new int[_objectTable.Count];
_objectTable.Keys.CopyTo(idTable, 0);
Array.Sort(idTable);
for (int index = 0; index < idTable.Length; index++)
{
WeakReference weakRef = (WeakReference)_objectTable[idTable[index]];
Timeline timeline = (Timeline)weakRef.Target;
if (timeline != null)
{
timeline.BuildInfo(builder, 0, true);
timelineCount++;
}
}
}
}
if (timelineCount == 0)
{
builder.Append("There are no Timelines in the GC heap.\n");
}
builder.Append("----------------------------------------\n");
Trace.Write(builder.ToString());
}
///
/// Dumps the description of the subtree rooted at this timeline.
///
///
/// A StringBuilder that accumulates the description text.
///
///
/// The depth of recursion for this timeline.
///
internal void BuildInfoRecursive(System.Text.StringBuilder builder, int depth)
{
// Add the info for this timeline
BuildInfo(builder, depth, true);
// Recurse into the children
depth++;
TimelineGroup timelineGroup = this as TimelineGroup;
if (timelineGroup != null)
{
TimelineCollection children = timelineGroup.Children;
if (children != null)
{
for (int childIndex = 0; childIndex < children.Count; childIndex++)
{
children.Internal_GetItem(childIndex).BuildInfoRecursive(builder, depth);
}
}
}
}
///
/// Dumps the description of this timeline.
///
///
/// A StringBuilder that accumulates the description text.
///
///
/// The depth of recursion for this timeline.
///
///
/// Whether or not to include the debug ID in the description.
///
internal void BuildInfo(System.Text.StringBuilder builder, int depth, bool includeDebugID)
{
// Start with the name of the timeline
if (includeDebugID)
{
builder.Append(' ', depth);
builder.Append("Timeline ");
builder.Append(_debugIdentity);
}
builder.Append(" (");
builder.Append(GetType().Name);
// Build attributes
if (Name != null)
{
builder.Append(", Name=\"");
builder.Append(Name);
builder.Append("\"");
}
if (AccelerationRatio != 0.0f)
{
builder.Append(", AccelerationRatio = ");
builder.Append(AccelerationRatio.ToString());
}
if (AutoReverse != false)
{
builder.Append(", AutoReverse = ");
builder.Append(AutoReverse.ToString());
}
if (DecelerationRatio != 0.0f)
{
builder.Append(", DecelerationRatio = ");
builder.Append(DecelerationRatio.ToString());
}
if (Duration != Duration.Automatic)
{
builder.Append(", Duration = ");
builder.Append(Duration.ToString());
}
if (FillBehavior != FillBehavior.HoldEnd)
{
builder.Append(", FillBehavior = ");
builder.Append(FillBehavior.ToString());
}
if (SpeedRatio != 1.0f)
{
builder.Append(", Speed = ");
builder.Append(SpeedRatio);
}
builder.Append(")\n");
}
///
/// Finds a previously registered object.
///
///
/// The Name of the object to look for
///
///
/// The object if found, null otherwise.
///
internal static Timeline Find(int id)
{
Timeline timeline = null;
lock (_debugLockObject)
{
object handleReference = _objectTable[id];
if (handleReference != null)
{
WeakReference weakRef = (WeakReference)handleReference;
timeline = (Timeline)weakRef.Target;
if (timeline == null)
{
// Object has been destroyed, so remove the weakRef.
_objectTable.Remove(id);
}
}
}
return timeline;
}
///
/// Cleans up the known timelines table by removing dead weak
/// references.
///
internal static void CleanKnownTimelinesTable()
{
lock (_debugLockObject)
{
Hashtable removeTable = new Hashtable();
// Identify dead references
foreach (DictionaryEntry e in _objectTable)
{
WeakReference weakRef = (WeakReference) e.Value;
if (weakRef.Target == null)
{
removeTable[e.Key] = weakRef;
}
}
// Remove dead references
foreach (DictionaryEntry e in removeTable)
{
_objectTable.Remove(e.Key);
}
}
}
#endif // DEBUG
#endregion // Debugging instrumentation
#region Data
#region Event Handler Storage
internal static readonly UncommonField EventHandlersStoreField = new UncommonField();
// Unique identifiers for each of the events defined on Timeline.
// This is used as a key in the EventHandlerStore
internal static readonly EventPrivateKey CurrentGlobalSpeedInvalidatedKey = new EventPrivateKey();
internal static readonly EventPrivateKey CurrentStateInvalidatedKey = new EventPrivateKey();
internal static readonly EventPrivateKey CurrentTimeInvalidatedKey = new EventPrivateKey();
internal static readonly EventPrivateKey CompletedKey = new EventPrivateKey();
internal static readonly EventPrivateKey RemoveRequestedKey = new EventPrivateKey();
#endregion // Event Handler Storage
#region Debug data
#if DEBUG
internal int _debugIdentity;
internal static int _nextIdentity;
internal static Hashtable _objectTable = new Hashtable();
internal static object _debugLockObject = new object();
#endif // DEBUG
#endregion // Debug data
#endregion // Data
#endregion // Internal implementation
}
}
// 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
- X500Name.cs
- HistoryEventArgs.cs
- XmlUTF8TextWriter.cs
- Int32AnimationBase.cs
- SpellCheck.cs
- PathFigure.cs
- MsdtcClusterUtils.cs
- UnknownWrapper.cs
- ReferencedCollectionType.cs
- FormatVersion.cs
- Utilities.cs
- SmtpFailedRecipientsException.cs
- DES.cs
- GB18030Encoding.cs
- BaseTreeIterator.cs
- COM2Properties.cs
- OracleSqlParser.cs
- WindowsFormsSynchronizationContext.cs
- Parameter.cs
- Authorization.cs
- ServiceInfo.cs
- WebPartExportVerb.cs
- AutomationAttributeInfo.cs
- Ray3DHitTestResult.cs
- WorkflowOwnershipException.cs
- TreeViewDesigner.cs
- Constraint.cs
- DomNameTable.cs
- DataGridViewColumnHeaderCell.cs
- ReferencedAssemblyResolver.cs
- CodeAccessPermission.cs
- PageBorderless.cs
- LocalFileSettingsProvider.cs
- UnionExpr.cs
- CngProvider.cs
- ParallelTimeline.cs
- StatusBarDrawItemEvent.cs
- SupportingTokenListenerFactory.cs
- Crc32Helper.cs
- SQLInt16Storage.cs
- SetStateEventArgs.cs
- WCFBuildProvider.cs
- CodeGroup.cs
- ProcessModelInfo.cs
- ServerValidateEventArgs.cs
- ConnectionStringsExpressionBuilder.cs
- SqlDataSourceCache.cs
- ReachIDocumentPaginatorSerializer.cs
- ContextQuery.cs
- BooleanAnimationBase.cs
- X509SecurityTokenAuthenticator.cs
- TreeWalker.cs
- Blend.cs
- GridViewHeaderRowPresenter.cs
- MimeWriter.cs
- FixedSOMContainer.cs
- XmlQueryRuntime.cs
- AutomationPropertyInfo.cs
- InvalidOperationException.cs
- DataColumnMappingCollection.cs
- AttributeProviderAttribute.cs
- DataTemplate.cs
- ServiceDescriptionSerializer.cs
- ReferentialConstraintRoleElement.cs
- DbProviderSpecificTypePropertyAttribute.cs
- DateTimeConstantAttribute.cs
- TreeNodeStyleCollection.cs
- BinaryQueryOperator.cs
- XamlParser.cs
- StructuralCache.cs
- Transform.cs
- PauseStoryboard.cs
- PaginationProgressEventArgs.cs
- CodeDelegateInvokeExpression.cs
- FormsAuthentication.cs
- ScrollProperties.cs
- EncodingDataItem.cs
- SAPICategories.cs
- GeometryDrawing.cs
- Base64Stream.cs
- BigIntegerStorage.cs
- OracleConnectionFactory.cs
- FastPropertyAccessor.cs
- TextProperties.cs
- SerializationSectionGroup.cs
- TextRange.cs
- BindingManagerDataErrorEventArgs.cs
- SqlDependencyListener.cs
- BufferedStream.cs
- sqlcontext.cs
- XmlEventCache.cs
- RuntimeConfig.cs
- NameValueFileSectionHandler.cs
- TypeDescriptionProvider.cs
- PolicyValidationException.cs
- XmlAnyAttributeAttribute.cs
- PropertyChangedEventArgs.cs
- HelpProvider.cs
- serverconfig.cs
- OptimizerPatterns.cs