private bool ShouldTransitionToState(FrameworkElement control, VisualStateGroup group, VisualState state) { // No need to transition, if we are already at the target state. if ((group.GetCurrentState() ?? group.CurrentState) == state) { VisualStateSource.Verbose( "Not changing to visual state {0}, because the control \"{1}\" is already at that state.", state.Name, control ); return(false); } // The ExtendedVisualState can have a set of Conditions, which need to apply. if (state is ExtendedVisualState extendedState && !extendedState.AreConditionsApplyingToControl(control)) { VisualStateSource.Verbose( "Not changing to visual state {0}, because one of " + "the state's conditions doesn't apply.", state.Name ); return(false); } return(true); }
private static bool TransitionToState( FrameworkElement control, FrameworkElement stateGroupsRoot, string stateName, VisualStateGroup group, VisualState state, bool useTransitions) { VisualStateSource.Info( "Changing visual state from \"{0}\" to \"{1}\" on control {2} with root element {3}.", group.GetCurrentState()?.Name ?? group.CurrentState?.Name, stateName, control, stateGroupsRoot); // We offload the actual transitioning logic into multiple different StateSwitchers, // so that this class doesn't become cluttered. // Simply call them in order and check if one of them managed to transition to a new state. bool couldTransitionToState = false; couldTransitionToState |= new SetterVisualStateSwitcher().GoToState( control, stateGroupsRoot, stateName, group, state, useTransitions); couldTransitionToState |= new AnimationVisualStateSwitcher().GoToState( control, stateGroupsRoot, stateName, group, state, useTransitions); group.SetCurrentState(state); return(couldTransitionToState); }
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; VisualState lastState = group.GetCurrentState(); 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 ? ExtendedVisualStateManager.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.SetDynamicStoryboardCompleted(false); //transition.DynamicStoryboardCompleted = false; // Hook up generated Storyboard's Completed event handler dynamicTransition.Completed += delegate(object sender, Object e) { // transition.ExplicitStoryboardCompleted) && if ((transition.Storyboard == null || transition.GetExplicitStoryboardCompleted()) && // If the element or control is removed from the tree, then the new // storyboards will not be able to resolve target names. Thus, // if the element or control is unloaded, don't start the new // storyboards. //(element.IsLoaded && (control == null || control.IsLoaded))) (element.Parent != null && (control == null || control.Parent != null))) { group.StartNewThenStopOld(element, state.Storyboard); } //group.RaiseCurrentStateChanged(element, lastState, state, control); transition.SetDynamicStoryboardCompleted(true); //transition.DynamicStoryboardCompleted = true; }; // if (transition.Storyboard != null && transition.ExplicitStoryboardCompleted == true) if (transition.Storyboard != null && transition.GetExplicitStoryboardCompleted() == true) { EventHandler <Object> transitionCompleted = null; transitionCompleted = new EventHandler <Object>(delegate(object sender, Object e) { if (transition.GetDynamicStoryboardCompleted() && // If the element or control is removed from the tree, then the new // storyboards will not be able to resolve target names. Thus, // if the element or control is unloaded, don't start the new // storyboards. //(element.IsLoaded && (control == null || control.IsLoaded))) (element.Parent != null && (control == null || control.Parent != null))) { group.StartNewThenStopOld(element, state.Storyboard); } //group.RaiseCurrentStateChanged(element, lastState, state, control); transition.Storyboard.Completed -= transitionCompleted; transition.SetExplicitStoryboardCompleted(true); }); // hook up explicit storyboard's Completed event handler transition.SetExplicitStoryboardCompleted(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; group.SetCurrentState(state); return(true); }