private void ClearStateFlags() { using var suspender = new StateChangeSuspender(this); IsPressed = false; IsPointerOver = false; _isPointerCaptured = false; _isSpaceOrEnterKeyDown = false; _isPointerLeftButtonDown = false; _isNavigationAcceptOrGamepadAKeyDown = false; }
protected override void OnPointerPressed(PointerRoutedEventArgs args) { if (args.Handled) { Cleanup(); return; } var pointerPoint = args.GetCurrentPoint(this); var pointerProperties = pointerPoint.Properties; var isLeftButtonPressed = pointerProperties.IsLeftButtonPressed; if (isLeftButtonPressed) { _isPointerLeftButtonDown = true; // Note: even if ClickMode is Press, we capture the pointer and handle the Release args, but we do nothing if Hover // Capturing the Pointer ensures that we will be the first element to receive the pointer released event // It will also ensure that if we scroll while pressing the button, as the capture will be lost, we won't raise Click. if (!IsEnabled || ClickMode == ClickMode.Hover) { Cleanup(); return; } args.Handled = true; using (var suspender = new StateChangeSuspender(this)) { Focus(FocusState.Pointer); CapturePointerInternal(args.Pointer); if (_isPointerCaptured) { IsPressed = true; } } if (ClickMode == ClickMode.Press) { RaiseClick(args); } } Cleanup(); void Cleanup() { base.OnPointerPressed(args); } }
protected override void OnPointerExited(PointerRoutedEventArgs e) { IsPointerOver = false; using (var suspender = new StateChangeSuspender(this)) { if (ClickMode == ClickMode.Hover && IsEnabled) { IsPressed = false; } } base.OnPointerExited(e); }
protected override void OnPointerEntered(PointerRoutedEventArgs args) { IsPointerOver = true; using (var suspender = new StateChangeSuspender(this)) { if (ClickMode == ClickMode.Hover && IsEnabled) { IsPressed = true; RaiseClick(args); } } base.OnPointerEntered(args); }
protected override void OnLostFocus(RoutedEventArgs e) { if (FocusState == FocusState.Unfocused) { using var suspender = new StateChangeSuspender(this); if (ClickMode != ClickMode.Hover) { IsPressed = false; ReleasePointerCaptureInternal(null); } } base.OnLostFocus(e); }
protected override void OnPointerCaptureLost(PointerRoutedEventArgs args) { base.OnPointerCaptureLost(args); var pointer = args.Pointer; ReleasePointerCaptureInternal(pointer); // For touch, we can clear PointerOver when receiving PointerCaptureLost, which we get when the finger is lifted // or from cancellation, e.g. pinch-zoom gesture in ScrollViewer. // For mouse, we need to wait for PointerExited because the mouse may still be above the ButtonBase when // PointerCaptureLost is received from clicking. var pointerPoint = args.GetCurrentPoint(null); var pointerDeviceType = pointerPoint.PointerDevice?.PointerDeviceType ?? PointerDeviceType.Touch; if (pointerDeviceType == PointerDeviceType.Touch) { //IsPointerOver = false; } using var suspender = new StateChangeSuspender(this); IsPressed = false; }