internal static bool SetFocusedElementWithDirection( DependencyObject pElement, FocusState focusState, bool animateIfBringIntoView, bool forceBringIntoView, FocusNavigationDirection focusNavigationDirection) { DependencyObject spElementToFocus = pElement; Control? spControlToFocus; bool pFocusUpdated = false; if (pElement == null) { throw new ArgumentNullException(nameof(pElement)); } spControlToFocus = spElementToFocus as Control; if (spControlToFocus != null) { // For control, use IControl.Focus, for safer backward compat if (animateIfBringIntoView) { // Set the flag that indicates that the Focus change operation // needs to use an animation if the element is brouhgt into view. (spControlToFocus as Control).SetAnimateIfBringIntoView(); } pFocusUpdated = (spControlToFocus as Control).FocusWithDirection(focusState, focusNavigationDirection); } else { bool isShiftPressed = (focusNavigationDirection == FocusNavigationDirection.Previous); bool isProcessingTab = (focusNavigationDirection == FocusNavigationDirection.Next) || isShiftPressed; // Set focus on non-controls, like Hyperlink. DependencyObject?spElementToFocusDO; spElementToFocusDO = spElementToFocus as DependencyObject; FocusManager? focusManager = VisualTree.GetFocusManagerForElement(spElementToFocusDO); FocusMovement movement = new FocusMovement( spElementToFocusDO, focusNavigationDirection, focusState); movement.ForceBringIntoView = forceBringIntoView; movement.AnimateIfBringIntoView = animateIfBringIntoView; movement.IsProcessingTab = isProcessingTab; movement.IsShiftPressed = isShiftPressed; var result = focusManager?.SetFocusedElement(movement); pFocusUpdated = result?.WasMoved ?? false; } return(pFocusUpdated); }
private static IAsyncOperation <FocusMovementResult> TryFocusAsyncImpl( DependencyObject pElement, FocusState focusState) { FocusManager?focusManager = VisualTree.GetFocusManagerForElement(pElement); if (focusManager == null) { throw new InvalidOperationException("Element is not part of the visual tree."); } FocusMovement movement = new FocusMovement(pElement, FocusNavigationDirection.None, focusState); var spFocusAsyncOperation = new FocusAsyncOperation(movement.CorrelationId); var asyncOperation = spFocusAsyncOperation.CreateAsyncOperation(); if (FocusProperties.IsFocusable(pElement) == false) { // We need to start and complete the async operation since this is a no-op spFocusAsyncOperation.CoreSetResults(new FocusMovementResult()); spFocusAsyncOperation.CoreFireCompletion(); return(asyncOperation); } // TODO Uno specific: Do not use async operations, only simulated //movement.ShouldCompleteAsyncOperation = focusManager.TrySetAsyncOperation(spFocusAsyncOperation); if (movement.ShouldCompleteAsyncOperation) { //spFocusAsyncOperation.StartOperation(); } var result = focusManager.SetFocusedElement(movement); // TODO Uno specific: Simulate async completion. spFocusAsyncOperation?.CoreSetResults(result); spFocusAsyncOperation?.CoreFireCompletion(); // Async operation is not guaranteed to be released synchronously. // Therefore, we let UpdateFocus to handle the responsibility of releasing it. //spFocusAsyncOperation.Detach(); return(asyncOperation); }
internal bool Focus(FocusState focusState, bool animateIfBringIntoView, FocusNavigationDirection focusNavigationDirection = FocusNavigationDirection.None) { // Get FocusManager var pFocusManager = VisualTree.GetFocusManagerForElement(this, VisualTree.LookupOptions.NoFallback); if (pFocusManager == null) { return(false); } // FocusMovement is OK with NULL parameter, sets focusChanged to false FocusMovement movement = new FocusMovement(this, focusNavigationDirection, focusState); movement.AnimateIfBringIntoView = animateIfBringIntoView; FocusMovementResult result = pFocusManager.SetFocusedElement(movement); var focusChanged = result.WasMoved; return(focusChanged); }
public FocusMovementResult SetFocusedElement(FocusMovement movement) => SetFocusedElementResult ?? new FocusMovementResult();
private static bool TryMoveFocusStatic( FocusNavigationDirection focusNavigationDirection, FindNextElementOptions?pFocusNavigationOverride, ref IAsyncOperation <FocusMovementResult>?asyncOperation, bool useAsync) { DependencyObject?searchRootAsDO = null; Rect hintRect; Rect exclusionRect; XYFocusNavigationStrategyOverride navigationStrategyOverride; XYFocusOptions xyFocusOptions = new XYFocusOptions(); var pIsFocusMoved = false; FindNextElementOptions?options = pFocusNavigationOverride; bool ignoreOcclusivity; FocusAsyncOperation?spFocusAsyncOperation = null; DXamlCore pCore = DXamlCore.Current; if (pCore == null) { throw new InvalidOperationException("XamlCore is not set."); } FocusManager?focusManager = null; ContentRoot? contentRoot = null; var contentRootCoordinator = pCore.GetHandle().ContentRootCoordinator; if (options != null) { var searchRoot = options.SearchRoot; exclusionRect = options.ExclusionRect; hintRect = options.HintRect; navigationStrategyOverride = options.XYFocusNavigationStrategyOverride; ignoreOcclusivity = options.IgnoreOcclusivity; searchRootAsDO = searchRoot as DependencyObject; if (searchRootAsDO != null) { contentRoot = VisualTree.GetContentRootForElement(searchRootAsDO); focusManager = contentRoot?.FocusManager; if (focusManager == null) { throw new InvalidOperationException("Search root is not part of the visual tree."); } } else if (pCore.GetHandle().InitializationType == InitializationType.IslandsOnly) { // SearchRoot must exist for islands/ desktop throw new ArgumentException("The search root must not be null."); } else { contentRoot = contentRootCoordinator?.CoreWindowContentRoot; } // If we are being passed in the public root visual of a XamlRoot as the SearchRoot, then override the SearchRoot to be the RootVisual. // This will enable searching through both the public root visual and the popup root. We will also allow Next/Prev. bool shouldOverrideSearchRoot = contentRoot != null && GetAppVisibleXamlRootContent(contentRoot) == searchRootAsDO; if (shouldOverrideSearchRoot) { searchRootAsDO = contentRoot !.VisualTree.RootElement; } else { if (focusNavigationDirection != FocusNavigationDirection.Up && focusNavigationDirection != FocusNavigationDirection.Down && focusNavigationDirection != FocusNavigationDirection.Left && focusNavigationDirection != FocusNavigationDirection.Right) { throw new ArgumentOutOfRangeException( "Focus navigation directions Next, Previous, and None " + "are not supported when using FindNextElementOptions"); } } xyFocusOptions.NavigationStrategyOverride = navigationStrategyOverride; xyFocusOptions.IgnoreOcclusivity = ignoreOcclusivity; Rect exclusionRectNative = exclusionRect; Rect hintRectNative = hintRect; if (searchRootAsDO != null) { xyFocusOptions.SearchRoot = searchRootAsDO; } if (!exclusionRectNative.IsUniform) { xyFocusOptions.ExclusionRect = exclusionRectNative; } if (!hintRectNative.IsUniform) { xyFocusOptions.FocusHintRectangle = hintRectNative; } if (contentRoot != null) { var scale = RootScale.GetRasterizationScaleForContentRoot(contentRoot); ConvertOptionsRectsToPhysical(scale, xyFocusOptions); } } if (focusManager == null) { // Return error if call is without focus navigation option in islands/ desktop if (pCore.GetHandle().InitializationType == InitializationType.IslandsOnly) { throw new InvalidOperationException("Focus navigation options must be set for desktop apps."); } // For compat reasons, these FocusManager static APIs need to always use the CoreWindow as the // ContentRoot, so explicitly return the CoreWindow content root. if (contentRoot == null) { contentRoot = contentRootCoordinator?.CoreWindowContentRoot; } if (contentRoot == null) { return(pIsFocusMoved); } focusManager = contentRoot.FocusManager; } FocusMovement movement = new FocusMovement(xyFocusOptions, focusNavigationDirection, null); if (useAsync) { spFocusAsyncOperation = new FocusAsyncOperation(movement.CorrelationId); asyncOperation = spFocusAsyncOperation.CreateAsyncOperation(); // Async operation is not guaranteed to be released synchronously. // Therefore, we let UpdateFocus to handle the responsibility of releasing it. // TODO Uno specific: Do not use async operations, only simulated // movement.ShouldCompleteAsyncOperation = focusManager.TrySetAsyncOperation(spFocusAsyncOperation); if (movement.ShouldCompleteAsyncOperation) { //spFocusAsyncOperation.StartOperation(); } } FocusMovementResult result = focusManager.FindAndSetNextFocus(movement); // TODO Uno specific: Simulate async completion. spFocusAsyncOperation?.CoreSetResults(result); spFocusAsyncOperation?.CoreFireCompletion(); // We ignore result.GetHResult() here because this is a "Try" function pIsFocusMoved = result.WasMoved; // Async operation is not guaranteed to be released synchronously. // Therefore, we let UpdateFocus to handle the responsibility of releasing it. //spFocusAsyncOperation.Detach(); return(pIsFocusMoved); }