internal void HighlightCorrectButton(Type pageType, object pageParam) { DebugWrite($"PageType: {pageType} PageParam: {pageParam}"); // match type only var buttons = LoadedNavButtons.Where(x => Equals(x.HamburgerButtonInfo.PageType, pageType)); // serialize parameter for matching if (pageParam == null) { pageParam = NavigationService.CurrentPageParam; } else if (pageParam.ToString().StartsWith("{")) { try { pageParam = NavigationService.FrameFacade.SerializationService.Deserialize(pageParam.ToString()); } catch { } } // add parameter match buttons = buttons.Where(x => Equals(x.HamburgerButtonInfo.PageParameter, null) || Equals(x.HamburgerButtonInfo.PageParameter, pageParam)); var button = buttons.Select(x => x.HamburgerButtonInfo).FirstOrDefault(); Selected = button; }
internal void HighlightCorrectButton(Type pageType, object pageParam) { _isHighlightCorrectButtonRunning = true; try { HamburgerButtonInfo newButton = null; // match type only var buttons = LoadedNavButtons.Where(x => Equals(x.HamburgerButtonInfo.PageType, pageType)); if (buttons.Any()) { // serialize parameter for matching if (pageParam == null) { pageParam = NavigationService.CurrentPageParam; } else if (pageParam.ToString().StartsWith("{")) { try { pageParam = Services.NavigationService.Settings .SerializationStrategy.Deserialize(pageParam.ToString()); } catch { // } } // add parameter match buttons = buttons.Where(x => Equals(x.HamburgerButtonInfo.PageParameter, null) || Equals(x.HamburgerButtonInfo.PageParameter, pageParam)); newButton = buttons.OrderByDescending(x => x.HamburgerButtonInfo.PageParameter) .Select(x => x.HamburgerButtonInfo).FirstOrDefault(); } // Update selected button var oldButton = Selected; if (!ReferenceEquals(oldButton, newButton)) { Selected = newButton; if (oldButton?.ButtonType == HamburgerButtonInfo.ButtonTypes.Toggle) { oldButton.IsChecked = false; } if (newButton?.ButtonType == HamburgerButtonInfo.ButtonTypes.Toggle) { newButton.IsChecked = true; } } // Update internal binding values for both buttons oldButton?.UpdateInternalBindingValues(); newButton?.UpdateInternalBindingValues(); } finally { _isHighlightCorrectButtonRunning = false; } }
private async Task UpdateSelectedAsync(HamburgerButtonInfo previous, HamburgerButtonInfo value) { DebugWrite($"OldValue: {previous}, NewValue: {value}"); // pls. do not remove this if statement. this is the fix for #410 (click twice) if (previous != null) { IsOpen = (DisplayMode == SplitViewDisplayMode.CompactInline && IsOpen); } // signal previous if (previous != null && previous != value && previous.IsChecked.Value) { previous.IsChecked = false; previous.RaiseUnselected(); // Workaround for visual state of ToggleButton not reset correctly if (value != null) { var control = LoadedNavButtons.First(x => x.HamburgerButtonInfo == value).GetElement <Control>(); VisualStateManager.GoToState(control, "Normal", true); } } // navigate only when all navigation buttons have been loaded if (AllNavButtonsAreLoaded && value?.PageType != null) { if (await NavigationService.NavigateAsync(value.PageType, value?.PageParameter, value?.NavigationTransitionInfo)) { IsOpen = (DisplayMode == SplitViewDisplayMode.CompactInline && IsOpen); if (value.ClearHistory) { NavigationService.ClearHistory(); } if (value.ClearCache) { NavigationService.ClearCache(true); } } else if (NavigationService.CurrentPageType == value.PageType && (NavigationService.CurrentPageParam ?? string.Empty) == (value.PageParameter ?? string.Empty)) { if (value.ClearHistory) { NavigationService.ClearHistory(); } if (value.ClearCache) { NavigationService.ClearCache(true); } } else if (NavigationService.CurrentPageType == value.PageType) { // just check it } else { return; } } // that's it if null if (value == null) { return; } else { value.IsChecked = (value.ButtonType == HamburgerButtonInfo.ButtonTypes.Toggle); if (previous != value) { value.RaiseSelected(); } } }
// handle keyboard navigation (tabs and gamepad) private void HamburgerMenu_KeyDown(object sender, KeyRoutedEventArgs e) { var currentItem = FocusManager.GetFocusedElement() as FrameworkElement; var lastItem = LoadedNavButtons.FirstOrDefault(x => x.HamburgerButtonInfo == (SecondaryButtons.LastOrDefault(a => a != Selected) ?? PrimaryButtons.LastOrDefault(a => a != Selected))); var focus = new Func <FocusNavigationDirection, bool>(d => { if (d == FocusNavigationDirection.Next) { return(FocusManager.TryMoveFocus(d)); } else if (d == FocusNavigationDirection.Previous) { return(FocusManager.TryMoveFocus(d)); } else { var control = FocusManager.FindNextFocusableElement(d) as Control; return(control?.Focus(FocusState.Programmatic) ?? false); } }); var escape = new Func <bool>(() => { if (DisplayMode == SplitViewDisplayMode.CompactOverlay || DisplayMode == SplitViewDisplayMode.Overlay) { IsOpen = false; } if (Equals(ShellSplitView.PanePlacement, SplitViewPanePlacement.Left)) { ShellSplitView.Content.RenderTransform = new TranslateTransform { X = 48 + ShellSplitView.OpenPaneLength }; focus(FocusNavigationDirection.Right); ShellSplitView.Content.RenderTransform = null; } else { ShellSplitView.Content.RenderTransform = new TranslateTransform { X = -48 - ShellSplitView.OpenPaneLength }; focus(FocusNavigationDirection.Left); ShellSplitView.Content.RenderTransform = null; } return(true); }); var previous = new Func <bool>(() => { if (Equals(currentItem, HamburgerButton)) { return(true); } else if (focus(FocusNavigationDirection.Previous) || focus(FocusNavigationDirection.Up)) { return(true); } else { return(escape()); } }); var next = new Func <bool>(() => { if (Equals(currentItem, HamburgerButton)) { return(focus(FocusNavigationDirection.Down)); } else if (focus(FocusNavigationDirection.Next) || focus(FocusNavigationDirection.Down)) { return(true); } else { return(escape()); } }); if (IsFullScreen) { return; } switch (e.Key) { case VirtualKey.Up: case VirtualKey.GamepadDPadUp: if (!(e.Handled = previous())) { Debugger.Break(); } break; case VirtualKey.Down: case VirtualKey.GamepadDPadDown: if (!(e.Handled = next())) { Debugger.Break(); } break; case VirtualKey.Right: case VirtualKey.GamepadDPadRight: if (SecondaryButtonContainer.Items.Contains(currentItem?.DataContext) && SecondaryButtonOrientation == Orientation.Horizontal) { if (Equals(lastItem.FrameworkElement, currentItem)) { if (!(e.Handled = escape())) { Debugger.Break(); } } else { if (!(e.Handled = next())) { Debugger.Break(); } } } else { if (!(e.Handled = escape())) { Debugger.Break(); } } break; case VirtualKey.Left: case VirtualKey.GamepadDPadLeft: if (SecondaryButtonContainer.Items.Contains(currentItem?.DataContext) && SecondaryButtonOrientation == Orientation.Horizontal) { if (Equals(lastItem.FrameworkElement, currentItem)) { if (!(e.Handled = escape())) { Debugger.Break(); } } else { if (!(e.Handled = previous())) { Debugger.Break(); } } } else { if (!(e.Handled = escape())) { Debugger.Break(); } } break; case VirtualKey.Space: case VirtualKey.Enter: case VirtualKey.GamepadA: if (currentItem != null) { var info = new InfoElement(currentItem); var hamburgerButtonInfo = info.HamburgerButtonInfo; if (hamburgerButtonInfo != null) { NavCommand.Execute(hamburgerButtonInfo); } } break; case VirtualKey.Escape: case VirtualKey.GamepadB: if (!(e.Handled = escape())) { Debugger.Break(); } break; } }
private async Task UpdateSelectedAsync(HamburgerButtonInfo previous, HamburgerButtonInfo current) { // pls. do not remove this if statement. this is the fix for #410 (click twice) if (previous != null) { IsOpen = (DisplayMode == SplitViewDisplayMode.CompactInline && IsOpen); } // signal previous if (previous != null && previous != current && previous.IsChecked.Value) { // Workaround for visual state of ToggleButton not reset correctly if (current != null) { var control = LoadedNavButtons.First(x => x.HamburgerButtonInfo == current).GetElement <Control>(); VisualStateManager.GoToState(control, "Normal", true); } } // navigate only when all navigation buttons have been loaded if (AllNavButtonsAreLoaded && current?.PageType != null) { if (await NavigationService.NavigateAsync(current.PageType, current?.PageParameter, current?.NavigationTransitionInfo)) { SignalPreviousPage(previous, current); SignalCurrentPage(previous, current); IsOpen = (DisplayMode == SplitViewDisplayMode.CompactInline && IsOpen); if (current.ClearHistory) { NavigationService.ClearHistory(); } if (current.ClearCache) { var frameState = await(NavigationService.FrameFacade as ITemplate10FrameInternal).GetFrameStateAsync(); await frameState.ClearAsync(); } } else if (NavigationService.CurrentPageType == current.PageType && (NavigationService.CurrentPageParam ?? string.Empty) == (current.PageParameter ?? string.Empty)) { SignalPreviousPage(previous, current); SignalCurrentPage(previous, current); if (current.ClearHistory) { NavigationService.ClearHistory(); } if (current.ClearCache) { var frameState = await(NavigationService.FrameFacade as ITemplate10FrameInternal).GetFrameStateAsync(); await frameState.ClearAsync(); } } else if (previous == null || NavigationService.CurrentPageType == current.PageType) { SignalCurrentPage(previous, current); } else { // Re-instate Selected to previous page, but avoid calling this method (UpdateSelectedAsync) all over // again, and we use a flag to effect this. See InternalSelectedChanged() method where it's used. _isUpdateSelectedRunning = true; try { Selected = previous; } finally { _isUpdateSelectedRunning = false; } current.IsChecked = false; current.RaiseUnselected(); return; } } else { SignalPreviousPage(previous, current); SignalCurrentPage(previous, current); } }
public void RefreshStyles(Color?color = null, bool clearExisting = false) { DebugWrite($"Color: {color}"); if (color == null) { color = AccentColor; } if (color == default(Color)) { return; } // since every brush will be based on one color, // we will do so with theme in mind. if (clearExisting) { ClearExisting(); } switch (RequestedTheme) { case ElementTheme.Light: { this.SetIfNotSet(NavAreaBackgroundProperty, Colors.DimGray.ToSolidColorBrush()); this.SetIfNotSet(SecondarySeparatorProperty, Colors.DarkGray.ToSolidColorBrush()); this.SetIfNotSet(PaneBorderBrushProperty, Colors.Transparent.ToSolidColorBrush()); this.SetIfNotSet(PaneBorderThicknessProperty, new Thickness(0)); this.SetIfNotSet(HamburgerForegroundProperty, Colors.White.ToSolidColorBrush()); this.SetIfNotSet(HamburgerBackgroundProperty, color?.ToSolidColorBrush()); this.SetIfNotSet(NavButtonForegroundProperty, Colors.White.Darken(ColorUtils.Add._20p).ToSolidColorBrush()); this.SetIfNotSet(NavButtonBackgroundProperty, Colors.Transparent.ToSolidColorBrush()); this.SetIfNotSet(NavButtonCheckedForegroundProperty, Colors.White.ToSolidColorBrush()); this.SetIfNotSet(NavButtonCheckedBackgroundProperty, Colors.Transparent.ToSolidColorBrush()); this.SetIfNotSet(NavButtonCheckedIndicatorBrushProperty, Colors.White.ToSolidColorBrush()); this.SetIfNotSet(NavButtonPressedForegroundProperty, Colors.White.Darken(ColorUtils.Add._30p).ToSolidColorBrush()); this.SetIfNotSet(NavButtonPressedBackgroundProperty, Colors.Transparent.ToSolidColorBrush()); this.SetIfNotSet(NavButtonHoverForegroundProperty, Colors.White.Darken(ColorUtils.Add._10p).ToSolidColorBrush()); this.SetIfNotSet(NavButtonHoverBackgroundProperty, Colors.Transparent.ToSolidColorBrush()); break; } case ElementTheme.Default: case ElementTheme.Dark: { this.SetIfNotSet(NavAreaBackgroundProperty, Colors.Gainsboro.Darken(ColorUtils.Add._80p).ToSolidColorBrush()); this.SetIfNotSet(SecondarySeparatorProperty, Colors.DimGray.ToSolidColorBrush()); this.SetIfNotSet(PaneBorderBrushProperty, Colors.Transparent.ToSolidColorBrush()); this.SetIfNotSet(PaneBorderThicknessProperty, new Thickness(0)); this.SetIfNotSet(HamburgerForegroundProperty, Colors.White.ToSolidColorBrush()); this.SetIfNotSet(HamburgerBackgroundProperty, color?.ToSolidColorBrush()); this.SetIfNotSet(NavButtonForegroundProperty, Colors.White.Darken(ColorUtils.Add._20p).ToSolidColorBrush()); this.SetIfNotSet(NavButtonBackgroundProperty, Colors.Transparent.ToSolidColorBrush()); this.SetIfNotSet(NavButtonCheckedForegroundProperty, Colors.White.ToSolidColorBrush()); this.SetIfNotSet(NavButtonCheckedBackgroundProperty, Colors.Transparent.ToSolidColorBrush()); this.SetIfNotSet(NavButtonCheckedIndicatorBrushProperty, Colors.White.ToSolidColorBrush()); this.SetIfNotSet(NavButtonPressedForegroundProperty, Colors.White.Darken(ColorUtils.Add._30p).ToSolidColorBrush()); this.SetIfNotSet(NavButtonPressedBackgroundProperty, Colors.Transparent.ToSolidColorBrush()); this.SetIfNotSet(NavButtonHoverForegroundProperty, Colors.White.Darken(ColorUtils.Add._10p).ToSolidColorBrush()); this.SetIfNotSet(NavButtonHoverBackgroundProperty, Colors.Transparent.ToSolidColorBrush()); break; } } // ensure LoadedNavButtons.ForEach(x => x.RefreshVisualState()); }
async Task SetSelectedAsync(HamburgerButtonInfo previous, HamburgerButtonInfo value) { DebugWrite($"OldValue: {previous}, NewValue: {value}"); // pls. do not remove this if statement. this is the fix for #410 (click twice) if (previous != null) { IsOpen = (DisplayMode == SplitViewDisplayMode.CompactInline && IsOpen); } // signal previous if (previous?.IsChecked ?? true && previous != value) { previous?.RaiseUnselected(); } // reset all, except selected var buttons = LoadedNavButtons.Where(x => x.Value != value); buttons.ForEach(x => x.Value.IsChecked = false); // navigate only when all navigation buttons have been loaded if (AllNavButtonsAreLoaded && value?.PageType != null) { if (await NavigationService.NavigateAsync(value.PageType, value?.PageParameter, value?.NavigationTransitionInfo)) { IsOpen = (DisplayMode == SplitViewDisplayMode.CompactInline && IsOpen); if (value.ClearHistory) { NavigationService.ClearHistory(); } } else if (NavigationService.CurrentPageType == value.PageType && (NavigationService.CurrentPageParam ?? string.Empty) == (value.PageParameter ?? string.Empty)) { if (value.ClearHistory) { NavigationService.ClearHistory(); } } else if (NavigationService.CurrentPageType == value.PageType) { // just check it } else { return; } } // that's it if null if (value == null) { return; } else { value.IsChecked = (value.ButtonType == HamburgerButtonInfo.ButtonTypes.Toggle); if (previous != value) { value.RaiseSelected(); } } }