コード例 #1
0
 private void UpdateCommonStatesWithoutNeedsLayout(ManipulationUpdateKind manipulationUpdate = ManipulationUpdateKind.None)
 {
     using (InterceptSetNeedsLayout())
     {
         UpdateCommonStates(manipulationUpdate);
     }
 }
コード例 #2
0
        private void UpdateCommonStates(ManipulationUpdateKind manipulationUpdate = ManipulationUpdateKind.None)
        {
            var state = GetState(IsSelected, IsPointerOver, HasPointerCapture);

            // On Windows, the pressed state appears only after a few, and won't appear at all if you quickly start to scroll with the finger.
            // So here we make sure to delay the beginning of a manipulation to match this behavior (and avoid flickering when scrolling)
            // We also make sure that when user taps (Enter->Pressed->Move*->Release->Exit) on the item, he is able to see the pressed (selected) state.
            var request = ++_goToStateRequest;

            TimeSpan delay;         // delay to apply the 'state'
            bool     pause;         // should we force a pause after applying the 'state'

            if (manipulationUpdate == ManipulationUpdateKind.Clicked &&
                _currentState != CommonStates.PressedSelected &&
                _currentState != CommonStates.Pressed)
            {
                // When clicked (i.e. pointer released), but not yet in pressed state, we force to go immediately in pressed state
                // Then we let the standard go to state process (i.e. with delay handling) reach the final expected state.

                var pressedState = GetState(IsSelected, IsPointerOver, isPressed: true);
                _currentState = pressedState;
                VisualStateManager.GoToState(this, pressedState, true);

                _pauseStateUpdateUntil = DateTime.Now + MinTimeBetweenPressStates;

                delay = MinTimeBetweenPressStates;
                pause = false;
            }
            else if (manipulationUpdate == ManipulationUpdateKind.Begin)
            {
                // We delay the beginning of a manipulation to avoid flickers, but not for "exact" devices which has hover states
                // (i.e. mouse and pen when not on iOS)

                delay = MinTimeBetweenPressStates;
                pause = true;
            }
            else
            {
                delay = _pauseStateUpdateUntil - DateTime.Now;
                pause = false;
            }

            if (delay < TimeSpan.Zero)
            {
                _currentState = state;
                VisualStateManager.GoToState(this, state, true);
            }
            else
            {
                CoreDispatcher.Main.RunAsync(CoreDispatcherPriority.Normal, async() =>
                {
                    await Task.Delay(delay);

                    if (_goToStateRequest != request)
                    {
                        return;
                    }

                    _currentState = state;
                    VisualStateManager.GoToState(this, state, true);

                    if (pause)
                    {
                        _pauseStateUpdateUntil = DateTime.Now + MinTimeBetweenPressStates;
                    }
                });
            }
        }
コード例 #3
0
        private void UpdateCommonStates(ManipulationUpdateKind manipulationUpdate = ManipulationUpdateKind.None)
        {
            // On Windows, the pressed state appears only after a few, and won't appear at all if you quickly start to scroll with the finger.
            // So here we make sure to delay the beginning of a manipulation to match this behavior (and avoid flickering when scrolling)
            // We also make sure that when user taps (Enter->Pressed->Move*->Release->Exit) on the item, he is able to see the pressed (selected) state.
            var state     = GetState(IsEnabled, IsSelected, IsPointerOver, _canRaiseClickOnPointerRelease);
            var requestId = ++_goToStateRequest; // Request ID is use to ensure to apply only the last requested state.

            TimeSpan delay;                      // delay to apply the 'state'
            bool     pause;                      // should we force a pause after applying the 'state'

            if (manipulationUpdate == ManipulationUpdateKind.Clicked &&
                _currentState != CommonStates.PressedSelected &&
                _currentState != CommonStates.Pressed)
            {
                // When clicked (i.e. pointer released), but not yet in pressed state, we force to go immediately in pressed state
                // Then we let the standard go to state process (i.e. with delay handling) reach the final expected state.

                var pressedState = GetState(IsEnabled, IsSelected, IsPointerOver, isPressed: true);
                _currentState = pressedState;
                VisualStateManager.GoToState(this, pressedState, true);

                _pauseStateUpdateUntil = _chronometer.Elapsed + MinTimeBetweenPressStates;

                delay = MinTimeBetweenPressStates;
                pause = false;
            }
            else if (manipulationUpdate == ManipulationUpdateKind.Begin)
            {
                // We delay the beginning of a manipulation to avoid flickers, but not for "exact" devices which has hover states
                // (i.e. mouse and pen when not on iOS)

                delay = MinTimeBetweenPressStates;
                pause = true;
            }
            else
            {
                delay = _pauseStateUpdateUntil - _chronometer.Elapsed;
                pause = false;
            }

            if (delay < TimeSpan.Zero)
            {
                _currentState = state;
                VisualStateManager.GoToState(this, state, true);
            }
            else
            {
                CoreDispatcher.Main.RunAsync(CoreDispatcherPriority.Normal, async() =>
                {
                    await Task.Delay(delay);

                    if (_goToStateRequest != requestId
                        // If element has been unloaded (e.g. click on a ComboBoxItem) native animations of the target state won't run.
                        // Then even if on next load we request UpdateCommonStates,
                        // the VSM will determine that state didn't changed and will just ignore the request.
                        // Note: The issue is probably in the VSM to allow a GoToState while not in visual tree,
                        //		 but this is the most common case and teh safest place to patch.
                        || !IsLoaded)
                    {
                        return;
                    }

                    _currentState = state;
                    VisualStateManager.GoToState(this, state, true);

                    if (pause)
                    {
                        _pauseStateUpdateUntil = _chronometer.Elapsed + MinTimeBetweenPressStates;
                    }
                });
            }
        }