private static bool GoToStateInternal(Control control, FrameworkElement stateGroupsRoot, VisualStateGroup group, VisualState state, bool useTransitions)
        {
            if (stateGroupsRoot == null)
            {
                throw new ArgumentNullException("stateGroupsRoot");
            }

            if (state == null)
            {
                throw new ArgumentNullException("state");
            }

            if (group == null)
            {
                throw new InvalidOperationException();
            }

            try
            {
                VisualState lastState = group.CurrentState;
                if (lastState == state)
                {
                    return(true);
                }

                // todo: see if this should be possible or if there should be a default State.
                if (lastState != null)
                {
                    lastState.StopStoryBoard(control);
                }

                // Note: when a property is set for the first time through a Storyboard, we need
                // to replace the value with a copy so that the other elements with the same Style
                // are not affected (example: PointerOver on one button must not change the
                // Background of another with the same Style)

                // we apply the new state
                Dictionary <Tuple <string, string>, Timeline> newPropertiesChanged = state.ApplyStoryboard(control, useTransitions);

                // we remove the former state if any
                if (lastState != null)
                {
                    // if the former VisualState changed properties that are not set in the new
                    // VisualState, we remove the value it put on it.
                    var formerPropertiesChanged = lastState.GetPropertiesChangedByStoryboard();
                    if (formerPropertiesChanged != null)
                    {
                        foreach (Tuple <string, string> formerProp in formerPropertiesChanged.Keys)
                        {
                            if (newPropertiesChanged == null || !newPropertiesChanged.ContainsKey(formerProp))
                            {
                                formerPropertiesChanged[formerProp].UnApply(control);
                            }
                        }
                        lastState.Storyboard.IsUnApplied = true;
                    }
                }

                // remember the current state
                group.CurrentState = state;

                // Fire both CurrentStateChanging and CurrentStateChanged events
                group.RaiseCurrentStateChanging(stateGroupsRoot, lastState, state, control);
                group.RaiseCurrentStateChanged(stateGroupsRoot, lastState, state, control);

                return(true);
            }
            catch
            {
                return(false);
            }
        }
Exemple #2
0
        /// <summary>
        /// Transitions the control between two states.
        /// </summary>
        /// <param name="control">The control to transition between states.</param>
        /// <param name="stateName">The state to transition to.</param>
        /// <param name="useTransitions">
        /// True to use a VisualTransition to transition between states; otherwise,
        /// false.
        /// </param>
        /// <returns>
        /// True if the control successfully transitioned to the new state; otherwise,
        /// false.
        /// </returns>
        public static bool GoToState(Control control, string stateName, bool useTransitions)
        {
            try
            {
                VisualState state = control.INTERNAL_GetVisualStateGroups().GetVisualState(stateName);
                if (state != null)
                {
                    VisualState formerState = state.INTERNAL_Group.CurrentState;
                    if (formerState != null) //todo: see if this should be possible or if there should be a default State.
                    {
                        formerState.StopStoryBoard(control);
                    }

                    if (state != formerState)
                    {
                        //Note: when a property is set for the first time through a Storyboard, we need to replace the value with a copy so that the other elements with the same Style are not affected (example: PointerOver on one button must not change the Background of another with the same Style)

                        //we apply the new state:
                        Dictionary <Tuple <string, string>, Timeline> newPropertiesChanged = state.ApplyStoryboard(control, useTransitions);//, _propertiesSetAtLeastOnce);

                        ////we add the properties that have been changed to the list of the properties already set:
                        //foreach (Tuple<string, string> propertyChanged in newPropertiesChanged.Keys)
                        //{
                        //    if (!_propertiesSetAtLeastOnce.Contains(propertyChanged))
                        //    {
                        //        _propertiesSetAtLeastOnce.Add(propertyChanged);
                        //    }
                        //}

                        //we remove the former state if any:
                        if (formerState != null)
                        {
                            //if the former VisualState changed properties that are not set in the new VisualState, we remove the value it put on it.
                            var formerPropertiesChanged = formerState.GetPropertiesChangedByStoryboard();
                            if (formerPropertiesChanged != null)
                            {
                                foreach (Tuple <string, string> formerProp in formerPropertiesChanged.Keys)
                                {
                                    if (newPropertiesChanged == null || !newPropertiesChanged.ContainsKey(formerProp))
                                    {
                                        formerPropertiesChanged[formerProp].UnApply(control);
                                    }
                                }
                                formerState.Storyboard.isUnApplied = true;
                            }
                        }

                        //remember the current state:
                        state.INTERNAL_Group.CurrentState = state;
                    }

                    return(true);
                }
                else
                {
                    return(false);
                }
            }
            catch
            {
                return(false);
            }
        }