protected void RaiseCurrentStateChanging(VisualStateGroup stateGroup, VisualState oldState, VisualState newState, Control control) { if (stateGroup == null) { throw new ArgumentNullException("stateGroup"); } if (newState == null) { throw new ArgumentNullException("newState"); } if (control == null) { throw new ArgumentNullException("control"); } FrameworkElement root = VisualStateManager.GetTemplateRoot(control); if (root == null) { return; // Ignore if a ControlTemplate hasn't been applied } stateGroup.RaiseCurrentStateChanging(root, oldState, newState, control); }
private static bool GoToStateInternal(Control control, FrameworkElement element, VisualStateGroup group, VisualState state, bool useTransitions) { if (element == null) { throw new ArgumentNullException("element"); } if (state == null) { throw new ArgumentNullException("state"); } if (group == null) { throw new InvalidOperationException(); } VisualState lastState = group.CurrentState; if (lastState == state) { return(true); } // Get the transition Storyboard. Even if there are no transitions specified, there might // be properties that we're rolling back to their default values. VisualTransition transition = useTransitions ? VisualStateManager.GetTransition(element, group, lastState, state) : null; // Generate dynamicTransition Storyboard Storyboard dynamicTransition = GenerateDynamicTransitionAnimations(element, group, state, transition); // If the transition is null, then we want to instantly snap. The dynamicTransition will // consist of everything that is being moved back to the default state. // If the transition.Duration and explicit storyboard duration is zero, then we want both the dynamic // and state Storyboards to happen in the same tick, so we start them at the same time. if (transition == null || (transition.GeneratedDuration == DurationZero && (transition.Storyboard == null || transition.Storyboard.Duration == DurationZero))) { // Start new state Storyboard and stop any previously running Storyboards if (transition != null && transition.Storyboard != null) { group.StartNewThenStopOld(element, transition.Storyboard, state.Storyboard); } else { group.StartNewThenStopOld(element, state.Storyboard); } // Fire both CurrentStateChanging and CurrentStateChanged events group.RaiseCurrentStateChanging(element, lastState, state, control); group.RaiseCurrentStateChanged(element, lastState, state, control); } else { // In this case, we have an interstitial storyboard of duration > 0 and/or // explicit storyboard of duration >0 , so we need // to run them first, and then we'll run the state storyboard. // we have to wait for both storyboards to complete before // starting the steady state animations. transition.DynamicStoryboardCompleted = false; // Hook up generated Storyboard's Completed event handler dynamicTransition.Completed += delegate(object sender, EventArgs e) { if (transition.Storyboard == null || transition.ExplicitStoryboardCompleted) { if (ShouldRunStateStoryboard(control, element, state, group)) { group.StartNewThenStopOld(element, state.Storyboard); } group.RaiseCurrentStateChanged(element, lastState, state, control); } transition.DynamicStoryboardCompleted = true; }; if (transition.Storyboard != null && transition.ExplicitStoryboardCompleted == true) { EventHandler transitionCompleted = null; transitionCompleted = new EventHandler(delegate(object sender, EventArgs e) { if (transition.DynamicStoryboardCompleted) { if (ShouldRunStateStoryboard(control, element, state, group)) { group.StartNewThenStopOld(element, state.Storyboard); } group.RaiseCurrentStateChanged(element, lastState, state, control); } transition.Storyboard.Completed -= transitionCompleted; transition.ExplicitStoryboardCompleted = true; }); // hook up explicit storyboard's Completed event handler transition.ExplicitStoryboardCompleted = false; transition.Storyboard.Completed += transitionCompleted; } // Start transition and dynamicTransition Storyboards // Stop any previously running Storyboards group.StartNewThenStopOld(element, transition.Storyboard, dynamicTransition); group.RaiseCurrentStateChanging(element, lastState, state, control); } group.CurrentState = state; return(true); }