/// <summary> /// Processes a double animation with keyframes, looking for known /// special values to store with an adapter. /// </summary> /// <param name="da">The double animation using key frames instance.</param> private void ProcessDoubleAnimationWithKeys(DoubleAnimationUsingKeyFrames da) { // Look through all keyframes in the instance. foreach (DoubleKeyFrame frame in da.KeyFrames) { var d = DoubleAnimationFrameAdapter.GetDimensionFromIdentifyingValue(frame.Value); if (d.HasValue) { _specialAnimations.Add(new DoubleAnimationFrameAdapter(d.Value, frame)); } } }
/// <summary> /// Processes a double animation with keyframes, looking for known /// special values to store with an adapter. /// </summary> /// <param name="da">The double animation using key frames instance.</param> private void ProcessDoubleAnimationWithKeys(DoubleAnimationUsingKeyFrames da, Storyboard sb) { // Look through all keyframes in the instance. foreach (DoubleKeyFrame frame in da.KeyFrames) { var d = DoubleAnimationFrameAdapter.GetDimensionFromMagicNumber(frame.Value); if (d.HasValue) { _specialAnimations.Add(new DoubleAnimationFrameAdapter(d.Value, frame, this, sb)); } } }
/// <summary> /// Walks through the known storyboards in the control's template that /// may contain identifying values, storing them for future /// use and updates. /// </summary> void UpdateAnyAnimationValues() { if (_knownHeight > 0 && _knownWidth > 0) { // Initially, before any special animations have been found, // the visual state groups of the control must be explored. // By definition they must be at the implementation root of the // control. if (_specialAnimations == null) { _specialAnimations = new List <AnimationValueAdapter>(); foreach (VisualStateGroup group in VisualStateManager.GetVisualStateGroups(this)) { if (group == null) { continue; } foreach (VisualState state in group.States) { if (state != null) { Storyboard sb = state.Storyboard; if (sb != null) { // Examine all children of the storyboards, // looking for either type of double // animation. foreach (Timeline timeline in sb.Children) { DoubleAnimation da = timeline as DoubleAnimation; DoubleAnimationUsingKeyFrames dakeys = timeline as DoubleAnimationUsingKeyFrames; if (da != null) { // Look for a special value in the To property. if (da.To.HasValue) { var d = DoubleAnimationToAdapter.GetDimensionFromIdentifyingValue(da.To.Value); if (d.HasValue) { _specialAnimations.Add(new DoubleAnimationToAdapter(d.Value, da)); } } // Look for a special value in the From property. if (da.From.HasValue) { var d = DoubleAnimationFromAdapter.GetDimensionFromIdentifyingValue(da.To.Value); if (d.HasValue) { _specialAnimations.Add(new DoubleAnimationFromAdapter(d.Value, da)); } } } else if (dakeys != null) { // Look through all keyframes in the instance. foreach (DoubleKeyFrame frame in dakeys.KeyFrames) { var d = DoubleAnimationFrameAdapter.GetDimensionFromIdentifyingValue(frame.Value); if (d.HasValue) { _specialAnimations.Add(new DoubleAnimationFrameAdapter(d.Value, frame)); } } } } } } } } } // Update special animation values relative to the current size. foreach (AnimationValueAdapter adapter in _specialAnimations) { adapter.UpdateWithNewDimension(_knownWidth, _knownHeight); } // HACK: force storyboard to use new values foreach (VisualStateGroup group in VisualStateManager.GetVisualStateGroups(this)) { if (group == null) { continue; } foreach (VisualState state in group.States) { if (state != null) { Storyboard sb = state.Storyboard; if (sb != null) { // need to kick the storyboard, otherwise new values are not taken into account. // it's sad, really don't want to start storyboards in vsm, but I see no other option sb.Begin(this); } } } } } }