public static bool MoveFocus([CanBeNull] DependencyObject element, FocusNavigationDirection direction = FocusNavigationDirection.Next) { var e = element as UIElement; if (e == null) return false; e.MoveFocus(new TraversalRequest(direction)); return true; }
/// <summary> /// Gets the next control in the specified navigation direction. /// </summary> /// <param name="element">The element.</param> /// <param name="direction">The navigation direction.</param> /// <returns> /// The next element in the specified direction, or null if <paramref name="element"/> /// was the last in the requested direction. /// </returns> public static IInputElement GetNext( IInputElement element, FocusNavigationDirection direction) { Contract.Requires<ArgumentNullException>(element != null); Contract.Requires<ArgumentException>( direction != FocusNavigationDirection.Next && direction != FocusNavigationDirection.Previous); var container = element.GetVisualParent<IInputElement>(); if (container != null) { var isForward = IsForward(direction); var mode = KeyboardNavigation.GetDirectionalNavigation((InputElement)container); switch (mode) { case KeyboardNavigationMode.Continue: return GetNextInContainer(element, container, direction) ?? GetFirstInNextContainer(element, direction); case KeyboardNavigationMode.Cycle: return GetNextInContainer(element, container, direction) ?? GetFocusableDescendent(container, direction); case KeyboardNavigationMode.Contained: return GetNextInContainer(element, container, direction); default: return null; } } else { return GetFocusableDescendents(element).FirstOrDefault(); } }
/// <summary> /// Returns a value indicting whether the specified direction is forward. /// </summary> /// <param name="direction">The direction.</param> /// <returns>True if the direction is forward.</returns> private static bool IsForward(FocusNavigationDirection direction) { return direction == FocusNavigationDirection.Next || direction == FocusNavigationDirection.Last || direction == FocusNavigationDirection.Right || direction == FocusNavigationDirection.Down; }
/// <summary> /// Gets the first item that should be focused in the next container. /// </summary> /// <param name="container">The container.</param> /// <param name="direction">The direction of the search.</param> /// <returns>The first element, or null if there are no more elements.</returns> private static IInputElement GetFirstInNextContainer( IInputElement container, FocusNavigationDirection direction) { var parent = container.GetVisualParent<IInputElement>(); var isForward = IsForward(direction); IInputElement next = null; if (parent != null) { if (!isForward && parent.CanFocus()) { return parent; } var siblings = parent.GetVisualChildren() .OfType<IInputElement>() .Where(FocusExtensions.CanFocusDescendents); IInputElement sibling; if (isForward) { sibling = siblings.SkipWhile(x => x != container).Skip(1).FirstOrDefault(); } else { sibling = siblings.TakeWhile(x => x != container).LastOrDefault(); } if (sibling != null) { if (sibling.CanFocus()) { next = sibling; } else { next = isForward ? GetFocusableDescendents(sibling).FirstOrDefault() : GetFocusableDescendents(sibling).LastOrDefault(); } } if (next == null) { next = GetFirstInNextContainer(parent, direction); } } else { next = isForward ? GetFocusableDescendents(container).FirstOrDefault() : GetFocusableDescendents(container).LastOrDefault(); } return next; }
/// <summary> /// Initializes a new instance of the <see cref="QueryMoveFocusEventArgs"/> class. /// </summary> /// <param name="pDirection">The focus direction.</param> /// <param name="pReachedMaxLength">Flag indicating if the text maximum length has been reached.</param> internal QueryMoveFocusEventArgs(FocusNavigationDirection pDirection, bool pReachedMaxLength) : base(AutoSelectTextBox.QueryMoveFocusEvent) { // Internal to prevent anybody from building this type of event. this.FocusNavigationDirection = pDirection; this.ReachedMaxLength = pReachedMaxLength; // Defaults to true. If nobody does nothing, then its capable of moving focus. this.CanMoveFocus = true; }
private void TryMoveFocus(FocusNavigationDirection direction) { if (direction == FocusNavigationDirection.Next || direction == FocusNavigationDirection.Previous) { FocusManager.TryMoveFocus(direction); } else { var control = FocusManager.FindNextFocusableElement(direction) as Control; control?.Focus(FocusState.Programmatic); } }
private static bool MoveFocus(FocusNavigationDirection navigationDirection) { var traversalRequest = new TraversalRequest(navigationDirection); var keyboardFocus = Keyboard.FocusedElement as UIElement; if (keyboardFocus != null) { keyboardFocus.MoveFocus(traversalRequest); return(true); } return(false); }
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); }
/// <summary> /// Helper method to move focus into the footer pane /// </summary> internal bool FooterPaneMoveFocus(FocusNavigationDirection direction) { UIElement footerPaneHost = FooterPaneHost; if (footerPaneHost != null && footerPaneHost.IsVisible && footerPaneHost.IsEnabled && footerPaneHost.MoveFocus(new TraversalRequest(direction))) { return(true); } return(false); }
/// <summary> /// Helper method to move focus into auxiliary pane. /// </summary> internal bool AuxiliaryPaneMoveFocus(FocusNavigationDirection direction) { UIElement auxiliaryPaneHost = AuxiliaryPaneHost; if (auxiliaryPaneHost != null && auxiliaryPaneHost.IsVisible && auxiliaryPaneHost.IsEnabled && auxiliaryPaneHost.MoveFocus(new TraversalRequest(direction))) { return(true); } return(false); }
private static void MoveToNextUiElement(RoutedEventArgs e) { const FocusNavigationDirection focusDirection = FocusNavigationDirection.Next; var request = new TraversalRequest(focusDirection); if (!(Keyboard.FocusedElement is UIElement elementWithFocus)) { return; } if (elementWithFocus.MoveFocus(request)) { e.Handled = true; } }
private static DependencyObject?GetDirectionOverrideRoot( DependencyObject?element, DependencyObject?searchRoot, FocusNavigationDirection direction) { var root = element; while (root != null && GetDirectionOverride(root, searchRoot, direction) == null) { root = root.GetParent() as DependencyObject; } return(root); }
protected override void MoveSelection(FocusNavigationDirection direction) { // TODO: Up and down movement is a *HACK* and probably pretty slow. Probably needs // rewriting at some point. if (this.SelectedItem != null) { switch (direction) { case FocusNavigationDirection.Up: { var list = this.Flatten(); var index = list.IndexOf(this.SelectedItem); if (index > 0) { this.SelectedItem = list[index - 1]; } break; } case FocusNavigationDirection.Down: { var list = this.Flatten(); var index = list.IndexOf(this.SelectedItem); if (index + 1 < list.Count) { this.SelectedItem = list[index + 1]; } break; } case FocusNavigationDirection.Left: { var node = (TreeViewItem)this.ItemContainerGenerator.GetContainerForItem(this.SelectedItem); node.IsExpanded = false; break; } case FocusNavigationDirection.Right: { var node = (TreeViewItem)this.ItemContainerGenerator.GetContainerForItem(this.SelectedItem); node.IsExpanded = true; break; } } } }
protected virtual void MoveSelection(FocusNavigationDirection direction) { // TODO: Up and down movement is a *HACK* and probably pretty slow. Probably needs // rewriting at some point. if (this.SelectedItem != null) { switch (direction) { case FocusNavigationDirection.Up: { var list = this.Flatten(); var index = list.IndexOf(this.SelectedItem); if (index > 0) { this.SelectedItem = list[index - 1]; } break; } case FocusNavigationDirection.Down: { var list = this.Flatten(); var index = list.IndexOf(this.SelectedItem); if (index + 1 < list.Count) { this.SelectedItem = list[index + 1]; } break; } case FocusNavigationDirection.Left: { var node = (TreeViewItem)this.ItemContainerGenerator.GetContainerForItem(this.SelectedItem); node.IsExpanded = false; break; } case FocusNavigationDirection.Right: { var node = (TreeViewItem)this.ItemContainerGenerator.GetContainerForItem(this.SelectedItem); node.IsExpanded = true; break; } } } }
/// <summary> /// Moves the focus in the specified direction. /// </summary> /// <param name="element">The current element.</param> /// <param name="direction">The direction to move.</param> public void Move(IInputElement element, FocusNavigationDirection direction) { Contract.Requires<ArgumentNullException>(element != null); var next = GetNext(element, direction); if (next != null) { var method = direction == FocusNavigationDirection.Next || direction == FocusNavigationDirection.Previous ? NavigationMethod.Tab : NavigationMethod.Directional; FocusManager.Instance.Focus(next, method); } }
/// <summary> /// Gets the first item that should be focused in the next container. /// </summary> /// <param name="container">The container.</param> /// <param name="direction">The direction of the search.</param> /// <returns>The first element, or null if there are no more elements.</returns> private static IInputElement GetFirstInNextContainer( IInputElement container, FocusNavigationDirection direction) { var parent = container.GetVisualParent <IInputElement>(); var isForward = IsForward(direction); IInputElement next = null; if (parent != null) { if (!isForward && parent.CanFocus()) { return(parent); } var siblings = parent.GetVisualChildren() .OfType <IInputElement>() .Where(FocusExtensions.CanFocusDescendents); var sibling = isForward ? siblings.SkipWhile(x => x != container).Skip(1).FirstOrDefault() : siblings.TakeWhile(x => x != container).LastOrDefault(); if (sibling != null) { if (sibling.CanFocus()) { next = sibling; } else { next = isForward ? GetFocusableDescendents(sibling).FirstOrDefault() : GetFocusableDescendents(sibling).LastOrDefault(); } } if (next == null) { next = GetFirstInNextContainer(parent, direction); } } else { next = isForward ? GetFocusableDescendents(container).FirstOrDefault() : GetFocusableDescendents(container).LastOrDefault(); } return(next); }
/// <summary> /// Moves the focus in the specified direction. /// </summary> /// <param name="element">The current element.</param> /// <param name="direction">The direction to move.</param> public void Move(IInputElement element, FocusNavigationDirection direction) { Contract.Requires <ArgumentNullException>(element != null); var next = GetNext(element, direction); if (next != null) { var method = direction == FocusNavigationDirection.Next || direction == FocusNavigationDirection.Previous ? NavigationMethod.Tab : NavigationMethod.Directional; FocusManager.Instance.Focus(next, method); } }
private void MoveFocus(FocusNavigationDirection direction) { //var request = new TraversalRequest(direction); TraversalRequest request = new TraversalRequest(direction); // Gets the element with keyboard focus. UIElement elementWithFocus = Keyboard.FocusedElement as UIElement; // Change keyboard focus. if (elementWithFocus != null) { elementWithFocus.MoveFocus(request); } }
private void MoveToNextUIElement(KeyEventArgs pObjArgs) { FocusNavigationDirection lObjfocusDirection = FocusNavigationDirection.Next; TraversalRequest lObjrequest = new TraversalRequest(lObjfocusDirection); UIElement lObjElementWithFocus = Keyboard.FocusedElement as UIElement; if (lObjElementWithFocus != null) { if (lObjElementWithFocus.MoveFocus(lObjrequest)) { pObjArgs.Handled = true; } } }
void MoveToNextUIElement(KeyEventArgs e) { FocusNavigationDirection focusDirection = FocusNavigationDirection.Next; TraversalRequest request = new TraversalRequest(focusDirection); UIElement elementWithFocus = Keyboard.FocusedElement as UIElement; if (elementWithFocus != null) { if (elementWithFocus.MoveFocus(request)) { e.Handled = true; } } }
internal static DependencyObject PredictFocus(DependencyObject o, FocusNavigationDirection direction) { Debug.Assert(o != null, "UIElementHelper.PredictFocus called with null argument"); UIElement oAsUIElement = o as UIElement; if (oAsUIElement != null) { return oAsUIElement.PredictFocus(direction); } else { return ((UIElement3D)o).PredictFocus(direction); } }
public void VerifyNearnessMeasuresShadow() { Rect a = new Rect(new Point(0, 100), new Point(50, 200)); Rect b = new Rect(new Point(75, 50), new Point(125, 140)); Rect c = new Rect(new Point(75, 150), new Point(125, 200)); const double maxDistance = 600; FocusNavigationDirection direction = FocusNavigationDirection.Down; double scoreA = ProximityStrategy.GetScore(direction, a, b, maxDistance, true); double scoreB = ProximityStrategy.GetScore(direction, a, c, maxDistance, true); Assert.IsTrue(scoreA == scoreB); }
/// <summary> /// Moves the selected item in the specified direction. /// </summary> private void MoveSelectedItem(FocusNavigationDirection direction, ModifierKeys modifiers = ModifierKeys.None) { var selection = Keyboard.GetFocusedElement(View) as UIElement; if (selection != null && selection.MoveFocus(direction)) { var focused = Keyboard.GetFocusedElement(View) as UIElement; var listBoxItem = ItemsControlUtil.FindContainer <ListBoxItem>(this, focused); if (listBoxItem != null && (modifiers & ModifierKeys.Control) != ModifierKeys.Control) { HandleItemClickedAndScrollIntoView(listBoxItem); } } }
public bool MoveToCell(FocusNavigationDirection direction) { if (CurrentRow == null) { return(false); } using (PreserveEditState()) { int currentColumnIndex = -1; if (DataGrid.CurrentCell != null) { currentColumnIndex = DataGrid.CurrentCell.Column.DisplayIndex; if (!CommitEdit(DataGridEditingUnit.Cell, true)) { return(false); } } switch (direction) { case FocusNavigationDirection.First: currentColumnIndex = 0; break; case FocusNavigationDirection.Last: currentColumnIndex = DataGrid.Columns.Count - 1; break; case FocusNavigationDirection.Right: currentColumnIndex = (currentColumnIndex + 1) % DataGrid.Columns.Count; break; case FocusNavigationDirection.Left: currentColumnIndex = (currentColumnIndex - 1 + DataGrid.Columns.Count) % DataGrid.Columns.Count; break; default: throw new ArgumentException("Argument must specify an absolute horizontal direction: First, Last, Right or Left", "direction"); } DataGridColumn nextColumn = DataGrid.Columns.First((c) => { return(c.DisplayIndex == currentColumnIndex); }); DataGrid.CurrentColumn = nextColumn; } return(true); }
/// <summary> /// Gets the next control in the specified direction. /// </summary> /// <param name="direction">The movement direction.</param> /// <param name="from">The control from which movement begins.</param> /// <returns>The control.</returns> IInputElement INavigableContainer.GetControl(FocusNavigationDirection direction, IInputElement from) { var horiz = Orientation == Orientation.Horizontal; int index = Children.IndexOf((IControl)from); switch (direction) { case FocusNavigationDirection.First: index = 0; break; case FocusNavigationDirection.Last: index = Children.Count - 1; break; case FocusNavigationDirection.Next: ++index; break; case FocusNavigationDirection.Previous: --index; break; case FocusNavigationDirection.Left: index = horiz ? index - 1 : -1; break; case FocusNavigationDirection.Right: index = horiz ? index + 1 : -1; break; case FocusNavigationDirection.Up: index = horiz ? -1 : index - 1; break; case FocusNavigationDirection.Down: index = horiz ? -1 : index + 1; break; } if (index >= 0 && index < Children.Count) { return(Children[index]); } else { return(null); } }
/// <summary> /// Default keyboard focus movement for any unhandled keyboarding /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void AppShell_KeyDown(object sender, KeyRoutedEventArgs e) { FocusNavigationDirection direction = FocusNavigationDirection.None; switch (e.Key) { case Windows.System.VirtualKey.Left: case Windows.System.VirtualKey.GamepadDPadLeft: case Windows.System.VirtualKey.GamepadLeftThumbstickLeft: case Windows.System.VirtualKey.NavigationLeft: direction = FocusNavigationDirection.Left; break; case Windows.System.VirtualKey.Right: case Windows.System.VirtualKey.GamepadDPadRight: case Windows.System.VirtualKey.GamepadLeftThumbstickRight: case Windows.System.VirtualKey.NavigationRight: direction = FocusNavigationDirection.Right; break; case Windows.System.VirtualKey.Up: case Windows.System.VirtualKey.GamepadDPadUp: case Windows.System.VirtualKey.GamepadLeftThumbstickUp: case Windows.System.VirtualKey.NavigationUp: direction = FocusNavigationDirection.Up; break; case Windows.System.VirtualKey.Down: case Windows.System.VirtualKey.GamepadDPadDown: case Windows.System.VirtualKey.GamepadLeftThumbstickDown: case Windows.System.VirtualKey.NavigationDown: direction = FocusNavigationDirection.Down; break; } if (direction == FocusNavigationDirection.None) { return; } var control = FocusManager.FindNextFocusableElement(direction) as Control; if (control == null) { return; } control.Focus(FocusState.Programmatic); e.Handled = true; }
private static bool UpdateFocus(DependencyObject newFocus, FocusNavigationDirection focusNavigationDirection, FocusState focusState) { // TODO: check AllowFocusOnInteraction if (_log.Value.IsEnabled(LogLevel.Debug)) { _log.Value.LogDebug($"{nameof(UpdateFocus)}()- oldFocus={_focusedElement}, newFocus={newFocus}, oldFocus.FocusState={(_focusedElement as Control)?.FocusState}, focusState={focusState}"); } if (newFocus == _focusedElement) { var newFocusAsControl = newFocus as Control; if (newFocusAsControl != null && newFocusAsControl.FocusState != focusState) { // We do not raise GettingFocus here since the OldFocusedElement and NewFocusedElement // would be the same element. RaiseGotFocusEvent(_focusedElement); // Make sure the FocusState is up-to-date. (newFocus as Control)?.UpdateFocusState(focusState); } // No change in focus element - can skip the rest of this method. return(true); } //TODO: RaiseAndProcessGettingAndLosingFocusEvents var oldFocusedElement = _focusedElement; (oldFocusedElement as Control)?.UpdateFocusState(FocusState.Unfocused); // Set previous unfocused // Update the focused control _focusedElement = newFocus; (newFocus as Control)?.UpdateFocusState(focusState); FocusNative(newFocus as Control); if (oldFocusedElement != null) { RaiseLostFocusEvent(oldFocusedElement); } if (_focusedElement != null) { RaiseGotFocusEvent(_focusedElement); } return(true); }
public void VerifyProximityStrategyClosestToAxisWithExtremeDistance() { Rect focusedElement = new Rect(new Point(100, 100), new Point(200, 200)); Rect candidateElementA = new Rect(new Point(2000, 200), new Point(2200, 300)); Rect candidateElementB = new Rect(new Point(100, 315), new Point(200, 415)); const double maxDistance = 3000; FocusNavigationDirection direction = FocusNavigationDirection.Down; double scoreA = ProximityStrategy.GetScore(direction, focusedElement, candidateElementA, maxDistance, false); double scoreB = ProximityStrategy.GetScore(direction, focusedElement, candidateElementB, maxDistance, false); Assert.IsTrue(scoreA > scoreB); }
/// <summary> /// Manually handle tab navigation. Tab not working maybe because accelerators aren't translated. /// </summary> /// <param name="e">Key event.</param> protected override void OnPreviewKeyUp(KeyEventArgs e) { base.OnPreviewKeyUp(e); if (e.Key != Key.Tab) { return; } var focusedElement = Keyboard.FocusedElement as UIElement; FocusNavigationDirection direction = Keyboard.Modifiers.HasFlag(ModifierKeys.Shift) ? FocusNavigationDirection.Previous : FocusNavigationDirection.Next; focusedElement?.MoveFocus(new TraversalRequest(direction)); }
/// <summary> /// This method is a work-around until the bug in FocusManager.TryMoveFocus is fixed. /// </summary> /// <param name="direction"></param> private void TryMoveFocus(FocusNavigationDirection direction) { if (direction == FocusNavigationDirection.Next || direction == FocusNavigationDirection.Previous) { FocusManager.TryMoveFocus(direction); } else { var control = FocusManager.FindNextFocusableElement(direction) as Windows.UI.Xaml.Controls.Control; if (control != null) { control.Focus(FocusState.Programmatic); } } }
/// <summary> /// Gets the next control in the specified navigation direction. /// </summary> /// <param name="element">The element.</param> /// <param name="direction">The navigation direction.</param> /// <returns> /// The next element in the specified direction, or null if <paramref name="element"/> /// was the last in therequested direction. /// </returns> public static IInputElement GetNext( IInputElement element, FocusNavigationDirection direction) { Contract.Requires<ArgumentNullException>(element != null); if (direction == FocusNavigationDirection.Next || direction == FocusNavigationDirection.Previous) { return TabNavigation.GetNextInTabOrder(element, direction); } else { return DirectionalNavigation.GetNext(element, direction); } }
internal static bool SetFocusedElementWithDirection( this DependencyObject sourceElement, // In WinUI this parameter does not exist, as the method is static on DependencyObject DependencyObject?pFocusedElement, FocusState focusState, bool animateIfBringIntoView, FocusNavigationDirection focusNavigationDirection, bool forceBringIntoView) { return(FocusManager.SetFocusedElementWithDirection( pFocusedElement, focusState, animateIfBringIntoView, forceBringIntoView, focusNavigationDirection)); }
public void VerifyEmptyRectsAreIgnoredAsCandidates() { var focusedElement = new Rect(new Point(100, 100), new Point(200, 200)); var candidateElement = new Rect(new Point(100, 10), new Point(100, 10)); const double maxDistance = 600; FocusNavigationDirection direction = FocusNavigationDirection.Up; bool shouldConsider = XYFocusAlgorithms.ShouldCandidateBeConsideredForRanking( focusedElement, candidateElement, maxDistance, direction, new Rect()); Assert.IsFalse(shouldConsider); }
public void VerifyProximityStrategyNearness() { Rect focusedElement = new Rect(new Point(100, 100), new Point(200, 200)); Rect candidateElementA = new Rect(new Point(1000, 110), new Point(1200, 160)); Rect candidateElementB = new Rect(new Point(100, 300), new Point(200, 400)); const double maxDistance = 600; FocusNavigationDirection direction = FocusNavigationDirection.Down; double scoreA = ProximityStrategy.GetScore(direction, focusedElement, candidateElementA, maxDistance, true); double scoreB = ProximityStrategy.GetScore(direction, focusedElement, candidateElementB, maxDistance, true); Assert.IsTrue(scoreB > scoreA); }
private void MoveFocus(ListBox listBox, FocusNavigationDirection direction) { var scrollViewer = VisualTreeExtensions.FindVisualChildren <ScrollViewer>(listBox).First(); if (direction == FocusNavigationDirection.First) { scrollViewer.ScrollToTop(); } else { scrollViewer.ScrollToBottom(); } Dispatcher.Invoke(new Action(() => { listBox.MoveFocus(new TraversalRequest(direction)); }), DispatcherPriority.ContextIdle, null); }
/// <summary> /// Gets the next control in the specified navigation direction. /// </summary> /// <param name="element">The element.</param> /// <param name="direction">The navigation direction.</param> /// <returns> /// The next element in the specified direction, or null if <paramref name="element"/> /// was the last in therequested direction. /// </returns> public static IInputElement GetNext( IInputElement element, FocusNavigationDirection direction) { Contract.Requires <ArgumentNullException>(element != null); if (direction == FocusNavigationDirection.Next || direction == FocusNavigationDirection.Previous) { return(TabNavigation.GetNextInTabOrder(element, direction)); } else { return(DirectionalNavigation.GetNext(element, direction)); } }
/// <summary> /// Перемещение клавиатурного фокуса на предыдущее поле. /// Леволежащее поле определяется методом FocusNavigationDirection.Previous /// </summary> public static void JumpToPrevious(KeyEventArgs eventArgs) { const FocusNavigationDirection focusDirection = FocusNavigationDirection.Previous; var request = new TraversalRequest(focusDirection); var elementWithFocus = Keyboard.FocusedElement as UIElement; if (elementWithFocus == null) { return; } if (elementWithFocus.MoveFocus(request)) { eventArgs.Handled = true; } }
internal static DependencyObject PredictFocus(DependencyObject o, FocusNavigationDirection direction) { Debug.Assert(o != null, "UIElementHelper.PredictFocus called with null argument"); UIElement oAsUIElement = o as UIElement; if (oAsUIElement != null) { return(oAsUIElement.PredictFocus(direction)); } else { return(((UIElement3D)o).PredictFocus(direction)); } }
/// <remarks> See overview of keyboard input handling in WebBrowser.cs. </remarks> int UnsafeNativeMethods.IOleControlSite.TranslateAccelerator(ref MSG msg, int grfModifiers) { // Handle tabbing out of the WebOC if ((WindowMessage)msg.message == WindowMessage.WM_KEYDOWN && (int)msg.wParam == NativeMethods.VK_TAB) { FocusNavigationDirection direction = (grfModifiers & 1 /*KEYMOD_SHIFT*/) != 0 ? FocusNavigationDirection.Previous : FocusNavigationDirection.Next; // For the WebOCHostedInBrowserProcess case, we need to switch to the right thread. Host.Dispatcher.Invoke( DispatcherPriority.Send, new SendOrPostCallback(MoveFocusCallback), direction); return(NativeMethods.S_OK); } return(NativeMethods.S_FALSE); }
/// <summary> /// Constructor that requests passing FocusNavigationDirection /// </summary> /// <param name="focusNavigationDirection">Type of focus traversal to perform</param> public TraversalRequest(FocusNavigationDirection focusNavigationDirection) { if (focusNavigationDirection != FocusNavigationDirection.Next && focusNavigationDirection != FocusNavigationDirection.Previous && focusNavigationDirection != FocusNavigationDirection.First && focusNavigationDirection != FocusNavigationDirection.Last && focusNavigationDirection != FocusNavigationDirection.Left && focusNavigationDirection != FocusNavigationDirection.Right && focusNavigationDirection != FocusNavigationDirection.Up && focusNavigationDirection != FocusNavigationDirection.Down) { throw new System.ComponentModel.InvalidEnumArgumentException("focusNavigationDirection", (int)focusNavigationDirection, typeof(FocusNavigationDirection)); } _focusNavigationDirection = focusNavigationDirection; }
/// <summary> /// 指定の方向にある Control へフォーカスの設定を試みます。 /// </summary> /// <param name="direction">フォーカスの移動方向。</param> /// <returns> /// true (フォーカスの設定に成功した場合)、false (それ以外の場合)。 /// </returns> public bool MoveFocus(FocusNavigationDirection direction) { var next = owner.GetFocusableControl(direction, FocusNavigationMode); if (next == null) return false; var result = MoveFocusTo(next); if (result) { var sound = owner.Screen.GetSound(SoundKey.FocusNavigation); if (sound != null) { if (sound.State != SoundState.Stopped) sound.Stop(); sound.Play(); } } return result; }
Control INavigablePanel.GetControl(FocusNavigationDirection direction, Control from) { var horiz = this.Orientation == Orientation.Horizontal; int index = this.Children.IndexOf(from); switch (direction) { case FocusNavigationDirection.First: index = 0; break; case FocusNavigationDirection.Last: index = this.Children.Count - 1; break; case FocusNavigationDirection.Next: ++index; break; case FocusNavigationDirection.Previous: ++index; break; case FocusNavigationDirection.Left: index = horiz ? index - 1 : -1; break; case FocusNavigationDirection.Right: index = horiz ? index + 1 : -1; break; case FocusNavigationDirection.Up: index = horiz ? -1 : index - 1; break; case FocusNavigationDirection.Down: index = horiz ? -1 : index + 1; break; } if (index >= 0 && index < this.Children.Count) { return this.Children[index]; } else { return null; } }
/// <summary> /// Gets the next control in the specified direction. /// </summary> /// <param name="direction">The movement direction.</param> /// <param name="from">The control from which movement begins.</param> /// <returns>The control.</returns> IInputElement INavigableContainer.GetControl(FocusNavigationDirection direction, IInputElement from) { var horiz = Orientation == Orientation.Horizontal; int index = Children.IndexOf((IControl)from); switch (direction) { case FocusNavigationDirection.First: index = 0; break; case FocusNavigationDirection.Last: index = Children.Count - 1; break; case FocusNavigationDirection.Next: ++index; break; case FocusNavigationDirection.Previous: --index; break; case FocusNavigationDirection.Left: index = horiz ? index - 1 : -1; break; case FocusNavigationDirection.Right: index = horiz ? index + 1 : -1; break; case FocusNavigationDirection.Up: index = horiz ? -1 : index - 1; break; case FocusNavigationDirection.Down: index = horiz ? -1 : index + 1; break; } if (index >= 0 && index < Children.Count) { return Children[index]; } else { return null; } }
public static void MoveFocus(this IInputElement element, FocusNavigationDirection direction) { //Focus in a callback to run on another thread, ensuring the main //UI thread is initialized by the time focus is set ThreadPool.QueueUserWorkItem ( delegate(object theElement) { FrameworkElement elem = (FrameworkElement)theElement; elem.InvokeAsynchronouslyInBackground ( () => { elem.Focus(); Keyboard.Focus(elem); elem.MoveFocus(new TraversalRequest(direction)); } ); }, element ); }
internal static bool NavigatePageAndHighlightRibbonGalleryItem(RibbonGallery gallery, RibbonGalleryItem galleryItem, FocusNavigationDirection direction) { RibbonGalleryItem highlightedGalleryItem; return NavigatePageAndHighlightRibbonGalleryItem(gallery, galleryItem, direction, out highlightedGalleryItem); }
/// <summary> /// Gets the next item that should be focused in the specified container. /// </summary> /// <param name="element">The starting element/</param> /// <param name="container">The container.</param> /// <param name="direction">The direction.</param> /// <returns>The next element, or null if the element is the last.</returns> private static IInputElement GetNextInContainer( IInputElement element, IInputElement container, FocusNavigationDirection direction) { if (direction == FocusNavigationDirection.Down) { var descendent = GetFocusableDescendents(element).FirstOrDefault(); if (descendent != null) { return descendent; } } if (container != null) { var navigable = container as INavigableContainer; if (navigable != null) { while (element != null) { element = navigable.GetControl(direction, element); if (element != null && element.CanFocus()) { break; } } } else { // TODO: Do a spatial search here if the container doesn't implement // INavigableContainer. element = null; } if (element != null && direction == FocusNavigationDirection.Up) { var descendent = GetFocusableDescendents(element).LastOrDefault(); if (descendent != null) { return descendent; } } return element; } return null; }
/// <summary> /// This should be PredictFocus but since UIElement.PredictFocus is sealed by FE we can't override it. /// TreeViewItem has its own code for deciding where focus should go. /// </summary> /// <param name="direction"></param> /// <returns></returns> internal DependencyObject InternalPredictFocus(FocusNavigationDirection direction) { switch (direction) { case FocusNavigationDirection.Left: case FocusNavigationDirection.Up: return FindPreviousFocusableItem(); case FocusNavigationDirection.Right: case FocusNavigationDirection.Down: return FindNextFocusableItem(true); default: return null; } }
private bool AllowHandleKeyEvent(FocusNavigationDirection direction) { if (!IsSelected) { return false; } DependencyObject currentFocus = Keyboard.FocusedElement as DependencyObject; if (currentFocus != null && UIElementHelper.IsUIElementOrUIElement3D(currentFocus)) { DependencyObject predict = UIElementHelper.PredictFocus(currentFocus, direction); if (predict != currentFocus) { while (predict != null) { TreeViewItem item = predict as TreeViewItem; if (item == this) { return false; // There is a focusable item in the header } else if ((item != null) || (predict is TreeView)) { return true; } predict = VisualTreeHelper.GetParent(predict); } } } return true; }
/// <summary> /// Request to predict the element that should receive focus relative to this element for a /// given direction, without actually moving focus to it. /// </summary> /// <param name="direction">The direction for which focus should be predicted</param> /// <returns> /// Returns the next element that focus should move to for a given FocusNavigationDirection. /// Returns null if focus cannot be moved relative to this element. /// </returns> public sealed override DependencyObject PredictFocus(FocusNavigationDirection direction) { return KeyboardNavigation.Current.PredictFocusedElement(this, direction); }
private bool CanMoveFocus( FocusNavigationDirection direction, bool reachedMax ) { QueryMoveFocusEventArgs e = new QueryMoveFocusEventArgs( direction, reachedMax ); this.RaiseEvent( e ); return e.CanMoveFocus; }
/// <summary> /// Gets the first or last focusable descendent of the specified element. /// </summary> /// <param name="container">The element.</param> /// <param name="direction">The direction to search.</param> /// <returns>The element or null if not found.##</returns> private static IInputElement GetFocusableDescendent(IInputElement container, FocusNavigationDirection direction) { return IsForward(direction) ? GetFocusableDescendents(container).FirstOrDefault() : GetFocusableDescendents(container).LastOrDefault(); }
// This method is called when trying to navigate a single step up, down, left or // right within a RibbonGallery. internal static bool NavigateAndHighlightGalleryItem(RibbonGalleryItem focusedElement, FocusNavigationDirection direction) { if (focusedElement != null) { RibbonGalleryItem predictedFocus = focusedElement.PredictFocus(direction) as RibbonGalleryItem; if (predictedFocus != null) { predictedFocus.IsHighlighted = true; return true; } } return false; }
/// <summary> /// Moves the focus in a specific direction. /// </summary> /// <param name="element">The element.</param> /// <param name="direction">The direction.</param> /// <param name="hops">The hops.</param> private static void MoveFocus(object element, FocusNavigationDirection direction, int hops) { if (hops <= 0) { return; } var frameworkElement = element as FrameworkElement; bool delayMove = ((frameworkElement != null) && !frameworkElement.IsLoaded); if (delayMove) { RoutedEventHandler onFrameworkElementLoaded = null; onFrameworkElementLoaded = delegate { MoveFocus((object)frameworkElement, direction, hops); frameworkElement.Loaded -= onFrameworkElementLoaded; }; frameworkElement.Loaded += onFrameworkElementLoaded; } else { var uiElement = element as UIElement; var contentElement = element as ContentElement; if (uiElement != null) { // Focus next uiElement.MoveFocus(new TraversalRequest(direction)); } else if (contentElement != null) { // Focus next contentElement.MoveFocus(new TraversalRequest(direction)); } if (hops > 1) { MoveFocus(Keyboard.FocusedElement, direction, hops - 1); } } }
/// <summary> /// Moves the focus in a specific direction. /// </summary> /// <param name="element">The element.</param> /// <param name="direction">The direction.</param> /// <param name="hops">The hops.</param> public static void MoveFocus(this ContentElement element, FocusNavigationDirection direction, int hops) { MoveFocus((object)element, direction, hops); }
// This method is called when trying to navigate pages within a RibbonGallery. // We approximate the RibbonGalleryItem that is a page away from the currently // focused item based upon the precomputed MaxColumnWidth and MaxRowHeight values. internal static bool NavigatePageAndHighlightRibbonGalleryItem( RibbonGallery gallery, RibbonGalleryItem galleryItem, FocusNavigationDirection direction, out RibbonGalleryItem highlightedGalleryItem) { highlightedGalleryItem = null; RibbonGalleryCategoriesPanel categoriesPanel = gallery.ItemsHostSite as RibbonGalleryCategoriesPanel; if (categoriesPanel != null) { double viewportWidth = categoriesPanel.ViewportWidth; double viewportHeight = categoriesPanel.ViewportHeight; RibbonGalleryCategory category, prevCategory = null; if (galleryItem != null) { category = galleryItem.RibbonGalleryCategory; } else { category = gallery.Items.Count > 0 ? gallery.ItemContainerGenerator.ContainerFromIndex(0) as RibbonGalleryCategory : null; galleryItem = category != null && category.Items.Count > 0 ? category.ItemContainerGenerator.ContainerFromIndex(0) as RibbonGalleryItem : null; } if (category != null) { Debug.Assert(category.RibbonGallery == gallery, "The reference RibbongalleryItem and the RibbonGallery must be related."); int startCatIndex = gallery.ItemContainerGenerator.IndexFromContainer(category); int endCatIndex, incr; if (direction == FocusNavigationDirection.Up) { endCatIndex = -1; incr = -1; } else { endCatIndex = gallery.Items.Count; incr = 1; } for (int catIndex = startCatIndex; catIndex != endCatIndex && highlightedGalleryItem == null; catIndex += incr) { category = gallery.ItemContainerGenerator.ContainerFromIndex(catIndex) as RibbonGalleryCategory; RibbonGalleryItemsPanel galleryItemsPanel = category.ItemsHostSite as RibbonGalleryItemsPanel; // We want to skip over filtered categories if (category.Visibility != Visibility.Visible) { continue; } int startItemIndex, endItemIndex, startColumnIndex, endColumnIndex, columnCount; columnCount = (int)(viewportWidth / galleryItemsPanel.MaxColumnWidth); if (direction == FocusNavigationDirection.Up) { startItemIndex = galleryItem != null ? category.ItemContainerGenerator.IndexFromContainer(galleryItem) : category.Items.Count - 1; endItemIndex = -1; if (prevCategory != null) { viewportHeight -= prevCategory.HeaderPresenter.ActualHeight; if (DoubleUtil.LessThanOrClose(viewportHeight, 0)) { highlightedGalleryItem = category.ItemContainerGenerator.ContainerFromIndex(startItemIndex) as RibbonGalleryItem; break; } } // startColumnIndex is the last column in the last row or the column of the anchor item if (columnCount == 1) { startColumnIndex = 0; endColumnIndex = 0; } else { startColumnIndex = (galleryItem != null ? startItemIndex : category.Items.Count - 1) % columnCount; endColumnIndex = 0; } } else { startItemIndex = galleryItem != null ? category.ItemContainerGenerator.IndexFromContainer(galleryItem) : 0; endItemIndex = category.Items.Count; if (prevCategory != null) { viewportHeight -= category.HeaderPresenter.ActualHeight; if (DoubleUtil.LessThanOrClose(viewportHeight, 0)) { highlightedGalleryItem = category.ItemContainerGenerator.ContainerFromIndex(startItemIndex) as RibbonGalleryItem; break; } } // endColumnIndex is the last column in the first row if (columnCount == 1) { startColumnIndex = 0; endColumnIndex = 0; } else { int remainingItems = category.Items.Count; bool isLastRow = remainingItems <= columnCount; startColumnIndex = galleryItem != null ? (startItemIndex % columnCount) : 0; endColumnIndex = isLastRow ? remainingItems - 1 : columnCount - 1; } } galleryItem = null; for (int itemIndex = startItemIndex, columnIndex = startColumnIndex; itemIndex != endItemIndex; itemIndex += incr) { if (columnIndex == endColumnIndex) { // We are at the end of a row viewportHeight -= galleryItemsPanel.MaxRowHeight; if (DoubleUtil.LessThanOrClose(viewportHeight, 0) || (itemIndex == endItemIndex - incr && catIndex == endCatIndex - incr)) { // If we have scrolled a page or have reached the boundary // of the gallery, highlight that item highlightedGalleryItem = category.ItemContainerGenerator.ContainerFromIndex(itemIndex) as RibbonGalleryItem; break; } if (direction == FocusNavigationDirection.Up) { if (columnCount > 1) { startColumnIndex = columnCount - 1; endColumnIndex = 0; } } else { if (columnCount > 1) { int remainingItems = category.Items.Count - itemIndex; bool isLastRow = remainingItems <= columnCount; startColumnIndex = 0; endColumnIndex = isLastRow ? remainingItems - 1 : columnCount - 1; } } columnIndex = startColumnIndex; } else { // We are interating through the cells in a row columnIndex += incr; } } prevCategory = category; } if (highlightedGalleryItem != null) { highlightedGalleryItem.IsHighlighted = true; return true; } } } return false; }
public static bool MoveFocus(FocusNavigationDirection direction) { UIElement uie = Keyboard.FocusedElement as UIElement; if (uie != null) { return uie.MoveFocus(new TraversalRequest(direction)); } ContentElement ce = Keyboard.FocusedElement as ContentElement; if (ce != null) { return ce.MoveFocus(new TraversalRequest(direction)); } return false; }
/// <summary> /// Tests if the focus can be given to an other control. /// </summary> /// <param name="pDirection">The focus direction.</param> /// <param name="pReachedMax">Flag to know if the maximum text length has been reached.</param> /// <returns></returns> private bool CanMoveFocus(FocusNavigationDirection pDirection, bool pReachedMax) { QueryMoveFocusEventArgs lEvent = new QueryMoveFocusEventArgs(pDirection, pReachedMax); this.RaiseEvent(lEvent); return lEvent.CanMoveFocus; }
public static DependencyObject PredictFocus(DependencyObject element, FocusNavigationDirection direction) { UIElement uie = element as UIElement; if (uie != null) { return uie.PredictFocus(direction); } ContentElement ce = element as ContentElement; if (ce != null) { return ce.PredictFocus(direction); } return null; }
/// <summary> /// This method is a work-around until the bug in FocusManager.TryMoveFocus is fixed. /// </summary> /// <param name="direction"></param> private void TryMoveFocus(FocusNavigationDirection direction) { if (direction == FocusNavigationDirection.Next || direction == FocusNavigationDirection.Previous) { FocusManager.TryMoveFocus(direction); } else { var control = FocusManager.FindNextFocusableElement(direction) as Control; if (control != null) { control.Focus(FocusState.Programmatic); } } }
/// <summary> /// Request to predict the element that should receive focus relative to this element for a /// given direction, without actually moving focus to it. /// </summary> /// <param name="direction">The direction for which focus should be predicted</param> /// <returns> /// Returns the next element that focus should move to for a given FocusNavigationDirection. /// Returns null if focus cannot be moved relative to this element. /// </returns> public virtual DependencyObject PredictFocus(FocusNavigationDirection direction) { return null; }