diff --git a/source/iNKORE.UI.WPF.Modern.Controls/Controls/Windows/NavigationView/NavigationView.cs b/source/iNKORE.UI.WPF.Modern.Controls/Controls/Windows/NavigationView/NavigationView.cs index f938961e..a54432d0 100644 --- a/source/iNKORE.UI.WPF.Modern.Controls/Controls/Windows/NavigationView/NavigationView.cs +++ b/source/iNKORE.UI.WPF.Modern.Controls/Controls/Windows/NavigationView/NavigationView.cs @@ -433,336 +433,344 @@ public override void OnApplyTemplate() // Stop update anything because of PropertyChange during OnApplyTemplate. Update them all together at the end of this function m_appliedTemplate = false; + m_fromOnApplyTemplate = true; - UnhookEventsAndClearFields(); - - IControlProtected controlProtected = this; - - // Set up the pane toggle button click handler - if (GetTemplateChild(c_togglePaneButtonName) is Button paneToggleButton) + try { - m_paneToggleButton = paneToggleButton; - paneToggleButton.Click += OnPaneToggleButtonClick; + UnhookEventsAndClearFields(); - SetPaneToggleButtonAutomationName(); + IControlProtected controlProtected = this; - // TODO: WPF - KeyboardAccelerator - /* - if (SharedHelpers::IsRS3OrHigher()) + // Set up the pane toggle button click handler + if (GetTemplateChild(c_togglePaneButtonName) is Button paneToggleButton) { - winrt::KeyboardAccelerator keyboardAccelerator; - keyboardAccelerator.Key(winrt::VirtualKey::Back); - keyboardAccelerator.Modifiers(winrt::VirtualKeyModifiers::Windows); - paneToggleButton.KeyboardAccelerators().Append(keyboardAccelerator); - } - */ - - WindowChrome.SetIsHitTestVisibleInChrome(paneToggleButton, true); - } + m_paneToggleButton = paneToggleButton; + paneToggleButton.Click += OnPaneToggleButtonClick; - m_leftNavPaneHeaderContentBorder = GetTemplateChild(c_leftNavPaneHeaderContentBorder) as ContentControl; - m_leftNavPaneCustomContentBorder = GetTemplateChild(c_leftNavPaneCustomContentBorder) as ContentControl; - m_leftNavFooterContentBorder = GetTemplateChild(c_leftNavFooterContentBorder) as ContentControl; - m_paneHeaderOnTopPane = GetTemplateChild(c_paneHeaderOnTopPane) as ContentControl; - m_paneTitleOnTopPane = GetTemplateChild(c_paneTitleOnTopPane) as ContentControl; - m_paneCustomContentOnTopPane = GetTemplateChild(c_paneCustomContentOnTopPane) as ContentControl; - m_paneFooterOnTopPane = GetTemplateChild(c_paneFooterOnTopPane) as ContentControl; + SetPaneToggleButtonAutomationName(); - // Get a pointer to the root SplitView - if (GetTemplateChild(c_rootSplitViewName) is SplitView splitView) - { - m_rootSplitView = splitView; - splitView.IsPaneOpenChanged += OnSplitViewClosedCompactChanged; - splitView.DisplayModeChanged += OnSplitViewClosedCompactChanged; + // TODO: WPF - KeyboardAccelerator + /* + if (SharedHelpers::IsRS3OrHigher()) + { + winrt::KeyboardAccelerator keyboardAccelerator; + keyboardAccelerator.Key(winrt::VirtualKey::Back); + keyboardAccelerator.Modifiers(winrt::VirtualKeyModifiers::Windows); + paneToggleButton.KeyboardAccelerators().Append(keyboardAccelerator); + } + */ - if (SharedHelpers.IsRS3OrHigher()) // These events are new to RS3/v5 API - { - splitView.PaneClosed += OnSplitViewPaneClosed; - splitView.PaneClosing += OnSplitViewPaneClosing; - splitView.PaneOpened += OnSplitViewPaneOpened; - splitView.PaneOpening += OnSplitViewPaneOpening; + WindowChrome.SetIsHitTestVisibleInChrome(paneToggleButton, true); } - UpdateIsClosedCompact(); - } + m_leftNavPaneHeaderContentBorder = GetTemplateChild(c_leftNavPaneHeaderContentBorder) as ContentControl; + m_leftNavPaneCustomContentBorder = GetTemplateChild(c_leftNavPaneCustomContentBorder) as ContentControl; + m_leftNavFooterContentBorder = GetTemplateChild(c_leftNavFooterContentBorder) as ContentControl; + m_paneHeaderOnTopPane = GetTemplateChild(c_paneHeaderOnTopPane) as ContentControl; + m_paneTitleOnTopPane = GetTemplateChild(c_paneTitleOnTopPane) as ContentControl; + m_paneCustomContentOnTopPane = GetTemplateChild(c_paneCustomContentOnTopPane) as ContentControl; + m_paneFooterOnTopPane = GetTemplateChild(c_paneFooterOnTopPane) as ContentControl; - m_topNavGrid = GetTemplateChild(c_topNavGrid) as Grid; + // Get a pointer to the root SplitView + if (GetTemplateChild(c_rootSplitViewName) is SplitView splitView) + { + m_rootSplitView = splitView; + splitView.IsPaneOpenChanged += OnSplitViewClosedCompactChanged; + splitView.DisplayModeChanged += OnSplitViewClosedCompactChanged; - // Change code to NOT do this if we're in top nav mode, to prevent it from being realized: - if (GetTemplateChild(c_menuItemsHost) is ItemsRepeater leftNavRepeater) - { - m_leftNavRepeater = leftNavRepeater; + if (SharedHelpers.IsRS3OrHigher()) // These events are new to RS3/v5 API + { + splitView.PaneClosed += OnSplitViewPaneClosed; + splitView.PaneClosing += OnSplitViewPaneClosing; + splitView.PaneOpened += OnSplitViewPaneOpened; + splitView.PaneOpening += OnSplitViewPaneOpening; + } - // API is currently in preview, so setting this via code. - // Disabling virtualization for now because of https://github.com/microsoft/microsoft-ui-xaml/issues/2095 - if (leftNavRepeater.Layout is StackLayout stackLayout) - { - var stackLayoutImpl = stackLayout; - stackLayoutImpl.DisableVirtualization = true; + UpdateIsClosedCompact(); } - leftNavRepeater.ElementPrepared += OnRepeaterElementPrepared; - leftNavRepeater.ElementClearing += OnRepeaterElementClearing; + m_topNavGrid = GetTemplateChild(c_topNavGrid) as Grid; - leftNavRepeater.IsVisibleChanged += OnRepeaterIsVisibleChanged; + // Change code to NOT do this if we're in top nav mode, to prevent it from being realized: + if (GetTemplateChild(c_menuItemsHost) is ItemsRepeater leftNavRepeater) + { + m_leftNavRepeater = leftNavRepeater; - m_leftNavRepeaterGettingFocusHelper = new GettingFocusHelper(leftNavRepeater); - m_leftNavRepeaterGettingFocusHelper.GettingFocus += OnRepeaterGettingFocus; + // API is currently in preview, so setting this via code. + // Disabling virtualization for now because of https://github.com/microsoft/microsoft-ui-xaml/issues/2095 + if (leftNavRepeater.Layout is StackLayout stackLayout) + { + var stackLayoutImpl = stackLayout; + stackLayoutImpl.DisableVirtualization = true; + } - leftNavRepeater.ItemTemplate = m_navigationViewItemsFactory; - } + leftNavRepeater.ElementPrepared += OnRepeaterElementPrepared; + leftNavRepeater.ElementClearing += OnRepeaterElementClearing; - // Change code to NOT do this if we're in left nav mode, to prevent it from being realized: - if (GetTemplateChild(c_topNavMenuItemsHost) is ItemsRepeater topNavRepeater) - { - m_topNavRepeater = topNavRepeater; + leftNavRepeater.IsVisibleChanged += OnRepeaterIsVisibleChanged; - // API is currently in preview, so setting this via code - if (topNavRepeater.Layout is StackLayout stackLayout) - { - var stackLayoutImpl = stackLayout; - stackLayoutImpl.DisableVirtualization = true; + m_leftNavRepeaterGettingFocusHelper = new GettingFocusHelper(leftNavRepeater); + m_leftNavRepeaterGettingFocusHelper.GettingFocus += OnRepeaterGettingFocus; + + leftNavRepeater.ItemTemplate = m_navigationViewItemsFactory; } - topNavRepeater.ElementPrepared += OnRepeaterElementPrepared; - topNavRepeater.ElementClearing += OnRepeaterElementClearing; + // Change code to NOT do this if we're in left nav mode, to prevent it from being realized: + if (GetTemplateChild(c_topNavMenuItemsHost) is ItemsRepeater topNavRepeater) + { + m_topNavRepeater = topNavRepeater; - topNavRepeater.IsVisibleChanged += OnRepeaterIsVisibleChanged; + // API is currently in preview, so setting this via code + if (topNavRepeater.Layout is StackLayout stackLayout) + { + var stackLayoutImpl = stackLayout; + stackLayoutImpl.DisableVirtualization = true; + } - m_topNavRepeaterGettingFocusHelper = new GettingFocusHelper(topNavRepeater); - m_topNavRepeaterGettingFocusHelper.GettingFocus += OnRepeaterGettingFocus; + topNavRepeater.ElementPrepared += OnRepeaterElementPrepared; + topNavRepeater.ElementClearing += OnRepeaterElementClearing; - topNavRepeater.ItemTemplate = m_navigationViewItemsFactory; - } + topNavRepeater.IsVisibleChanged += OnRepeaterIsVisibleChanged; - // Change code to NOT do this if we're in left nav mode, to prevent it from being realized: - if (GetTemplateChild(c_topNavMenuItemsOverflowHost) is ItemsRepeater topNavListOverflowRepeater) - { - m_topNavRepeaterOverflowView = topNavListOverflowRepeater; + m_topNavRepeaterGettingFocusHelper = new GettingFocusHelper(topNavRepeater); + m_topNavRepeaterGettingFocusHelper.GettingFocus += OnRepeaterGettingFocus; - // API is currently in preview, so setting this via code. - // Disabling virtualization for now because of https://github.com/microsoft/microsoft-ui-xaml/issues/2095 - if (topNavListOverflowRepeater.Layout is StackLayout stackLayout) - { - var stackLayoutImpl = stackLayout; - stackLayoutImpl.DisableVirtualization = true; + topNavRepeater.ItemTemplate = m_navigationViewItemsFactory; } - topNavListOverflowRepeater.ElementPrepared += OnRepeaterElementPrepared; - topNavListOverflowRepeater.ElementClearing += OnRepeaterElementClearing; + // Change code to NOT do this if we're in left nav mode, to prevent it from being realized: + if (GetTemplateChild(c_topNavMenuItemsOverflowHost) is ItemsRepeater topNavListOverflowRepeater) + { + m_topNavRepeaterOverflowView = topNavListOverflowRepeater; - topNavListOverflowRepeater.ItemTemplate = m_navigationViewItemsFactory; - } + // API is currently in preview, so setting this via code. + // Disabling virtualization for now because of https://github.com/microsoft/microsoft-ui-xaml/issues/2095 + if (topNavListOverflowRepeater.Layout is StackLayout stackLayout) + { + var stackLayoutImpl = stackLayout; + stackLayoutImpl.DisableVirtualization = true; + } - if (GetTemplateChild(c_topNavOverflowButton) is Button topNavOverflowButton) - { - m_topNavOverflowButton = topNavOverflowButton; - AutomationProperties.SetName(topNavOverflowButton, ResourceAccessor.GetLocalizedStringResource(SR_NavigationOverflowButtonName)); - topNavOverflowButton.Content = ResourceAccessor.GetLocalizedStringResource(SR_NavigationOverflowButtonText); - // TODO: WPF - Header Animation - /* - auto visual = winrt::ElementCompositionPreview::GetElementVisual(topNavOverflowButton); - CreateAndAttachHeaderAnimation(visual); - */ + topNavListOverflowRepeater.ElementPrepared += OnRepeaterElementPrepared; + topNavListOverflowRepeater.ElementClearing += OnRepeaterElementClearing; - var toolTip = ToolTipService.GetToolTip(topNavOverflowButton); - if (toolTip is null) - { - var tooltip = new ToolTip(); - tooltip.Content = ResourceAccessor.GetLocalizedStringResource(SR_NavigationOverflowButtonToolTip); - ToolTipService.SetToolTip(topNavOverflowButton, tooltip); + topNavListOverflowRepeater.ItemTemplate = m_navigationViewItemsFactory; } - if (FlyoutService.GetFlyout(topNavOverflowButton) is { } flyoutBase) + if (GetTemplateChild(c_topNavOverflowButton) is Button topNavOverflowButton) { + m_topNavOverflowButton = topNavOverflowButton; + AutomationProperties.SetName(topNavOverflowButton, ResourceAccessor.GetLocalizedStringResource(SR_NavigationOverflowButtonName)); + topNavOverflowButton.Content = ResourceAccessor.GetLocalizedStringResource(SR_NavigationOverflowButtonText); + // TODO: WPF - Header Animation /* - if (winrt::IFlyoutBase6 topNavOverflowButtonAsFlyoutBase6 = flyoutBase) + auto visual = winrt::ElementCompositionPreview::GetElementVisual(topNavOverflowButton); + CreateAndAttachHeaderAnimation(visual); + */ + + var toolTip = ToolTipService.GetToolTip(topNavOverflowButton); + if (toolTip is null) { - topNavOverflowButtonAsFlyoutBase6.ShouldConstrainToRootBounds(false); + var tooltip = new ToolTip(); + tooltip.Content = ResourceAccessor.GetLocalizedStringResource(SR_NavigationOverflowButtonToolTip); + ToolTipService.SetToolTip(topNavOverflowButton, tooltip); } - */ - flyoutBase.Closing += OnFlyoutClosing; - flyoutBase.Offset = 0; - } - } - // Change code to NOT do this if we're in top nav mode, to prevent it from being realized: - if (GetTemplateChildT(c_footerMenuItemsHost, controlProtected) is { } leftFooterMenuNavRepeater) - { - m_leftNavFooterMenuRepeater = leftFooterMenuNavRepeater; + if (FlyoutService.GetFlyout(topNavOverflowButton) is { } flyoutBase) + { + /* + if (winrt::IFlyoutBase6 topNavOverflowButtonAsFlyoutBase6 = flyoutBase) + { + topNavOverflowButtonAsFlyoutBase6.ShouldConstrainToRootBounds(false); + } + */ + flyoutBase.Closing += OnFlyoutClosing; + flyoutBase.Offset = 0; + } + } - // API is currently in preview, so setting this via code. - // Disabling virtualization for now because of https://github.com/microsoft/microsoft-ui-xaml/issues/2095 - if (leftFooterMenuNavRepeater.Layout is StackLayout stackLayout) + // Change code to NOT do this if we're in top nav mode, to prevent it from being realized: + if (GetTemplateChildT(c_footerMenuItemsHost, controlProtected) is { } leftFooterMenuNavRepeater) { - var stackLayoutImpl = stackLayout; - stackLayoutImpl.DisableVirtualization = true; - } + m_leftNavFooterMenuRepeater = leftFooterMenuNavRepeater; - leftFooterMenuNavRepeater.ElementPrepared += OnRepeaterElementPrepared; - leftFooterMenuNavRepeater.ElementClearing += OnRepeaterElementClearing; + // API is currently in preview, so setting this via code. + // Disabling virtualization for now because of https://github.com/microsoft/microsoft-ui-xaml/issues/2095 + if (leftFooterMenuNavRepeater.Layout is StackLayout stackLayout) + { + var stackLayoutImpl = stackLayout; + stackLayoutImpl.DisableVirtualization = true; + } - leftFooterMenuNavRepeater.IsVisibleChanged += OnRepeaterIsVisibleChanged; + leftFooterMenuNavRepeater.ElementPrepared += OnRepeaterElementPrepared; + leftFooterMenuNavRepeater.ElementClearing += OnRepeaterElementClearing; - m_leftNavFooterMenuRepeaterGettingFocusHelper = new GettingFocusHelper(leftFooterMenuNavRepeater); - m_leftNavFooterMenuRepeaterGettingFocusHelper.GettingFocus += OnRepeaterGettingFocus; + leftFooterMenuNavRepeater.IsVisibleChanged += OnRepeaterIsVisibleChanged; - leftFooterMenuNavRepeater.ItemTemplate = m_navigationViewItemsFactory; - } + m_leftNavFooterMenuRepeaterGettingFocusHelper = new GettingFocusHelper(leftFooterMenuNavRepeater); + m_leftNavFooterMenuRepeaterGettingFocusHelper.GettingFocus += OnRepeaterGettingFocus; - // Change code to NOT do this if we're in left nav mode, to prevent it from being realized: - if (GetTemplateChildT(c_topNavFooterMenuItemsHost, controlProtected) is { } topFooterMenuNavRepeater) - { - m_topNavFooterMenuRepeater = topFooterMenuNavRepeater; + leftFooterMenuNavRepeater.ItemTemplate = m_navigationViewItemsFactory; + } - // API is currently in preview, so setting this via code. - // Disabling virtualization for now because of https://github.com/microsoft/microsoft-ui-xaml/issues/2095 - if (topFooterMenuNavRepeater.Layout is StackLayout stackLayout) + // Change code to NOT do this if we're in left nav mode, to prevent it from being realized: + if (GetTemplateChildT(c_topNavFooterMenuItemsHost, controlProtected) is { } topFooterMenuNavRepeater) { - var stackLayoutImpl = stackLayout; - stackLayoutImpl.DisableVirtualization = true; - } + m_topNavFooterMenuRepeater = topFooterMenuNavRepeater; - topFooterMenuNavRepeater.ElementPrepared += OnRepeaterElementPrepared; - topFooterMenuNavRepeater.ElementClearing += OnRepeaterElementClearing; + // API is currently in preview, so setting this via code. + // Disabling virtualization for now because of https://github.com/microsoft/microsoft-ui-xaml/issues/2095 + if (topFooterMenuNavRepeater.Layout is StackLayout stackLayout) + { + var stackLayoutImpl = stackLayout; + stackLayoutImpl.DisableVirtualization = true; + } - topFooterMenuNavRepeater.IsVisibleChanged += OnRepeaterIsVisibleChanged; + topFooterMenuNavRepeater.ElementPrepared += OnRepeaterElementPrepared; + topFooterMenuNavRepeater.ElementClearing += OnRepeaterElementClearing; - m_topNavFooterMenuRepeaterGettingFocusHelper = new GettingFocusHelper(topFooterMenuNavRepeater); - m_topNavFooterMenuRepeaterGettingFocusHelper.GettingFocus += OnRepeaterGettingFocus; + topFooterMenuNavRepeater.IsVisibleChanged += OnRepeaterIsVisibleChanged; - topFooterMenuNavRepeater.ItemTemplate = m_navigationViewItemsFactory; - } + m_topNavFooterMenuRepeaterGettingFocusHelper = new GettingFocusHelper(topFooterMenuNavRepeater); + m_topNavFooterMenuRepeaterGettingFocusHelper.GettingFocus += OnRepeaterGettingFocus; - m_topNavContentOverlayAreaGrid = GetTemplateChild(c_topNavContentOverlayAreaGrid) as Border; - m_leftNavPaneAutoSuggestBoxPresenter = GetTemplateChild(c_leftNavPaneAutoSuggestBoxPresenter) as ContentControl; - m_topNavPaneAutoSuggestBoxPresenter = GetTemplateChild(c_topNavPaneAutoSuggestBoxPresenter) as ContentControl; + topFooterMenuNavRepeater.ItemTemplate = m_navigationViewItemsFactory; + } - // Get pointer to the pane content area, for use in the selection indicator animation - m_paneContentGrid = GetTemplateChild(c_paneContentGridName) as UIElement; + m_topNavContentOverlayAreaGrid = GetTemplateChild(c_topNavContentOverlayAreaGrid) as Border; + m_leftNavPaneAutoSuggestBoxPresenter = GetTemplateChild(c_leftNavPaneAutoSuggestBoxPresenter) as ContentControl; + m_topNavPaneAutoSuggestBoxPresenter = GetTemplateChild(c_topNavPaneAutoSuggestBoxPresenter) as ContentControl; - m_contentLeftPadding = GetTemplateChild(c_contentLeftPadding) as FrameworkElement; + // Get pointer to the pane content area, for use in the selection indicator animation + m_paneContentGrid = GetTemplateChild(c_paneContentGridName) as UIElement; - m_paneHeaderCloseButtonColumn = GetTemplateChild(c_paneHeaderCloseButtonColumn) as ColumnDefinition; - m_paneHeaderToggleButtonColumn = GetTemplateChild(c_paneHeaderToggleButtonColumn) as ColumnDefinition; - m_paneHeaderContentBorderRow = GetTemplateChild(c_paneHeaderContentBorderRow) as RowDefinition; - m_paneTitleFrameworkElement = GetTemplateChild(c_paneTitleFrameworkElement) as FrameworkElement; - m_paneTitlePresenter = GetTemplateChild(c_paneTitlePresenter) as ContentControl; + m_contentLeftPadding = GetTemplateChild(c_contentLeftPadding) as FrameworkElement; - if (GetTemplateChild(c_paneTitleHolderFrameworkElement) is FrameworkElement paneTitleHolderFrameworkElement) - { - m_paneTitleHolderFrameworkElement = paneTitleHolderFrameworkElement; - paneTitleHolderFrameworkElement.SizeChanged += OnPaneTitleHolderSizeChanged; - } + m_paneHeaderCloseButtonColumn = GetTemplateChild(c_paneHeaderCloseButtonColumn) as ColumnDefinition; + m_paneHeaderToggleButtonColumn = GetTemplateChild(c_paneHeaderToggleButtonColumn) as ColumnDefinition; + m_paneHeaderContentBorderRow = GetTemplateChild(c_paneHeaderContentBorderRow) as RowDefinition; + m_paneTitleFrameworkElement = GetTemplateChild(c_paneTitleFrameworkElement) as FrameworkElement; + m_paneTitlePresenter = GetTemplateChild(c_paneTitlePresenter) as ContentControl; - // Set automation name on search button - if (GetTemplateChild(c_searchButtonName) is Button button) - { - m_paneSearchButton = button; - button.Click += OnPaneSearchButtonClick; + if (GetTemplateChild(c_paneTitleHolderFrameworkElement) is FrameworkElement paneTitleHolderFrameworkElement) + { + m_paneTitleHolderFrameworkElement = paneTitleHolderFrameworkElement; + paneTitleHolderFrameworkElement.SizeChanged += OnPaneTitleHolderSizeChanged; + } - var searchButtonName = ResourceAccessor.GetLocalizedStringResource(SR_NavigationViewSearchButtonName); - AutomationProperties.SetName(button, searchButtonName); - var toolTip = new ToolTip(); - toolTip.Content = searchButtonName; - ToolTipService.SetToolTip(button, toolTip); - } + // Set automation name on search button + if (GetTemplateChild(c_searchButtonName) is Button button) + { + m_paneSearchButton = button; + button.Click += OnPaneSearchButtonClick; - if (GetTemplateChild(c_navViewBackButton) is Button backButton) - { - m_backButton = backButton; - backButton.Click += OnBackButtonClicked; + var searchButtonName = ResourceAccessor.GetLocalizedStringResource(SR_NavigationViewSearchButtonName); + AutomationProperties.SetName(button, searchButtonName); + var toolTip = new ToolTip(); + toolTip.Content = searchButtonName; + ToolTipService.SetToolTip(button, toolTip); + } - string navigationName = ResourceAccessor.GetLocalizedStringResource(SR_NavigationBackButtonName); - AutomationProperties.SetName(backButton, navigationName); + if (GetTemplateChild(c_navViewBackButton) is Button backButton) + { + m_backButton = backButton; + backButton.Click += OnBackButtonClicked; - WindowChrome.SetIsHitTestVisibleInChrome(backButton, true); - } + string navigationName = ResourceAccessor.GetLocalizedStringResource(SR_NavigationBackButtonName); + AutomationProperties.SetName(backButton, navigationName); - // Register for changes in title bar layout - if (CoreApplicationViewTitleBar.GetTitleBar(this) is { } coreTitleBar) - { - m_coreTitleBar = coreTitleBar; - coreTitleBar.LayoutMetricsChanged += OnTitleBarMetricsChanged; - coreTitleBar.IsVisibleChanged += OnTitleBarIsVisibleChanged; + WindowChrome.SetIsHitTestVisibleInChrome(backButton, true); + } - if (ShouldPreserveNavigationViewRS4Behavior()) + // Register for changes in title bar layout + if (CoreApplicationViewTitleBar.GetTitleBar(this) is { } coreTitleBar) { - m_togglePaneTopPadding = GetTemplateChild(c_togglePaneTopPadding) as FrameworkElement; - m_contentPaneTopPadding = GetTemplateChild(c_contentPaneTopPadding) as FrameworkElement; - } - } + m_coreTitleBar = coreTitleBar; + coreTitleBar.LayoutMetricsChanged += OnTitleBarMetricsChanged; + coreTitleBar.IsVisibleChanged += OnTitleBarIsVisibleChanged; - if (GetTemplateChild(c_navViewBackButtonToolTip) is ToolTip backButtonToolTip) - { - string navigationBackButtonToolTip = ResourceAccessor.GetLocalizedStringResource(SR_NavigationBackButtonToolTip); - backButtonToolTip.Content = navigationBackButtonToolTip; - } + if (ShouldPreserveNavigationViewRS4Behavior()) + { + m_togglePaneTopPadding = GetTemplateChild(c_togglePaneTopPadding) as FrameworkElement; + m_contentPaneTopPadding = GetTemplateChild(c_contentPaneTopPadding) as FrameworkElement; + } + } - if (GetTemplateChild(c_navViewCloseButton) is Button closeButton) - { - m_closeButton = closeButton; - closeButton.Click += OnPaneToggleButtonClick; + if (GetTemplateChild(c_navViewBackButtonToolTip) is ToolTip backButtonToolTip) + { + string navigationBackButtonToolTip = ResourceAccessor.GetLocalizedStringResource(SR_NavigationBackButtonToolTip); + backButtonToolTip.Content = navigationBackButtonToolTip; + } - string navigationName = ResourceAccessor.GetLocalizedStringResource(SR_NavigationCloseButtonName); - AutomationProperties.SetName(closeButton, navigationName); + if (GetTemplateChild(c_navViewCloseButton) is Button closeButton) + { + m_closeButton = closeButton; + closeButton.Click += OnPaneToggleButtonClick; - WindowChrome.SetIsHitTestVisibleInChrome(closeButton, true); - } + string navigationName = ResourceAccessor.GetLocalizedStringResource(SR_NavigationCloseButtonName); + AutomationProperties.SetName(closeButton, navigationName); - if (GetTemplateChild(c_navViewCloseButtonToolTip) is ToolTip closeButtonToolTip) - { - string navigationCloseButtonToolTip = ResourceAccessor.GetLocalizedStringResource(SR_NavigationButtonOpenName); - closeButtonToolTip.Content = navigationCloseButtonToolTip; - } + WindowChrome.SetIsHitTestVisibleInChrome(closeButton, true); + } - m_itemsContainerRow = GetTemplateChildT(c_itemsContainerRow, controlProtected); - m_menuItemsScrollViewer = GetTemplateChildT(c_menuItemsScrollViewer, controlProtected); - m_footerItemsScrollViewer = GetTemplateChildT(c_footerItemsScrollViewer, controlProtected); - m_visualItemsSeparator = GetTemplateChildT(c_visualItemsSeparator, controlProtected); + if (GetTemplateChild(c_navViewCloseButtonToolTip) is ToolTip closeButtonToolTip) + { + string navigationCloseButtonToolTip = ResourceAccessor.GetLocalizedStringResource(SR_NavigationButtonOpenName); + closeButtonToolTip.Content = navigationCloseButtonToolTip; + } - m_itemsContainerSizeChangedRevoker?.Revoke(); - if (GetTemplateChildT(c_itemsContainer, controlProtected) is { } itemsContainerRow) - { - m_itemsContainerSizeChangedRevoker = new FrameworkElementSizeChangedRevoker(itemsContainerRow, OnItemsContainerSizeChanged); - } + m_itemsContainerRow = GetTemplateChildT(c_itemsContainerRow, controlProtected); + m_menuItemsScrollViewer = GetTemplateChildT(c_menuItemsScrollViewer, controlProtected); + m_footerItemsScrollViewer = GetTemplateChildT(c_footerItemsScrollViewer, controlProtected); + m_visualItemsSeparator = GetTemplateChildT(c_visualItemsSeparator, controlProtected); - if (SharedHelpers.IsRS2OrHigher()) - { - // Get hold of the outermost grid and enable XYKeyboardNavigationMode - // However, we only want this to work in the content pane + the hamburger button (which is not inside the splitview) - // so disable it on the grid in the content area of the SplitView - if (GetTemplateChildT(c_rootGridName, controlProtected) is { } rootGrid) + m_itemsContainerSizeChangedRevoker?.Revoke(); + if (GetTemplateChildT(c_itemsContainer, controlProtected) is { } itemsContainerRow) { - KeyboardNavigation.SetDirectionalNavigation(rootGrid, KeyboardNavigationMode.Contained); + m_itemsContainerSizeChangedRevoker = new FrameworkElementSizeChangedRevoker(itemsContainerRow, OnItemsContainerSizeChanged); } - if (GetTemplateChildT(c_contentGridName, controlProtected) is { } contentGrid) + if (SharedHelpers.IsRS2OrHigher()) { - KeyboardNavigation.SetDirectionalNavigation(contentGrid, KeyboardNavigationMode.None); + // Get hold of the outermost grid and enable XYKeyboardNavigationMode + // However, we only want this to work in the content pane + the hamburger button (which is not inside the splitview) + // so disable it on the grid in the content area of the SplitView + if (GetTemplateChildT(c_rootGridName, controlProtected) is { } rootGrid) + { + KeyboardNavigation.SetDirectionalNavigation(rootGrid, KeyboardNavigationMode.Contained); + } + + if (GetTemplateChildT(c_contentGridName, controlProtected) is { } contentGrid) + { + KeyboardNavigation.SetDirectionalNavigation(contentGrid, KeyboardNavigationMode.None); + } } - } - // TODO: WPF - AccessKey - //m_accessKeyInvokedRevoker = AccessKeyInvoked(winrt::auto_revoke, { this, &NavigationView::OnAccessKeyInvoked }); + // TODO: WPF - AccessKey + //m_accessKeyInvokedRevoker = AccessKeyInvoked(winrt::auto_revoke, { this, &NavigationView::OnAccessKeyInvoked }); - UpdatePaneShadow(); + UpdatePaneShadow(); - m_appliedTemplate = true; + m_appliedTemplate = true; - // Do initial setup - UpdatePaneDisplayMode(); - UpdateHeaderVisibility(); - UpdatePaneTitleFrameworkElementParents(); - UpdateTitleBarPadding(); - UpdatePaneTabFocusNavigation(); - UpdateBackAndCloseButtonsVisibility(); - UpdateSingleSelectionFollowsFocusTemplateSetting(); - UpdatePaneVisibility(); - UpdateVisualState(); - UpdatePaneTitleMargins(); - UpdatePaneLayout(); - UpdatePaneOverlayGroup(); + // Do initial setup + UpdatePaneDisplayMode(); + UpdateHeaderVisibility(); + UpdatePaneTitleFrameworkElementParents(); + UpdateTitleBarPadding(); + UpdatePaneTabFocusNavigation(); + UpdateBackAndCloseButtonsVisibility(); + UpdateSingleSelectionFollowsFocusTemplateSetting(); + UpdatePaneVisibility(); + UpdateVisualState(); + UpdatePaneTitleMargins(); + UpdatePaneLayout(); + UpdatePaneOverlayGroup(); + } + finally + { + m_fromOnApplyTemplate = false; + } } void UpdateRepeaterItemsSource(bool forceSelectionModelUpdate) @@ -2832,7 +2840,18 @@ void UpdateVisualStateForDisplayModeGroup(NavigationViewDisplayMode displayMode) { VisualStateManager.GoToState(this, visualStateName, false /*useTransitions*/); } - splitView.DisplayMode = splitViewDisplayMode; + + // Updating the splitview 'DisplayMode' property in some displaymodes causes children to be added to the popup root. + // This causes an exception if the NavigationView is in the popup root itself (as SplitView is trying to add children to the tree while it is being measured). + // Due to this, we want to defer updating this property for all calls coming from `OnApplyTemplate`to the OnLoaded function. + if (m_fromOnApplyTemplate) + { + m_updateVisualStateForDisplayModeFromOnLoaded = true; + } + else + { + splitView.DisplayMode = splitViewDisplayMode; + } } } @@ -4333,6 +4352,12 @@ void OnUnloaded(object sender, RoutedEventArgs args) void OnLoaded(object sender, RoutedEventArgs args) { + if (m_updateVisualStateForDisplayModeFromOnLoaded) + { + m_updateVisualStateForDisplayModeFromOnLoaded = false; + UpdateVisualStateForDisplayModeGroup(DisplayMode); + } + if (m_coreTitleBar is { } coreTitleBar) { coreTitleBar.LayoutMetricsChanged += OnTitleBarMetricsChanged; @@ -5917,6 +5942,12 @@ protected override void OnDpiChanged(DpiScale oldDpi, DpiScale newDpi) bool m_appliedTemplate = false; + // Identifies whenever a call is the result of OnApplyTemplate + bool m_fromOnApplyTemplate = false; + + // Used to defer updating the SplitView displaymode property + bool m_updateVisualStateForDisplayModeFromOnLoaded = false; + // flag is used to stop recursive call. eg: // Customer select an item from SelectedItem property->ChangeSelection update ListView->LIstView raise OnSelectChange(we want stop here)->change property do do animation again. // Customer clicked listview->listview raised OnSelectChange->SelectedItem property changed->ChangeSelection->Undo the selection by SelectedItem(prevItem) (we want it stop here)->ChangeSelection again ->... diff --git a/source/iNKORE.UI.WPF.Modern.Controls/Controls/Windows/NavigationView/NavigationView.properties.cs b/source/iNKORE.UI.WPF.Modern.Controls/Controls/Windows/NavigationView/NavigationView.properties.cs index f17607c3..480d00fc 100644 --- a/source/iNKORE.UI.WPF.Modern.Controls/Controls/Windows/NavigationView/NavigationView.properties.cs +++ b/source/iNKORE.UI.WPF.Modern.Controls/Controls/Windows/NavigationView/NavigationView.properties.cs @@ -41,7 +41,7 @@ public CornerRadius CornerRadius nameof(IsPaneOpen), typeof(bool), typeof(NavigationView), - new PropertyMetadata(true, OnIsPaneOpenPropertyChanged)); + new PropertyMetadata(OnIsPaneOpenPropertyChanged)); public bool IsPaneOpen {