diff --git a/components/Segmented/src/Segmented/Segmented.cs b/components/Segmented/src/Segmented/Segmented.cs index 058bf42c..17931848 100644 --- a/components/Segmented/src/Segmented/Segmented.cs +++ b/components/Segmented/src/Segmented/Segmented.cs @@ -30,20 +30,20 @@ public Segmented() /// protected override bool IsItemItsOwnContainerOverride(object item) - { - return item is SegmentedItem; - } + => item is SegmentedItem; /// protected override void OnApplyTemplate() { base.OnApplyTemplate(); + if (!_hasLoaded) { SelectedIndex = -1; SelectedIndex = _internalSelectedIndex; _hasLoaded = true; } + PreviewKeyDown -= Segmented_PreviewKeyDown; PreviewKeyDown += Segmented_PreviewKeyDown; } @@ -52,82 +52,61 @@ protected override void OnApplyTemplate() protected override void PrepareContainerForItemOverride(DependencyObject element, object item) { base.PrepareContainerForItemOverride(element, item); + if (element is SegmentedItem segmentedItem) { - segmentedItem.Loaded += SegmentedItem_Loaded; + segmentedItem.UpdateOrientation(Orientation); } } private void Segmented_PreviewKeyDown(object sender, KeyRoutedEventArgs e) { - switch (e.Key) + var dir = e.Key switch { - case VirtualKey.Left: e.Handled = MoveFocus(MoveDirection.Previous); break; - case VirtualKey.Right: e.Handled = MoveFocus(MoveDirection.Next); break; - } - } +#if !HAS_UNO + // Invert left/right when the flow direction is right to left + VirtualKey.Left when FlowDirection is FlowDirection.RightToLeft => 1, + VirtualKey.Right when FlowDirection is FlowDirection.RightToLeft => -1, +#endif - private void SegmentedItem_Loaded(object sender, RoutedEventArgs e) - { - if (sender is SegmentedItem segmentedItem) - { - segmentedItem.Loaded -= SegmentedItem_Loaded; - } - } + // Decrement if left/up or increment if right/up + VirtualKey.Left or VirtualKey.Up => -1, + VirtualKey.Right or VirtualKey.Down => 1, - /// - protected override void OnItemsChanged(object e) - { - base.OnItemsChanged(e); - } + // Otherwise don't adjust + _ => 0, + }; - private enum MoveDirection - { - Next, - Previous + if (dir is not 0) + { + e.Handled = MoveFocus(dir); + } } /// /// Adjust the selected item and range based on keyboard input. /// This is used to override the ListView behaviors for up/down arrow manipulation vs left/right for a horizontal control /// - /// direction to move the selection + /// The signed number of indicies to shift the focus. /// True if the focus was moved, false otherwise - private bool MoveFocus(MoveDirection direction) + private bool MoveFocus(int adjustment) { - bool retVal = false; var currentContainerItem = GetCurrentContainerItem(); + if (currentContainerItem is null) + return false; - if (currentContainerItem != null) - { - var currentItem = ItemFromContainer(currentContainerItem); - var previousIndex = Items.IndexOf(currentItem); - var index = previousIndex; + var currentItem = ItemFromContainer(currentContainerItem); + var previousIndex = Items.IndexOf(currentItem); - if (direction == MoveDirection.Previous) - { - if (previousIndex > 0) - { - index -= 1; - } - } - else if (direction == MoveDirection.Next) - { - if (previousIndex < Items.Count - 1) - { - index += 1; - } - } + // Apply the adjustment, with a clamp + var index = Math.Clamp(previousIndex + adjustment, 0, Items.Count); - // Only do stuff if the index is actually changing - if (index != previousIndex && ContainerFromIndex(index) is SegmentedItem newItem) - { - newItem.Focus(FocusState.Keyboard); - retVal = true; - } - } + // Only do stuff if the index is actually changing + if (index == previousIndex || ContainerFromIndex(index) is not SegmentedItem newItem) + return false; - return retVal; + newItem.Focus(FocusState.Keyboard); + return true; } private SegmentedItem? GetCurrentContainerItem()