From ef0e5f31e198c2bebd168ffa12f22fd8b6e250b9 Mon Sep 17 00:00:00 2001
From: Ivan Dmitriev <42055372+IvanDmitriev1@users.noreply.github.com>
Date: Wed, 25 Jan 2023 18:01:38 +0600
Subject: [PATCH 01/27] nullable annotation
---
.../Controls/Navigation/INavigationView.cs | 41 +++-------
.../Navigation/INavigationViewItem.cs | 8 +-
.../Navigation/NavigationView.Base.cs | 7 +-
.../Navigation/NavigationView.Parent.cs | 3 +-
.../Navigation/NavigationView.Properties.cs | 82 ++++++-------------
.../NavigationView.TemplateParts.cs | 61 +++++++-------
.../Controls/Navigation/NavigationViewItem.cs | 46 ++++-------
7 files changed, 86 insertions(+), 162 deletions(-)
diff --git a/src/Wpf.Ui/Controls/Navigation/INavigationView.cs b/src/Wpf.Ui/Controls/Navigation/INavigationView.cs
index 7861d8408..819425342 100644
--- a/src/Wpf.Ui/Controls/Navigation/INavigationView.cs
+++ b/src/Wpf.Ui/Controls/Navigation/INavigationView.cs
@@ -23,7 +23,7 @@ public interface INavigationView
///
/// Gets or sets the header content.
///
- object Header { get; set; }
+ object? Header { get; set; }
///
/// Gets or sets the visibility.
@@ -43,7 +43,7 @@ public interface INavigationView
///
/// Gets or sets an object source used to generate the content of the NavigationView menu.
///
- object MenuItemsSource { get; set; }
+ object? MenuItemsSource { get; set; }
///
/// Gets the list of objects to be used as navigation items in the footer menu.
@@ -53,7 +53,7 @@ public interface INavigationView
///
/// Gets or sets the object that represents the navigation items to be used in the footer menu.
///
- object FooterMenuItemsSource { get; set; }
+ object? FooterMenuItemsSource { get; set; }
///
/// Gets the selected item.
@@ -63,7 +63,7 @@ public interface INavigationView
///
/// Gets or sets a UI element that is shown at the top of the control, below the pane if PaneDisplayMode is Top.
///
- object ContentOverlay { get; set; }
+ object? ContentOverlay { get; set; }
///
/// Gets a value that indicates whether the back button is enabled or disabled.
@@ -99,12 +99,12 @@ public interface INavigationView
///
/// Gets or sets the content for the pane header.
///
- object PaneHeader { get; set; }
+ object? PaneHeader { get; set; }
///
/// Gets or sets the content for the pane footer.
///
- object PaneFooter { get; set; }
+ object? PaneFooter { get; set; }
///
/// Gets a value that specifies how the pane and content areas of a NavigationView are being shown.
@@ -115,17 +115,17 @@ public interface INavigationView
///
/// Gets or sets an AutoSuggestBox to be displayed in the NavigationView.
///
- AutoSuggestBox AutoSuggestBox { get; set; }
+ AutoSuggestBox? AutoSuggestBox { get; set; }
///
/// Gets or sets an TitleBar to be displayed in the NavigationView.
///
- TitleBar TitleBar { get; set; }
+ TitleBar? TitleBar { get; set; }
///
/// Template Property for and .
///
- ControlTemplate ItemTemplate { get; set; }
+ ControlTemplate? ItemTemplate { get; set; }
///
/// Gets or sets a value deciding how long the effect of the transition between the pages should take.
@@ -171,25 +171,13 @@ public interface INavigationView
/// Synchronously navigates current navigation Frame to the
/// given Element.
///
- bool Navigate(Type pageType);
+ bool Navigate(Type pageType, object? dataContext = null);
///
/// Synchronously navigates current navigation Frame to the
/// given Element.
///
- bool Navigate(Type pageType, object dataContext);
-
- ///
- /// Synchronously navigates current navigation Frame to the
- /// given Element.
- ///
- bool Navigate(string pageIdOrTargetTag);
-
- ///
- /// Synchronously navigates current navigation Frame to the
- /// given Element.
- ///
- bool Navigate(string pageIdOrTargetTag, object dataContext);
+ bool Navigate(string pageIdOrTargetTag, object? dataContext = null);
///
/// Replaces the contents of the navigation frame, without changing the currently selected item or triggering an .
@@ -199,12 +187,7 @@ public interface INavigationView
///
/// Replaces the contents of the navigation frame, without changing the currently selected item or triggering an .
///
- bool ReplaceContent(UIElement pageInstanceToEmbed);
-
- ///
- /// Replaces the contents of the navigation frame, without changing the currently selected item or triggering an .
- ///
- bool ReplaceContent(UIElement pageInstanceToEmbed, object dataContext);
+ bool ReplaceContent(UIElement pageInstanceToEmbed, object? dataContext = null);
///
/// Navigates the NavigationView to the next journal entry.
diff --git a/src/Wpf.Ui/Controls/Navigation/INavigationViewItem.cs b/src/Wpf.Ui/Controls/Navigation/INavigationViewItem.cs
index 1ec705092..07bf5c25b 100644
--- a/src/Wpf.Ui/Controls/Navigation/INavigationViewItem.cs
+++ b/src/Wpf.Ui/Controls/Navigation/INavigationViewItem.cs
@@ -28,7 +28,7 @@ public interface INavigationViewItem
/// Gets or sets the icon displayed in the MenuItem object.
/// If it's a , additional effects will be applied.
///
- object Icon { get; set; }
+ object? Icon { get; set; }
///
/// Gets the collection of menu items displayed in the NavigationView.
@@ -38,7 +38,7 @@ public interface INavigationViewItem
///
/// Gets or sets an object source used to generate the content of the NavigationView menu.
///
- object MenuItemsSource { get; set; }
+ object? MenuItemsSource { get; set; }
///
/// Gets information whether the current element is active.
@@ -58,12 +58,12 @@ public interface INavigationViewItem
///
/// The type of the page to be navigated. (Should be derived from ).
///
- public Type TargetPageType { get; set; }
+ public Type? TargetPageType { get; set; }
///
/// Template Property
///
- public ControlTemplate Template { get; set; }
+ public ControlTemplate? Template { get; set; }
///
/// Add / Remove ClickEvent handler.
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs b/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs
index d8906e2c9..1681acc62 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs
@@ -39,7 +39,6 @@ static NavigationView()
public NavigationView()
{
- SelectedItem = null;
NavigationParent = this;
SetValue(MenuItemsProperty,
@@ -93,11 +92,7 @@ private void OnLoaded(object sender, RoutedEventArgs e)
///
protected virtual void OnUnloaded(object sender, RoutedEventArgs e)
{
- if (MenuItems is INotifyCollectionChanged menuItemsCollection)
- menuItemsCollection.CollectionChanged -= OnMenuItemsCollectionChanged;
-
- if (FooterMenuItems is INotifyCollectionChanged footerMenuItemsCollection)
- footerMenuItemsCollection.CollectionChanged -= OnFooterMenuItemsCollectionChanged;
+ NavigationViewContentPresenter.Navigated -= OnNavigationViewContentPresenterNavigated;
}
///
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationView.Parent.cs b/src/Wpf.Ui/Controls/Navigation/NavigationView.Parent.cs
index ffe8f0b0e..ba4595976 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationView.Parent.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationView.Parent.cs
@@ -33,8 +33,7 @@ internal INavigationView NavigationParent
///
///
/// Instance of the or .
- internal static NavigationView? GetNavigationParent(T navigationItem)
- where T : DependencyObject, INavigationViewItem
+ internal static NavigationView? GetNavigationParent(T navigationItem) where T : DependencyObject, INavigationViewItem
{
if (navigationItem.GetValue(NavigationParentProperty) is NavigationView navigationView)
return navigationView;
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationView.Properties.cs b/src/Wpf.Ui/Controls/Navigation/NavigationView.Properties.cs
index 0b0ecabf2..e72c3ae0a 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationView.Properties.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationView.Properties.cs
@@ -22,14 +22,14 @@ public partial class NavigationView
///
public static readonly DependencyProperty HeaderProperty = DependencyProperty.Register(nameof(Header),
typeof(object), typeof(NavigationView),
- new FrameworkPropertyMetadata(((object)null!)));
+ new FrameworkPropertyMetadata(null));
///
/// Property for .
///
public static readonly DependencyProperty HeaderVisibilityProperty = DependencyProperty.Register(nameof(HeaderVisibility),
typeof(Visibility), typeof(NavigationView),
- new FrameworkPropertyMetadata(System.Windows.Visibility.Visible));
+ new FrameworkPropertyMetadata(Visibility.Visible));
///
/// Property for .
@@ -50,7 +50,7 @@ public partial class NavigationView
///
public static readonly DependencyProperty MenuItemsSourceProperty = DependencyProperty.Register(nameof(MenuItemsSource),
typeof(object), typeof(NavigationView),
- new FrameworkPropertyMetadata(((object)null!), OnMenuItemsSourcePropertyChanged));
+ new FrameworkPropertyMetadata(null, OnMenuItemsSourcePropertyChanged));
///
/// Property for .
@@ -64,14 +64,14 @@ public partial class NavigationView
///
public static readonly DependencyProperty FooterMenuItemsSourceProperty = DependencyProperty.Register(nameof(FooterMenuItemsSource),
typeof(object), typeof(NavigationView),
- new FrameworkPropertyMetadata(((object)null!), OnFooterMenuItemsSourcePropertyChanged));
+ new FrameworkPropertyMetadata(null, OnFooterMenuItemsSourcePropertyChanged));
///
/// Property for .
///
public static readonly DependencyProperty ContentOverlayProperty = DependencyProperty.Register(nameof(ContentOverlay),
typeof(object), typeof(NavigationView),
- new FrameworkPropertyMetadata(((object)null!)));
+ new FrameworkPropertyMetadata(null));
///
/// Property for .
@@ -120,14 +120,14 @@ public partial class NavigationView
///
public static readonly DependencyProperty PaneHeaderProperty = DependencyProperty.Register(nameof(PaneHeader),
typeof(object), typeof(NavigationView),
- new FrameworkPropertyMetadata(((object)null!)));
+ new FrameworkPropertyMetadata(null));
///
/// Property for .
///
public static readonly DependencyProperty PaneFooterProperty = DependencyProperty.Register(nameof(PaneFooter),
typeof(object), typeof(NavigationView),
- new FrameworkPropertyMetadata(((object)null!)));
+ new FrameworkPropertyMetadata(null));
///
/// Property for .
@@ -141,14 +141,14 @@ public partial class NavigationView
///
public static readonly DependencyProperty AutoSuggestBoxProperty = DependencyProperty.Register(nameof(AutoSuggestBox),
typeof(AutoSuggestBox), typeof(NavigationView),
- new FrameworkPropertyMetadata(((AutoSuggestBox)null!)));
+ new FrameworkPropertyMetadata(null));
///
/// Property for .
///
public static readonly DependencyProperty TitleBarProperty = DependencyProperty.Register(nameof(TitleBar),
typeof(TitleBar), typeof(NavigationView),
- new FrameworkPropertyMetadata(((TitleBar)null!)));
+ new FrameworkPropertyMetadata(null));
///
/// Property for .
@@ -175,7 +175,7 @@ public partial class NavigationView
new FrameworkPropertyMetadata(TransitionType.FadeInWithSlide));
///
- public object Header
+ public object? Header
{
get => GetValue(HeaderProperty);
set => SetValue(HeaderProperty, value);
@@ -204,7 +204,7 @@ public IList? MenuItems
///
[Bindable(true)]
- public object MenuItemsSource
+ public object? MenuItemsSource
{
get => GetValue(MenuItemsSourceProperty);
set
@@ -225,7 +225,7 @@ public IList? FooterMenuItems
///
[Bindable(true)]
- public object FooterMenuItemsSource
+ public object? FooterMenuItemsSource
{
get => GetValue(FooterMenuItemsSourceProperty);
set
@@ -238,7 +238,7 @@ public object FooterMenuItemsSource
}
///
- public object ContentOverlay
+ public object? ContentOverlay
{
get => GetValue(ContentOverlayProperty);
set => SetValue(ContentOverlayProperty, value);
@@ -287,14 +287,14 @@ public double OpenPaneLength
}
///
- public object PaneHeader
+ public object? PaneHeader
{
get => GetValue(PaneHeaderProperty);
set => SetValue(PaneHeaderProperty, value);
}
///
- public object PaneFooter
+ public object? PaneFooter
{
get => GetValue(PaneFooterProperty);
set => SetValue(PaneFooterProperty, value);
@@ -308,21 +308,21 @@ public NavigationViewPaneDisplayMode PaneDisplayMode
}
///
- public AutoSuggestBox AutoSuggestBox
+ public AutoSuggestBox? AutoSuggestBox
{
get => (AutoSuggestBox)GetValue(AutoSuggestBoxProperty);
set => SetValue(AutoSuggestBoxProperty, value);
}
///
- public TitleBar TitleBar
+ public TitleBar? TitleBar
{
get => (TitleBar)GetValue(TitleBarProperty);
set => SetValue(TitleBarProperty, value);
}
///
- public ControlTemplate ItemTemplate
+ public ControlTemplate? ItemTemplate
{
get => (ControlTemplate)GetValue(ItemTemplateProperty);
set => SetValue(ItemTemplateProperty, value);
@@ -348,66 +348,34 @@ private static void OnMenuItemsPropertyChanged(DependencyObject? d, DependencyPr
if (d is not NavigationView navigationView)
return;
- if (e.OldValue is INotifyCollectionChanged oldMenuItemsCollection)
- oldMenuItemsCollection.CollectionChanged -= navigationView.OnMenuItemsCollectionChanged;
-
- if (e.NewValue is INotifyCollectionChanged newMenuItemsCollection)
- newMenuItemsCollection.CollectionChanged += navigationView.OnMenuItemsCollectionChanged;
-
navigationView.OnMenuItemsChanged();
}
- protected virtual void OnMenuItemsCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
- {
- }
-
- private static void OnMenuItemsSourcePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ private static void OnMenuItemsSourcePropertyChanged(DependencyObject? d, DependencyPropertyChangedEventArgs e)
{
- if (d is not NavigationView navigationView)
- return;
-
- if (e.NewValue is not IList enumerableNewValue)
+ if (d is not NavigationView navigationView || e.NewValue is not IList enumerableNewValue)
return;
- if (navigationView.MenuItems != null)
- navigationView.MenuItems = null;
-
navigationView.MenuItems = enumerableNewValue;
}
- private static void OnFooterMenuItemsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ private static void OnFooterMenuItemsPropertyChanged(DependencyObject? d, DependencyPropertyChangedEventArgs e)
{
if (d is not NavigationView navigationView)
return;
- if (e.OldValue is INotifyCollectionChanged oldMenuItemsCollection)
- oldMenuItemsCollection.CollectionChanged -= navigationView.OnFooterMenuItemsCollectionChanged;
-
- if (e.NewValue is INotifyCollectionChanged newMenuItemsCollection)
- newMenuItemsCollection.CollectionChanged += navigationView.OnFooterMenuItemsCollectionChanged;
-
navigationView.OnFooterMenuItemsChanged();
}
- private static void OnFooterMenuItemsSourcePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ private static void OnFooterMenuItemsSourcePropertyChanged(DependencyObject? d, DependencyPropertyChangedEventArgs e)
{
- if (d is not NavigationView navigationView)
- return;
-
- if (e.NewValue is not IList enumerableNewValue)
+ if (d is not NavigationView navigationView || e.NewValue is not IList enumerableNewValue)
return;
- if (navigationView.FooterMenuItems != null)
- navigationView.FooterMenuItems = null;
-
navigationView.FooterMenuItems = enumerableNewValue;
}
- protected virtual void OnFooterMenuItemsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
- {
- }
-
- private static void OnPaneDisplayModePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ private static void OnPaneDisplayModePropertyChanged(DependencyObject? d, DependencyPropertyChangedEventArgs e)
{
if (d is not NavigationView navigationView)
return;
@@ -415,7 +383,7 @@ private static void OnPaneDisplayModePropertyChanged(DependencyObject d, Depende
navigationView.OnPaneDisplayModeChanged();
}
- private static void OnItemTemplatePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ private static void OnItemTemplatePropertyChanged(DependencyObject? d, DependencyPropertyChangedEventArgs e)
{
if (d is not NavigationView navigationView)
return;
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationView.TemplateParts.cs b/src/Wpf.Ui/Controls/Navigation/NavigationView.TemplateParts.cs
index 84efd5bad..282ad79b3 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationView.TemplateParts.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationView.TemplateParts.cs
@@ -6,15 +6,16 @@
// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
// All Rights Reserved.
+using System;
using System.Windows;
namespace Wpf.Ui.Controls.Navigation;
-[TemplatePart(Name = "PART_NavigationViewContentPresenter", Type = typeof(NavigationViewContentPresenter))]
-[TemplatePart(Name = "PART_MenuItemsItemsControl", Type = typeof(System.Windows.Controls.ItemsControl))]
-[TemplatePart(Name = "PART_FooterMenuItemsItemsControl", Type = typeof(System.Windows.Controls.ItemsControl))]
-[TemplatePart(Name = "PART_BackButton", Type = typeof(System.Windows.Controls.Button))]
-[TemplatePart(Name = "PART_ToggleButton", Type = typeof(System.Windows.Controls.Button))]
+[TemplatePart(Name = TemplateElementNavigationViewContentPresenter, Type = typeof(NavigationViewContentPresenter))]
+[TemplatePart(Name = TemplateElementMenuItemsItemsControl, Type = typeof(System.Windows.Controls.ItemsControl))]
+[TemplatePart(Name = TemplateElementFooterMenuItemsItemsControl, Type = typeof(System.Windows.Controls.ItemsControl))]
+[TemplatePart(Name = TemplateElementBackButton, Type = typeof(System.Windows.Controls.Button))]
+[TemplatePart(Name = TemplateElementToggleButton, Type = typeof(System.Windows.Controls.Button))]
public partial class NavigationView
{
///
@@ -45,67 +46,63 @@ public partial class NavigationView
///
/// Control responsible for rendering the content.
///
- protected NavigationViewContentPresenter NavigationViewContentPresenter;
+ protected NavigationViewContentPresenter NavigationViewContentPresenter = null!;
///
/// Control located at the top of the pane with left arrow icon.
///
- protected System.Windows.Controls.ItemsControl MenuItemsItemsControl;
+ protected System.Windows.Controls.ItemsControl MenuItemsItemsControl = null!;
///
/// Control located at the top of the pane with hamburger icon.
///
- protected System.Windows.Controls.ItemsControl FooterMenuItemsItemsControl;
+ protected System.Windows.Controls.ItemsControl FooterMenuItemsItemsControl = null!;
///
/// Control located at the top of the pane with left arrow icon.
///
- protected System.Windows.Controls.Button BackButton;
+ protected System.Windows.Controls.Button? BackButton;
///
/// Control located at the top of the pane with hamburger icon.
///
- protected System.Windows.Controls.Button ToggleButton;
+ protected System.Windows.Controls.Button? ToggleButton;
///
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
- if (GetTemplateChild(TemplateElementNavigationViewContentPresenter) is NavigationViewContentPresenter navigationViewContentPresenter)
- NavigationViewContentPresenter = navigationViewContentPresenter;
+ NavigationViewContentPresenter = GetTemplateChild(TemplateElementNavigationViewContentPresenter);
+ MenuItemsItemsControl = GetTemplateChild(TemplateElementMenuItemsItemsControl);
+ FooterMenuItemsItemsControl = GetTemplateChild(TemplateElementFooterMenuItemsItemsControl);
- if (GetTemplateChild(TemplateElementMenuItemsItemsControl) is System.Windows.Controls.ItemsControl menuItemsItemsControl)
- MenuItemsItemsControl = menuItemsItemsControl;
-
- if (GetTemplateChild(TemplateElementFooterMenuItemsItemsControl) is System.Windows.Controls.ItemsControl footerMenuItemsItemsControl)
- FooterMenuItemsItemsControl = footerMenuItemsItemsControl;
+ NavigationViewContentPresenter.Navigated += OnNavigationViewContentPresenterNavigated;
+ MenuItemsItemsControl.ItemsSource = MenuItems;
+ FooterMenuItemsItemsControl.ItemsSource = FooterMenuItems;
if (GetTemplateChild(TemplateElementBackButton) is System.Windows.Controls.Button backButton)
+ {
BackButton = backButton;
- if (GetTemplateChild(TemplateElementToggleButton) is System.Windows.Controls.Button toggleButton)
- ToggleButton = toggleButton;
-
- if (NavigationViewContentPresenter != null)
- NavigationViewContentPresenter.Navigated += OnNavigationViewContentPresenterNavigated;
-
- if (MenuItemsItemsControl != null)
- MenuItemsItemsControl.ItemsSource = MenuItems;
-
- if (FooterMenuItemsItemsControl != null)
- FooterMenuItemsItemsControl.ItemsSource = FooterMenuItems;
-
- if (BackButton != null)
- {
BackButton.Click -= OnBackButtonClick;
BackButton.Click += OnBackButtonClick;
}
- if (ToggleButton != null)
+ if (GetTemplateChild(TemplateElementToggleButton) is System.Windows.Controls.Button toggleButton)
{
+ ToggleButton = toggleButton;
+
ToggleButton.Click -= OnToggleButtonClick;
ToggleButton.Click += OnToggleButtonClick;
}
}
+
+ protected T GetTemplateChild(string name) where T : DependencyObject
+ {
+ if (GetTemplateChild(name) is not T dependencyObject)
+ throw new ArgumentNullException(name);
+
+ return dependencyObject;
+ }
}
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationViewItem.cs b/src/Wpf.Ui/Controls/Navigation/NavigationViewItem.cs
index fc550cee3..cdbe14364 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationViewItem.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationViewItem.cs
@@ -86,7 +86,7 @@ public IList? MenuItems
///
[Bindable(true)]
- public object MenuItemsSource
+ public object? MenuItemsSource
{
get => GetValue(MenuItemsSourceProperty);
set
@@ -126,7 +126,7 @@ public bool IsExpanded
///
[Bindable(true), Category("Appearance")]
- public object Icon
+ public object? Icon
{
get => GetValue(IconProperty);
set => SetValue(IconProperty, value);
@@ -140,7 +140,7 @@ public string TargetPageTag
}
///
- public Type TargetPageType
+ public Type? TargetPageType
{
get => (Type)GetValue(TargetPageTypeProperty);
set => SetValue(TargetPageTypeProperty, value);
@@ -158,16 +158,14 @@ public NavigationViewItem()
{
Id = Guid.NewGuid().ToString("n");
- SetValue(MenuItemsProperty,
- new ObservableCollection
protected virtual void OnUnloaded(object sender, RoutedEventArgs e)
{
+ Loaded -= OnLoaded;
+ Unloaded -= OnUnloaded;
+ SizeChanged -= OnSizeChanged;
+
NavigationViewContentPresenter.Navigated -= OnNavigationViewContentPresenterNavigated;
+
+ if (AutoSuggestBox is not null)
+ AutoSuggestBox.SuggestionChosen -= AutoSuggestBoxOnSuggestionChosen;
}
///
@@ -106,19 +106,14 @@ protected virtual void OnSizeChanged(object sender, SizeChangedEventArgs e)
///
/// This virtual method is called when is clicked.
///
- protected virtual void OnBackButtonClick(object sender, RoutedEventArgs e)
- {
- GoBack();
- }
+ protected virtual void OnBackButtonClick(object sender, RoutedEventArgs e) => GoBack();
///
/// This virtual method is called when is clicked.
///
protected virtual void OnToggleButtonClick(object sender, RoutedEventArgs e)
{
-#if DEBUG
- System.Diagnostics.Debug.WriteLine("Toggle");
-#endif
+ Debug.WriteLine("Toggle");
}
///
@@ -131,7 +126,6 @@ protected virtual void OnMenuItemsChanged()
UpdateLayout();
UpdateAutoSuggestBoxSuggestions();
-
UpdateSelectionForMenuItems();
}
@@ -141,7 +135,6 @@ protected virtual void OnMenuItemsChanged()
protected virtual void OnFooterMenuItemsChanged()
{
UpdateAutoSuggestBoxSuggestions();
-
UpdateSelectionForMenuItems();
}
@@ -164,7 +157,8 @@ protected virtual void OnPaneDisplayModeChanged()
///
protected virtual void OnItemTemplateChanged()
{
- UpdateMenuItemsTemplate();
+ UpdateMenuItemsTemplate(MenuItems);
+ UpdateMenuItemsTemplate(FooterMenuItems);
}
internal void ToggleAllExpands()
@@ -179,121 +173,109 @@ internal void OnNavigationViewItemClick(NavigationViewItem navigationViewItem)
NavigateInternal(navigationViewItem, null, true, false);
}
- private void UpdateMenuItemsTemplate()
- {
- if (MenuItems is IEnumerable enumerableItemsSource)
- foreach (var singleMenuItem in enumerableItemsSource)
- if (singleMenuItem is NavigationViewItem singleNavigationViewItem)
- if (ItemTemplate != null && singleNavigationViewItem.Template != ItemTemplate)
- singleNavigationViewItem.Template = ItemTemplate;
-
- if (FooterMenuItems is IEnumerable enumerableFooterItemsSource)
- foreach (var singleMenuItem in enumerableFooterItemsSource)
- if (singleMenuItem is NavigationViewItem singleNavigationViewItem)
- if (ItemTemplate != null && singleNavigationViewItem.Template != ItemTemplate)
- singleNavigationViewItem.Template = ItemTemplate;
- }
-
- private void UpdateAutoSuggestBoxSuggestions()
+ protected void UpdateAutoSuggestBoxSuggestions()
{
if (AutoSuggestBox == null)
return;
- _autoSuggestBoxItems = new ObservableCollection();
-
- if (MenuItems is IEnumerable enumerableItemsSource)
- foreach (var singleMenuItem in enumerableItemsSource)
- if (singleMenuItem is NavigationViewItem singleNavigationViewItem)
- {
- if (singleNavigationViewItem.Content is string content && singleNavigationViewItem.TargetPageType != null && !String.IsNullOrWhiteSpace(content))
- _autoSuggestBoxItems.Add(content);
-
- if (singleNavigationViewItem.MenuItems?.Count > 0)
- foreach (var subMenuItem in singleNavigationViewItem.MenuItems)
- if (subMenuItem is NavigationViewItem { Content: string subContent, TargetPageType: not null } && !String.IsNullOrWhiteSpace(subContent))
- _autoSuggestBoxItems.Add(subContent);
- }
-
- if (FooterMenuItems is IEnumerable enumerableFooterItemsSource)
- foreach (var singleMenuItem in enumerableFooterItemsSource)
- if (singleMenuItem is NavigationViewItem singleNavigationViewItem)
- {
- if (singleNavigationViewItem.Content is string content && singleNavigationViewItem.TargetPageType != null && !String.IsNullOrWhiteSpace(content))
- _autoSuggestBoxItems.Add(content);
-
- if (singleNavigationViewItem.MenuItems?.Count > 0)
- foreach (var subMenuItem in singleNavigationViewItem.MenuItems)
- if (subMenuItem is NavigationViewItem { Content: string subContent, TargetPageType: not null } && !String.IsNullOrWhiteSpace(subContent))
- _autoSuggestBoxItems.Add(subContent);
- }
-
- AutoSuggestBox.ItemsSource = _autoSuggestBoxItems;
-
- AutoSuggestBox.SuggestionChosen -= AutoSuggestBoxOnSuggestionChosen;
- AutoSuggestBox.SuggestionChosen += AutoSuggestBoxOnSuggestionChosen;
+ _autoSuggestBoxItems.Clear();
+
+ AddItemsToAutoSuggestBoxItemsForMenuItems(MenuItems);
+ AddItemsToAutoSuggestBoxItemsForMenuItems(FooterMenuItems);
}
///
/// Navigate to the page after its name is selected in .
///
- private void AutoSuggestBoxOnSuggestionChosen(object sender, RoutedEventArgs e)
+ protected void AutoSuggestBoxOnSuggestionChosen(object sender, RoutedEventArgs e)
+ {
+ if (sender is not AutoSuggestBox { ChosenSuggestion: string selectedSuggestBoxItem })
+ return;
+
+ if (string.IsNullOrEmpty(selectedSuggestBoxItem))
+ return;
+
+ if (NavigateToMenuItemFromAutoSuggestBox(MenuItems, selectedSuggestBoxItem))
+ return;
+
+ NavigateToMenuItemFromAutoSuggestBox(FooterMenuItems, selectedSuggestBoxItem);
+ }
+
+ private void AddItemsToAutoSuggestBoxItemsForMenuItems(IList? list)
{
- if (sender is not Controls.AutoSuggestBox autoSuggestBox)
+ if (list is null)
return;
- var selectedSuggestBoxItem = autoSuggestBox.ChosenSuggestion?.ToString() ?? String.Empty;
+ foreach (var singleMenuItem in list)
+ {
+ if (singleMenuItem is not NavigationViewItem singleNavigationViewItem)
+ continue;
+
+ if (singleNavigationViewItem is { Content: string content, TargetPageType: { } } && !string.IsNullOrWhiteSpace(content))
+ _autoSuggestBoxItems.Add(content);
+
+ if (!(singleNavigationViewItem.MenuItems?.Count > 0))
+ continue;
+
+ foreach (var subMenuItem in singleNavigationViewItem.MenuItems)
+ {
+ if (subMenuItem is NavigationViewItem { Content: string subContent, TargetPageType: not null } && !string.IsNullOrWhiteSpace(subContent))
+ _autoSuggestBoxItems.Add(subContent);
+ }
+
+ }
+ }
+
+ private bool NavigateToMenuItemFromAutoSuggestBox(IList? list, string selectedSuggestBoxItem)
+ {
+ if (list is null)
+ return false;
+
+ foreach (var singleMenuItem in list)
+ {
+ if (singleMenuItem is not NavigationViewItem singleNavigationViewItem)
+ continue;
+
+ if (singleNavigationViewItem.Content is string content && content == selectedSuggestBoxItem)
+ {
+ NavigateInternal(singleNavigationViewItem, null, true, false);
+ singleNavigationViewItem.BringIntoView();
+ singleNavigationViewItem.Focus();
- if (selectedSuggestBoxItem == String.Empty)
+ return true;
+ }
+
+ if (!(singleNavigationViewItem.MenuItems?.Count > 0))
+ continue;
+
+ foreach (var subMenuItem in singleNavigationViewItem.MenuItems)
+ {
+ if (subMenuItem is not NavigationViewItem { Content: string subContent } subMenuNavigationViewItem || subContent != selectedSuggestBoxItem)
+ continue;
+
+ NavigateInternal(subMenuNavigationViewItem, null, true, false);
+ subMenuNavigationViewItem.BringIntoView();
+ subMenuNavigationViewItem.Focus();
+
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private void UpdateMenuItemsTemplate(IList? list)
+ {
+ if (list is null)
return;
- if (MenuItems is IEnumerable enumerableItemsSource)
- foreach (var singleMenuItem in enumerableItemsSource)
- if (singleMenuItem is NavigationViewItem singleNavigationViewItem)
- {
- if (singleNavigationViewItem.Content is string content && content == selectedSuggestBoxItem)
- {
- NavigateInternal(singleNavigationViewItem, null, true, false);
- singleNavigationViewItem.BringIntoView();
- singleNavigationViewItem.Focus();
-
- return;
- }
-
- if (singleNavigationViewItem.MenuItems?.Count > 0)
- foreach (var subMenuItem in singleNavigationViewItem.MenuItems)
- if (subMenuItem is NavigationViewItem { Content: string subContent } subMenuNavigationViewItem && subContent == selectedSuggestBoxItem)
- {
- NavigateInternal(subMenuNavigationViewItem, null, true, false);
- subMenuNavigationViewItem.BringIntoView();
- subMenuNavigationViewItem.Focus();
-
- return;
- }
- }
-
- if (FooterMenuItems is IEnumerable enumerableFooterItemsSource)
- foreach (var singleMenuItem in enumerableFooterItemsSource)
- if (singleMenuItem is NavigationViewItem singleNavigationViewItem)
- {
- if (singleNavigationViewItem.Content is string content && content == selectedSuggestBoxItem)
- {
- NavigateInternal(singleNavigationViewItem, null, true, false);
- singleNavigationViewItem.BringIntoView();
- singleNavigationViewItem.Focus();
-
- return;
- }
-
- if (singleNavigationViewItem.MenuItems?.Count > 0)
- foreach (var subMenuItem in singleNavigationViewItem.MenuItems)
- if (subMenuItem is NavigationViewItem { Content: string subContent } subMenuNavigationViewItem && subContent == selectedSuggestBoxItem)
- {
- NavigateInternal(subMenuNavigationViewItem, null, true, false);
- subMenuNavigationViewItem.BringIntoView();
- subMenuNavigationViewItem.Focus();
-
- return;
- }
- }
+ foreach (var singleMenuItem in list)
+ {
+ if (singleMenuItem is not NavigationViewItem singleNavigationViewItem)
+ continue;
+
+ if (ItemTemplate is not null && singleNavigationViewItem.Template != ItemTemplate)
+ singleNavigationViewItem.Template = ItemTemplate;
+ }
}
}
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationView.Properties.cs b/src/Wpf.Ui/Controls/Navigation/NavigationView.Properties.cs
index e72c3ae0a..7ecd95a06 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationView.Properties.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationView.Properties.cs
@@ -345,7 +345,7 @@ public TransitionType TransitionType
private static void OnMenuItemsPropertyChanged(DependencyObject? d, DependencyPropertyChangedEventArgs e)
{
- if (d is not NavigationView navigationView)
+ if (d is not NavigationView { IsInitialized: true } navigationView)
return;
navigationView.OnMenuItemsChanged();
@@ -361,7 +361,7 @@ private static void OnMenuItemsSourcePropertyChanged(DependencyObject? d, Depend
private static void OnFooterMenuItemsPropertyChanged(DependencyObject? d, DependencyPropertyChangedEventArgs e)
{
- if (d is not NavigationView navigationView)
+ if (d is not NavigationView { IsInitialized: true } navigationView)
return;
navigationView.OnFooterMenuItemsChanged();
From b42807fdbc0b078b0e14a8f2ae41a68152704a3f Mon Sep 17 00:00:00 2001
From: Ivan Dmitriev <42055372+IvanDmitriev1@users.noreply.github.com>
Date: Wed, 25 Jan 2023 20:05:44 +0600
Subject: [PATCH 03/27] added BreadcrumbBar support
---
.../Views/Windows/MainWindow.xaml | 5 +-
.../Navigation/INavigationViewItem.cs | 5 +
.../Navigation/NavigationView.Base.cs | 30 ++++--
.../Navigation/NavigationViewBreadcrumb.cs | 99 -------------------
.../NavigationViewBreadcrumbItem.cs | 13 +++
src/Wpf.Ui/Styles/Controls/BreadcrumbBar.xaml | 2 +-
.../Controls/NavigationViewBreadcrumb.xaml | 42 --------
.../NavigationViewBreadcrumbItem.xaml | 17 ++++
src/Wpf.Ui/Styles/Wpf.Ui.xaml | 2 +-
9 files changed, 59 insertions(+), 156 deletions(-)
delete mode 100644 src/Wpf.Ui/Controls/Navigation/NavigationViewBreadcrumb.cs
create mode 100644 src/Wpf.Ui/Controls/Navigation/NavigationViewBreadcrumbItem.cs
delete mode 100644 src/Wpf.Ui/Styles/Controls/NavigationViewBreadcrumb.xaml
create mode 100644 src/Wpf.Ui/Styles/Controls/NavigationViewBreadcrumbItem.xaml
diff --git a/src/Wpf.Ui.Gallery/Views/Windows/MainWindow.xaml b/src/Wpf.Ui.Gallery/Views/Windows/MainWindow.xaml
index df1b99c8d..d95ac0e18 100644
--- a/src/Wpf.Ui.Gallery/Views/Windows/MainWindow.xaml
+++ b/src/Wpf.Ui.Gallery/Views/Windows/MainWindow.xaml
@@ -35,10 +35,7 @@
PaneDisplayMode="Left"
SelectionChanged="OnNavigationSelectionChanged">
-
+
public interface INavigationViewItem
{
+ ///
+ /// Get or sets content
+ ///
+ object Content { get; }
+
///
/// Unique identifier that allows the item to be located in the navigation.
///
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs b/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs
index 7a68cb487..168c9505d 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs
@@ -9,10 +9,10 @@
using System;
using System.Collections;
using System.Collections.ObjectModel;
-using System.Collections.Specialized;
using System.ComponentModel;
using System.Diagnostics;
using System.Windows;
+using Wpf.Ui.Common;
namespace Wpf.Ui.Controls.Navigation;
@@ -25,7 +25,8 @@ namespace Wpf.Ui.Controls.Navigation;
[System.Drawing.ToolboxBitmap(typeof(NavigationView), "NavigationView.bmp")]
public partial class NavigationView : System.Windows.Controls.Control, INavigationView
{
- private ObservableCollection _autoSuggestBoxItems = new();
+ private readonly ObservableCollection _autoSuggestBoxItems = new();
+ private readonly ObservableCollection _breadcrumbBarItems = new();
///
public INavigationViewItem? SelectedItem { get; private set; }
@@ -42,11 +43,8 @@ public NavigationView()
{
NavigationParent = this;
- SetValue(MenuItemsProperty,
- new ObservableCollection());
-
- SetValue(FooterMenuItemsProperty,
- new ObservableCollection());
+ SetValue(MenuItemsProperty, new ObservableCollection());
+ SetValue(FooterMenuItemsProperty, new ObservableCollection());
Loaded += OnLoaded;
Unloaded += OnUnloaded;
@@ -58,8 +56,12 @@ protected override void OnInitialized(EventArgs e)
{
base.OnInitialized(e);
- if (Header is NavigationViewBreadcrumb navigationViewBreadcrumb)
- navigationViewBreadcrumb.NavigationView = this;
+ if (Header is BreadcrumbBar breadcrumbBar)
+ {
+ breadcrumbBar.ItemsSource = _breadcrumbBarItems;
+ breadcrumbBar.ItemTemplate ??= Application.Current.TryFindResource("NavigationViewItemDataTemplate") as DataTemplate;
+ breadcrumbBar.ItemClicked += BreadcrumbBarOnItemClicked;
+ }
if (AutoSuggestBox is not null)
{
@@ -93,6 +95,11 @@ protected virtual void OnUnloaded(object sender, RoutedEventArgs e)
if (AutoSuggestBox is not null)
AutoSuggestBox.SuggestionChosen -= AutoSuggestBoxOnSuggestionChosen;
+
+ if (Header is BreadcrumbBar breadcrumbBar)
+ {
+ breadcrumbBar.ItemClicked -= BreadcrumbBarOnItemClicked;
+ }
}
///
@@ -173,6 +180,11 @@ internal void OnNavigationViewItemClick(NavigationViewItem navigationViewItem)
NavigateInternal(navigationViewItem, null, true, false);
}
+ protected virtual void BreadcrumbBarOnItemClicked(BreadcrumbBar sender, BreadcrumbBarItemClickedEventArgs e)
+ {
+
+ }
+
protected void UpdateAutoSuggestBoxSuggestions()
{
if (AutoSuggestBox == null)
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationViewBreadcrumb.cs b/src/Wpf.Ui/Controls/Navigation/NavigationViewBreadcrumb.cs
deleted file mode 100644
index aacdc183e..000000000
--- a/src/Wpf.Ui/Controls/Navigation/NavigationViewBreadcrumb.cs
+++ /dev/null
@@ -1,99 +0,0 @@
-// Based on Windows UI Library
-// Copyright(c) Microsoft Corporation.All rights reserved.
-
-// This Source Code Form is subject to the terms of the MIT License.
-// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT.
-// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
-// All Rights Reserved.
-
-
-using System;
-using System.Windows;
-
-namespace Wpf.Ui.Controls.Navigation;
-
-///
-/// Breadcrumb control allows you to keep track and maintain awareness of your locations within .
-///
-public class NavigationViewBreadcrumb : System.Windows.Controls.Control
-{
- ///
- /// Property for .
- ///
- public static readonly DependencyProperty NavigationViewProperty = DependencyProperty.Register(nameof(NavigationView),
- typeof(INavigationView), typeof(NavigationViewBreadcrumb),
- new PropertyMetadata(((NavigationViewBreadcrumb)null!), OnNavigationViewPropertyChanged));
-
- ///
- /// Property for .
- ///
- public static readonly DependencyProperty TextProperty = DependencyProperty.Register(nameof(Text),
- typeof(string), typeof(NavigationViewBreadcrumb),
- new PropertyMetadata(String.Empty));
-
-
- ///
- /// Pinned navigation control.
- ///
- public INavigationView NavigationView
- {
- get => (INavigationView)GetValue(NavigationViewProperty);
- set => SetValue(NavigationViewProperty, value);
- }
-
- ///
- /// Primary breadcrumb navigation element.
- ///
- public string Text
- {
- get => (string)GetValue(TextProperty);
- set => SetValue(TextProperty, value);
- }
-
- public NavigationViewBreadcrumb()
- {
- if (NavigationView != null)
- UpdateRenderedItems();
- }
-
- ///
- /// This virtual method is called when the is changed.
- ///
- protected virtual void OnNavigationViewChanged()
- {
- if (NavigationView == null)
- return;
-
- NavigationView.SelectionChanged -= OnNavigationViewSelectionChanged;
- NavigationView.SelectionChanged += OnNavigationViewSelectionChanged;
- }
-
- ///
- /// This virtual method is called when the of the is changed.
- ///
- protected virtual void OnNavigationViewSelectionChanged(object sender, RoutedEventArgs e)
- {
- UpdateRenderedItems();
- }
-
- private static void OnNavigationViewPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- if (d is not NavigationViewBreadcrumb breadcrumb)
- return;
-
- breadcrumb.OnNavigationViewChanged();
- }
-
- private void UpdateRenderedItems()
- {
- if (NavigationView.SelectedItem is not NavigationViewItem navigationViewItem)
- {
- Text = String.Empty;
-
- return;
- }
-
- // TODO: Multilevel
- Text = navigationViewItem.Content?.ToString() ?? String.Empty;
- }
-}
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationViewBreadcrumbItem.cs b/src/Wpf.Ui/Controls/Navigation/NavigationViewBreadcrumbItem.cs
new file mode 100644
index 000000000..96fbd38f2
--- /dev/null
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationViewBreadcrumbItem.cs
@@ -0,0 +1,13 @@
+namespace Wpf.Ui.Controls.Navigation;
+
+internal class NavigationViewBreadcrumbItem
+{
+ public NavigationViewBreadcrumbItem(INavigationViewItem item)
+ {
+ Content = item.Content;
+ PageId = item.Id;
+ }
+
+ public object Content { get; }
+ public object PageId { get; }
+}
diff --git a/src/Wpf.Ui/Styles/Controls/BreadcrumbBar.xaml b/src/Wpf.Ui/Styles/Controls/BreadcrumbBar.xaml
index 2d26c1cf0..ecabfe128 100644
--- a/src/Wpf.Ui/Styles/Controls/BreadcrumbBar.xaml
+++ b/src/Wpf.Ui/Styles/Controls/BreadcrumbBar.xaml
@@ -13,7 +13,7 @@
-
-
\ No newline at end of file
diff --git a/src/Wpf.Ui/Styles/Controls/NavigationViewBreadcrumbItem.xaml b/src/Wpf.Ui/Styles/Controls/NavigationViewBreadcrumbItem.xaml
new file mode 100644
index 000000000..f483140d6
--- /dev/null
+++ b/src/Wpf.Ui/Styles/Controls/NavigationViewBreadcrumbItem.xaml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Wpf.Ui/Styles/Wpf.Ui.xaml b/src/Wpf.Ui/Styles/Wpf.Ui.xaml
index 86d1b702c..956245665 100644
--- a/src/Wpf.Ui/Styles/Wpf.Ui.xaml
+++ b/src/Wpf.Ui/Styles/Wpf.Ui.xaml
@@ -53,7 +53,7 @@
-
+
From da11d1e76994c89e8728dfedba44236148045957 Mon Sep 17 00:00:00 2001
From: Ivan Dmitriev <42055372+IvanDmitriev1@users.noreply.github.com>
Date: Wed, 25 Jan 2023 20:50:25 +0600
Subject: [PATCH 04/27] added dictionaries
PageTagNavigationViewsDictionary , PageIdNavigationViewsDictionary , PageTypeNavigationViewsDictionary
---
.../Navigation/NavigationView.Base.cs | 58 +++++++++++++------
.../Navigation/NavigationView.Navigation.cs | 19 ++----
2 files changed, 46 insertions(+), 31 deletions(-)
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs b/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs
index 168c9505d..8a4630d9d 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs
@@ -8,6 +8,7 @@
using System;
using System.Collections;
+using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
@@ -28,6 +29,10 @@ public partial class NavigationView : System.Windows.Controls.Control, INavigati
private readonly ObservableCollection _autoSuggestBoxItems = new();
private readonly ObservableCollection _breadcrumbBarItems = new();
+ protected Dictionary PageTagNavigationViewsDictionary = new();
+ protected Dictionary PageIdNavigationViewsDictionary = new();
+ protected Dictionary PageTypeNavigationViewsDictionary = new();
+
///
public INavigationViewItem? SelectedItem { get; private set; }
@@ -75,6 +80,9 @@ protected override void OnInitialized(EventArgs e)
UpdateAutoSuggestBoxSuggestions();
UpdateSelectionForMenuItems();
+
+ AddItemsToDictionariesFromMenuItems(MenuItems);
+ AddItemsToDictionariesFromMenuItems(FooterMenuItems);
}
private void OnLoaded(object sender, RoutedEventArgs e)
@@ -134,6 +142,8 @@ protected virtual void OnMenuItemsChanged()
UpdateAutoSuggestBoxSuggestions();
UpdateSelectionForMenuItems();
+
+ AddItemsToDictionariesFromMenuItems(MenuItems);
}
///
@@ -143,6 +153,8 @@ protected virtual void OnFooterMenuItemsChanged()
{
UpdateAutoSuggestBoxSuggestions();
UpdateSelectionForMenuItems();
+
+ AddItemsToDictionariesFromMenuItems(FooterMenuItems);
}
///
@@ -213,6 +225,33 @@ protected void AutoSuggestBoxOnSuggestionChosen(object sender, RoutedEventArgs e
NavigateToMenuItemFromAutoSuggestBox(FooterMenuItems, selectedSuggestBoxItem);
}
+ protected void AddItemsToDictionariesFromMenuItems(IList? list)
+ {
+ if (list is null)
+ return;
+
+ foreach (var singleMenuItem in list)
+ {
+ if (singleMenuItem is not INavigationViewItem singleNavigationViewItem)
+ continue;
+
+ if (!PageIdNavigationViewsDictionary.ContainsKey(singleNavigationViewItem.Id))
+ PageIdNavigationViewsDictionary.Add(singleNavigationViewItem.Id, singleNavigationViewItem);
+
+ if (!PageTagNavigationViewsDictionary.ContainsKey(singleNavigationViewItem.TargetPageTag))
+ PageTagNavigationViewsDictionary.Add(singleNavigationViewItem.TargetPageTag, singleNavigationViewItem);
+
+ if (singleNavigationViewItem.TargetPageType is not null && !PageTypeNavigationViewsDictionary.ContainsKey(singleNavigationViewItem.TargetPageType))
+ PageTypeNavigationViewsDictionary.Add(singleNavigationViewItem.TargetPageType, singleNavigationViewItem);
+
+
+ if (!(singleNavigationViewItem.MenuItems?.Count > 0))
+ continue;
+
+ AddItemsToDictionariesFromMenuItems(singleNavigationViewItem.MenuItems);
+ }
+ }
+
private void AddItemsToAutoSuggestBoxItemsForMenuItems(IList? list)
{
if (list is null)
@@ -229,12 +268,7 @@ private void AddItemsToAutoSuggestBoxItemsForMenuItems(IList? list)
if (!(singleNavigationViewItem.MenuItems?.Count > 0))
continue;
- foreach (var subMenuItem in singleNavigationViewItem.MenuItems)
- {
- if (subMenuItem is NavigationViewItem { Content: string subContent, TargetPageType: not null } && !string.IsNullOrWhiteSpace(subContent))
- _autoSuggestBoxItems.Add(subContent);
- }
-
+ AddItemsToAutoSuggestBoxItemsForMenuItems(singleNavigationViewItem.MenuItems);
}
}
@@ -260,17 +294,7 @@ private bool NavigateToMenuItemFromAutoSuggestBox(IList? list, string selectedSu
if (!(singleNavigationViewItem.MenuItems?.Count > 0))
continue;
- foreach (var subMenuItem in singleNavigationViewItem.MenuItems)
- {
- if (subMenuItem is not NavigationViewItem { Content: string subContent } subMenuNavigationViewItem || subContent != selectedSuggestBoxItem)
- continue;
-
- NavigateInternal(subMenuNavigationViewItem, null, true, false);
- subMenuNavigationViewItem.BringIntoView();
- subMenuNavigationViewItem.Focus();
-
- return true;
- }
+ NavigateToMenuItemFromAutoSuggestBox(singleNavigationViewItem.MenuItems, selectedSuggestBoxItem);
}
return false;
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs b/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
index c4bf5b936..a015d6f92 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
@@ -20,12 +20,11 @@ namespace Wpf.Ui.Controls.Navigation;
public partial class NavigationView
{
- private IServiceProvider? _serviceProvider = null;
-
- private IPageService? _pageService = null;
-
private readonly List _journal = new();
+ private IServiceProvider? _serviceProvider;
+ private IPageService? _pageService;
+
private int _currentIndexInJournal = 0;
///
@@ -41,11 +40,7 @@ public void SetServiceProvider(IServiceProvider serviceProvider)
=> _serviceProvider = serviceProvider;
///
- public bool Navigate(Type pageType)
- => Navigate(pageType, null!);
-
- ///
- public bool Navigate(Type pageType, object dataContext)
+ public bool Navigate(Type pageType, object? dataContext = null)
{
if (MenuItems is IEnumerable enumerableMenuItems)
foreach (var singleMenuItem in enumerableMenuItems)
@@ -79,11 +74,7 @@ public bool Navigate(Type pageType, object dataContext)
}
///
- public bool Navigate(string pageIdOrTargetTag)
- => Navigate(pageIdOrTargetTag, null!);
-
- ///
- public bool Navigate(string pageIdOrTargetTag, object dataContext)
+ public bool Navigate(string pageIdOrTargetTag, object? dataContext = null)
{
if (MenuItems is IEnumerable enumerableMenuItems)
foreach (var singleMenuItem in enumerableMenuItems)
From da992b5b454e45617cfd5fc98fffdf20723b35ff Mon Sep 17 00:00:00 2001
From: Ivan Dmitriev <42055372+IvanDmitriev1@users.noreply.github.com>
Date: Wed, 25 Jan 2023 20:57:58 +0600
Subject: [PATCH 05/27] start using NavigationViewsDictionary dictionaries
---
.../Navigation/NavigationView.Base.cs | 11 ++---
.../Navigation/NavigationView.Navigation.cs | 47 +++----------------
2 files changed, 11 insertions(+), 47 deletions(-)
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs b/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs
index 8a4630d9d..0954572e4 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs
@@ -29,8 +29,7 @@ public partial class NavigationView : System.Windows.Controls.Control, INavigati
private readonly ObservableCollection _autoSuggestBoxItems = new();
private readonly ObservableCollection _breadcrumbBarItems = new();
- protected Dictionary PageTagNavigationViewsDictionary = new();
- protected Dictionary PageIdNavigationViewsDictionary = new();
+ protected Dictionary PageIdOrTargetTagNavigationViewsDictionary = new();
protected Dictionary PageTypeNavigationViewsDictionary = new();
///
@@ -235,11 +234,11 @@ protected void AddItemsToDictionariesFromMenuItems(IList? list)
if (singleMenuItem is not INavigationViewItem singleNavigationViewItem)
continue;
- if (!PageIdNavigationViewsDictionary.ContainsKey(singleNavigationViewItem.Id))
- PageIdNavigationViewsDictionary.Add(singleNavigationViewItem.Id, singleNavigationViewItem);
+ if (!PageIdOrTargetTagNavigationViewsDictionary.ContainsKey(singleNavigationViewItem.Id))
+ PageIdOrTargetTagNavigationViewsDictionary.Add(singleNavigationViewItem.Id, singleNavigationViewItem);
- if (!PageTagNavigationViewsDictionary.ContainsKey(singleNavigationViewItem.TargetPageTag))
- PageTagNavigationViewsDictionary.Add(singleNavigationViewItem.TargetPageTag, singleNavigationViewItem);
+ if (!PageIdOrTargetTagNavigationViewsDictionary.ContainsKey(singleNavigationViewItem.TargetPageTag))
+ PageIdOrTargetTagNavigationViewsDictionary.Add(singleNavigationViewItem.TargetPageTag, singleNavigationViewItem);
if (singleNavigationViewItem.TargetPageType is not null && !PageTypeNavigationViewsDictionary.ContainsKey(singleNavigationViewItem.TargetPageType))
PageTypeNavigationViewsDictionary.Add(singleNavigationViewItem.TargetPageType, singleNavigationViewItem);
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs b/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
index a015d6f92..850d242bb 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
@@ -42,54 +42,19 @@ public void SetServiceProvider(IServiceProvider serviceProvider)
///
public bool Navigate(Type pageType, object? dataContext = null)
{
- if (MenuItems is IEnumerable enumerableMenuItems)
- foreach (var singleMenuItem in enumerableMenuItems)
- if (singleMenuItem is NavigationViewItem singleNavigationViewItem)
- {
- if (singleNavigationViewItem.TargetPageType != null && singleNavigationViewItem.TargetPageType == pageType)
- return NavigateInternal(singleNavigationViewItem, dataContext, true, true); ;
-
- if (singleNavigationViewItem?.MenuItems?.Count > 0)
- foreach (var subMenuItem in singleNavigationViewItem.MenuItems)
- if (subMenuItem is NavigationViewItem subMenuNavigationViewItem)
- if (subMenuNavigationViewItem.TargetPageType != null && subMenuNavigationViewItem.TargetPageType == pageType)
- return NavigateInternal(subMenuNavigationViewItem, dataContext, true, true);
- }
-
- if (FooterMenuItems is IEnumerable enumerableFooterMenuItems)
- foreach (var singleMenuItem in enumerableFooterMenuItems)
- if (singleMenuItem is NavigationViewItem singleNavigationViewItem)
- {
- if (singleNavigationViewItem.TargetPageType != null && singleNavigationViewItem.TargetPageType == pageType)
- return NavigateInternal(singleNavigationViewItem, dataContext, true, true);
-
- if (singleNavigationViewItem?.MenuItems?.Count > 0)
- foreach (var subMenuItem in singleNavigationViewItem.MenuItems)
- if (subMenuItem is NavigationViewItem subMenuNavigationViewItem)
- if (subMenuNavigationViewItem.TargetPageType != null && subMenuNavigationViewItem.TargetPageType == pageType)
- return NavigateInternal(subMenuNavigationViewItem, dataContext, true, true);
- }
+ if (!PageTypeNavigationViewsDictionary.TryGetValue(pageType, out var navigationViewItem))
+ return false;
- return false;
+ return NavigateInternal(navigationViewItem, dataContext, true, true);
}
///
public bool Navigate(string pageIdOrTargetTag, object? dataContext = null)
{
- if (MenuItems is IEnumerable enumerableMenuItems)
- foreach (var singleMenuItem in enumerableMenuItems)
- if (singleMenuItem is NavigationViewItem singleNavigationViewItem)
- if (singleNavigationViewItem.Id == pageIdOrTargetTag || singleNavigationViewItem?.TargetPageTag == pageIdOrTargetTag)
- return NavigateInternal(singleNavigationViewItem, dataContext, true, true);
-
- if (FooterMenuItems is IEnumerable enumerableFooterMenuItems)
- foreach (var singleMenuItem in enumerableFooterMenuItems)
- if (singleMenuItem is NavigationViewItem singleNavigationViewItem)
- if (singleNavigationViewItem.Id == pageIdOrTargetTag ||
- singleNavigationViewItem?.TargetPageTag == pageIdOrTargetTag)
- return NavigateInternal(singleNavigationViewItem, dataContext, true, true);
+ if (!PageIdOrTargetTagNavigationViewsDictionary.TryGetValue(pageIdOrTargetTag, out var navigationViewItem))
+ return false;
- return false;
+ return NavigateInternal(navigationViewItem, dataContext, true, true);
}
///
From 55ce6bb24f21c7652d0a4ce4d0bc6a54679ae2b3 Mon Sep 17 00:00:00 2001
From: Ivan Dmitriev <42055372+IvanDmitriev1@users.noreply.github.com>
Date: Wed, 25 Jan 2023 21:38:13 +0600
Subject: [PATCH 06/27] moved navigation aware login to the
NavigationViewContentPresenter
---
.../Navigation/NavigationView.Base.cs | 2 -
.../Navigation/NavigationView.Navigation.cs | 62 +--------------
.../NavigationView.TemplateParts.cs | 1 -
.../NavigationViewContentPresenter.cs | 76 +++++++++++++++++++
.../Styles/Controls/NavigationView.xaml | 8 +-
5 files changed, 85 insertions(+), 64 deletions(-)
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs b/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs
index 0954572e4..e701e1c97 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs
@@ -98,8 +98,6 @@ protected virtual void OnUnloaded(object sender, RoutedEventArgs e)
Unloaded -= OnUnloaded;
SizeChanged -= OnSizeChanged;
- NavigationViewContentPresenter.Navigated -= OnNavigationViewContentPresenterNavigated;
-
if (AutoSuggestBox is not null)
AutoSuggestBox.SuggestionChosen -= AutoSuggestBoxOnSuggestionChosen;
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs b/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
index 850d242bb..cabe44f43 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
@@ -6,14 +6,11 @@
// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
// All Rights Reserved.
-#nullable enable
-
using System;
using System.Collections;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Windows;
-using System.Windows.Navigation;
-using Wpf.Ui.Animations;
using Wpf.Ui.Contracts;
namespace Wpf.Ui.Controls.Navigation;
@@ -136,9 +133,7 @@ private bool NavigateInternal(INavigationViewItem viewItem, object? dataContext,
IsBackEnabled = _journal.Count > 0;
-#if DEBUG
- System.Diagnostics.Debug.WriteLine($"DEBUG | {viewItem.Id} - {viewItem.TargetPageTag ?? "NO_TAG"} | NAVIGATED");
-#endif
+ Debug.WriteLine($"DEBUG | {viewItem.Id} - {viewItem.TargetPageTag ?? "NO_TAG"} | NAVIGATED");
RenderSelectedItemContent(viewItem, dataContext);
@@ -223,61 +218,10 @@ private void RenderSelectedItemContent(INavigationViewItem viewItem, object? dat
private void UpdateContent(object? content, object? dataContext)
{
- if (NavigationViewContentPresenter == null)
- return;
-
- NotifyContentAboutNavigatingFrom(NavigationViewContentPresenter?.Content ?? null);
-
if (dataContext != null && content is FrameworkElement frameworkViewContent)
frameworkViewContent.DataContext = dataContext;
- NavigationViewContentPresenter!.Navigate(content);
- }
-
- protected virtual void OnNavigationViewContentPresenterNavigated(object sender, NavigationEventArgs e)
- {
- if (sender is not NavigationViewContentPresenter contentPresenter)
- return;
-
- NotifyContentAboutNavigatingTo(contentPresenter?.Content ?? null);
-
- if (contentPresenter != null)
- ApplyTransitionEffectToNavigatedPage(contentPresenter);
- }
-
- private void NotifyContentAboutNavigatingFrom(object? content)
- {
- if (content is INavigationAware navigationAwareNavigationContent)
- navigationAwareNavigationContent.OnNavigatedFrom();
-
- if (content is INavigableView navigableView && navigableView.ViewModel is INavigationAware navigationAwareNavigableViewViewModel)
- navigationAwareNavigableViewViewModel.OnNavigatedFrom();
-
- if (content is FrameworkElement { DataContext: INavigationAware navigationAwareCurrentContent })
- navigationAwareCurrentContent.OnNavigatedFrom();
- }
-
- private void NotifyContentAboutNavigatingTo(object? content)
- {
- if (content is INavigationAware navigationAwareNavigationContent)
- navigationAwareNavigationContent.OnNavigatedTo();
-
- if (content is INavigableView navigableView && navigableView.ViewModel is INavigationAware navigationAwareNavigableViewViewModel)
- navigationAwareNavigableViewViewModel.OnNavigatedTo();
-
- if (content is FrameworkElement { DataContext: INavigationAware navigationAwareCurrentContent })
- navigationAwareCurrentContent.OnNavigatedTo();
- }
-
- private void ApplyTransitionEffectToNavigatedPage(NavigationViewContentPresenter contentPresenter)
- {
- if (TransitionDuration < 1)
- return;
-
- if (contentPresenter.Content == null)
- return;
-
- Transitions.ApplyTransition(contentPresenter.Content, TransitionType, TransitionDuration);
+ NavigationViewContentPresenter.Navigate(content);
}
private void UpdateSelectionForMenuItems()
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationView.TemplateParts.cs b/src/Wpf.Ui/Controls/Navigation/NavigationView.TemplateParts.cs
index 282ad79b3..5ae6c5f2e 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationView.TemplateParts.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationView.TemplateParts.cs
@@ -77,7 +77,6 @@ public override void OnApplyTemplate()
MenuItemsItemsControl = GetTemplateChild(TemplateElementMenuItemsItemsControl);
FooterMenuItemsItemsControl = GetTemplateChild(TemplateElementFooterMenuItemsItemsControl);
- NavigationViewContentPresenter.Navigated += OnNavigationViewContentPresenterNavigated;
MenuItemsItemsControl.ItemsSource = MenuItems;
FooterMenuItemsItemsControl.ItemsSource = FooterMenuItems;
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationViewContentPresenter.cs b/src/Wpf.Ui/Controls/Navigation/NavigationViewContentPresenter.cs
index 3fd80966c..47578afa5 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationViewContentPresenter.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationViewContentPresenter.cs
@@ -6,14 +6,47 @@
// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
// All Rights Reserved.
+using System;
+using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
+using Wpf.Ui.Animations;
namespace Wpf.Ui.Controls.Navigation;
public class NavigationViewContentPresenter : Frame
{
+ ///
+ /// Property for .
+ ///
+ public static readonly DependencyProperty TransitionDurationProperty =
+ DependencyProperty.Register(nameof(TransitionDuration), typeof(int), typeof(NavigationViewContentPresenter),
+ new FrameworkPropertyMetadata(200));
+
+ ///
+ /// Property for .
+ ///
+ public static readonly DependencyProperty TransitionTypeProperty =
+ DependencyProperty.Register(nameof(TransitionType), typeof(TransitionType),
+ typeof(NavigationViewContentPresenter), new FrameworkPropertyMetadata(TransitionType.FadeInWithSlide));
+
+ [Bindable(true), Category("Appearance")]
+ public int TransitionDuration
+ {
+ get => (int)GetValue(TransitionDurationProperty);
+ set => SetValue(TransitionDurationProperty, value);
+ }
+
+ ///
+ /// Gets or sets type of transitions during navigation.
+ ///
+ public TransitionType TransitionType
+ {
+ get => (TransitionType)GetValue(TransitionTypeProperty);
+ set => SetValue(TransitionTypeProperty, value);
+ }
+
static NavigationViewContentPresenter()
{
DefaultStyleKeyProperty.OverrideMetadata(
@@ -32,4 +65,47 @@ static NavigationViewContentPresenter()
typeof(NavigationViewContentPresenter),
new FrameworkPropertyMetadata(JournalOwnership.UsesParentJournal));
}
+
+ protected override void OnInitialized(EventArgs e)
+ {
+ base.OnInitialized(e);
+
+ Navigating += static (_, eventArgs) =>
+ {
+ if (eventArgs.Content is null)
+ return;
+
+ NotifyContentAboutNavigatingTo(eventArgs.Content);
+ };
+
+ Navigated += (sender, eventArgs) =>
+ {
+ var self = (NavigationViewContentPresenter)sender;
+
+ if (eventArgs.Content is null)
+ return;
+
+ self.ApplyTransitionEffectToNavigatedPage(eventArgs.Content);
+ };
+ }
+
+ private static void NotifyContentAboutNavigatingTo(object content)
+ {
+ if (content is INavigationAware navigationAwareNavigationContent)
+ navigationAwareNavigationContent.OnNavigatedTo();
+
+ if (content is INavigableView { ViewModel: INavigationAware navigationAwareNavigableViewViewModel })
+ navigationAwareNavigableViewViewModel.OnNavigatedTo();
+
+ if (content is FrameworkElement { DataContext: INavigationAware navigationAwareCurrentContent })
+ navigationAwareCurrentContent.OnNavigatedTo();
+ }
+
+ private void ApplyTransitionEffectToNavigatedPage(object content)
+ {
+ if (TransitionDuration < 1)
+ return;
+
+ Transitions.ApplyTransition(content, TransitionType, TransitionDuration);
+ }
}
diff --git a/src/Wpf.Ui/Styles/Controls/NavigationView.xaml b/src/Wpf.Ui/Styles/Controls/NavigationView.xaml
index e7c297f38..fe2fadf23 100644
--- a/src/Wpf.Ui/Styles/Controls/NavigationView.xaml
+++ b/src/Wpf.Ui/Styles/Controls/NavigationView.xaml
@@ -621,7 +621,9 @@
+ Margin="{TemplateBinding Padding}"
+ TransitionDuration="{TemplateBinding TransitionDuration}"
+ TransitionType="{TemplateBinding TransitionType}" />
+ Margin="{TemplateBinding Padding}"
+ TransitionDuration="{TemplateBinding TransitionDuration}"
+ TransitionType="{TemplateBinding TransitionType}" />
Date: Wed, 25 Jan 2023 21:57:03 +0600
Subject: [PATCH 07/27] removed duplicate code
---
.../Navigation/NavigationView.Base.cs | 97 +++++++++++++---
.../Navigation/NavigationView.Navigation.cs | 107 ++----------------
.../Navigation/NavigationViewActivator.cs | 14 +--
3 files changed, 94 insertions(+), 124 deletions(-)
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs b/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs
index e701e1c97..e5dba3100 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs
@@ -80,8 +80,7 @@ protected override void OnInitialized(EventArgs e)
UpdateAutoSuggestBoxSuggestions();
UpdateSelectionForMenuItems();
- AddItemsToDictionariesFromMenuItems(MenuItems);
- AddItemsToDictionariesFromMenuItems(FooterMenuItems);
+ AddItemsToDictionaries();
}
private void OnLoaded(object sender, RoutedEventArgs e)
@@ -140,7 +139,7 @@ protected virtual void OnMenuItemsChanged()
UpdateAutoSuggestBoxSuggestions();
UpdateSelectionForMenuItems();
- AddItemsToDictionariesFromMenuItems(MenuItems);
+ AddItemsToDictionaries(MenuItems);
}
///
@@ -151,7 +150,7 @@ protected virtual void OnFooterMenuItemsChanged()
UpdateAutoSuggestBoxSuggestions();
UpdateSelectionForMenuItems();
- AddItemsToDictionariesFromMenuItems(FooterMenuItems);
+ AddItemsToDictionaries(FooterMenuItems);
}
///
@@ -173,8 +172,7 @@ protected virtual void OnPaneDisplayModeChanged()
///
protected virtual void OnItemTemplateChanged()
{
- UpdateMenuItemsTemplate(MenuItems);
- UpdateMenuItemsTemplate(FooterMenuItems);
+ UpdateMenuItemsTemplate();
}
internal void ToggleAllExpands()
@@ -194,21 +192,20 @@ protected virtual void BreadcrumbBarOnItemClicked(BreadcrumbBar sender, Breadcru
}
- protected void UpdateAutoSuggestBoxSuggestions()
+ private void UpdateAutoSuggestBoxSuggestions()
{
if (AutoSuggestBox == null)
return;
_autoSuggestBoxItems.Clear();
- AddItemsToAutoSuggestBoxItemsForMenuItems(MenuItems);
- AddItemsToAutoSuggestBoxItemsForMenuItems(FooterMenuItems);
+ AddItemsToAutoSuggestBoxItems();
}
///
/// Navigate to the page after its name is selected in .
///
- protected void AutoSuggestBoxOnSuggestionChosen(object sender, RoutedEventArgs e)
+ private void AutoSuggestBoxOnSuggestionChosen(object sender, RoutedEventArgs e)
{
if (sender is not AutoSuggestBox { ChosenSuggestion: string selectedSuggestBoxItem })
return;
@@ -222,7 +219,7 @@ protected void AutoSuggestBoxOnSuggestionChosen(object sender, RoutedEventArgs e
NavigateToMenuItemFromAutoSuggestBox(FooterMenuItems, selectedSuggestBoxItem);
}
- protected void AddItemsToDictionariesFromMenuItems(IList? list)
+ protected virtual void AddItemsToDictionaries(IList? list)
{
if (list is null)
return;
@@ -245,11 +242,17 @@ protected void AddItemsToDictionariesFromMenuItems(IList? list)
if (!(singleNavigationViewItem.MenuItems?.Count > 0))
continue;
- AddItemsToDictionariesFromMenuItems(singleNavigationViewItem.MenuItems);
+ AddItemsToDictionaries(singleNavigationViewItem.MenuItems);
}
}
- private void AddItemsToAutoSuggestBoxItemsForMenuItems(IList? list)
+ protected virtual void AddItemsToDictionaries()
+ {
+ AddItemsToDictionaries(MenuItems);
+ AddItemsToDictionaries(FooterMenuItems);
+ }
+
+ protected virtual void AddItemsToAutoSuggestBoxItems(IList? list)
{
if (list is null)
return;
@@ -265,11 +268,17 @@ private void AddItemsToAutoSuggestBoxItemsForMenuItems(IList? list)
if (!(singleNavigationViewItem.MenuItems?.Count > 0))
continue;
- AddItemsToAutoSuggestBoxItemsForMenuItems(singleNavigationViewItem.MenuItems);
+ AddItemsToAutoSuggestBoxItems(singleNavigationViewItem.MenuItems);
}
}
- private bool NavigateToMenuItemFromAutoSuggestBox(IList? list, string selectedSuggestBoxItem)
+ protected virtual void AddItemsToAutoSuggestBoxItems()
+ {
+ AddItemsToAutoSuggestBoxItems(MenuItems);
+ AddItemsToAutoSuggestBoxItems(FooterMenuItems);
+ }
+
+ protected virtual bool NavigateToMenuItemFromAutoSuggestBox(IList? list, string selectedSuggestBoxItem)
{
if (list is null)
return false;
@@ -297,7 +306,7 @@ private bool NavigateToMenuItemFromAutoSuggestBox(IList? list, string selectedSu
return false;
}
- private void UpdateMenuItemsTemplate(IList? list)
+ protected virtual void UpdateMenuItemsTemplate(IList? list)
{
if (list is null)
return;
@@ -311,4 +320,60 @@ private void UpdateMenuItemsTemplate(IList? list)
singleNavigationViewItem.Template = ItemTemplate;
}
}
+
+ protected virtual void UpdateMenuItemsTemplate()
+ {
+ UpdateMenuItemsTemplate(MenuItems);
+ UpdateMenuItemsTemplate(FooterMenuItems);
+ }
+
+ protected virtual void UpdateSelectionForMenuItems(IList? list)
+ {
+ if (list is null)
+ return;
+
+ foreach (var singleMenuItem in list)
+ {
+ if (singleMenuItem is not NavigationViewItem navigationViewItem)
+ continue;
+
+ if (navigationViewItem == SelectedItem)
+ {
+ navigationViewItem.IsActive = true;
+
+ if (navigationViewItem.Icon is SymbolIcon symbolIcon && PaneDisplayMode == NavigationViewPaneDisplayMode.LeftFluent)
+ symbolIcon.Filled = true;
+ }
+ else
+ {
+ navigationViewItem.IsActive = false;
+
+ if (navigationViewItem.Icon is SymbolIcon symbolIcon && PaneDisplayMode == NavigationViewPaneDisplayMode.LeftFluent)
+ symbolIcon.Filled = false;
+ }
+
+ if (navigationViewItem.MenuItems is not IEnumerable enumerableSubMenuItems)
+ continue;
+
+ foreach (var singleSubMenuItem in enumerableSubMenuItems)
+ {
+ if (singleSubMenuItem is not NavigationViewItem navigationViewSubItem)
+ continue;
+
+ if (!navigationViewItem.IsExpanded && navigationViewSubItem == SelectedItem)
+ {
+ navigationViewItem.IsExpanded = true;
+ //navigationViewItem.BringIntoView();
+ }
+
+ navigationViewSubItem.IsActive = navigationViewSubItem == SelectedItem;
+ }
+ }
+ }
+
+ protected virtual void UpdateSelectionForMenuItems()
+ {
+ UpdateSelectionForMenuItems(MenuItems);
+ UpdateSelectionForMenuItems(FooterMenuItems);
+ }
}
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs b/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
index cabe44f43..c63421d61 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
@@ -62,7 +62,7 @@ public bool ReplaceContent(Type? pageTypeToEmbed)
if (_serviceProvider != null)
{
- UpdateContent(_serviceProvider.GetService(pageTypeToEmbed) ?? null!, null!);
+ UpdateContent(_serviceProvider.GetService(pageTypeToEmbed));
return true;
}
@@ -70,19 +70,13 @@ public bool ReplaceContent(Type? pageTypeToEmbed)
if (_pageService == null)
return false;
- UpdateContent(_pageService.GetPage(pageTypeToEmbed) ?? null!, null!);
+ UpdateContent(_pageService.GetPage(pageTypeToEmbed));
return true;
}
///
- public bool ReplaceContent(UIElement pageInstanceToEmbed)
- {
- return ReplaceContent(pageInstanceToEmbed, null!);
- }
-
- ///
- public bool ReplaceContent(UIElement pageInstanceToEmbed, object dataContext)
+ public bool ReplaceContent(UIElement pageInstanceToEmbed, object? dataContext = null)
{
UpdateContent(pageInstanceToEmbed, dataContext);
@@ -100,7 +94,7 @@ public bool GoForward()
if (_currentIndexInJournal > _journal.Count - 1)
return false;
- return Navigate(_journal[_currentIndexInJournal], null!);
+ return Navigate(_journal[_currentIndexInJournal]);
}
///
@@ -142,7 +136,9 @@ private bool NavigateInternal(INavigationViewItem viewItem, object? dataContext,
SelectedItem = viewItem;
- UpdateSelectionForMenuItems();
+ UpdateSelectionForMenuItems(MenuItems);
+ UpdateSelectionForMenuItems(FooterMenuItems);
+
OnSelectionChanged();
if (bringIntoView && viewItem is FrameworkElement frameworkElement)
@@ -157,9 +153,10 @@ private bool NavigateInternal(INavigationViewItem viewItem, object? dataContext,
private void UpdateJournal(INavigationViewItem viewItem)
{
#if DEBUG
- System.Diagnostics.Debug.WriteLine($"JOURNAL INDEX {_currentIndexInJournal}");
+ Debug.WriteLine($"JOURNAL INDEX {_currentIndexInJournal}");
+
if (_journal.Count > 0)
- System.Diagnostics.Debug.WriteLine($"JOURNAL LAST ELEMENT {_journal[_journal.Count - 1]}");
+ Debug.WriteLine($"JOURNAL LAST ELEMENT {_journal[_journal.Count - 1]}");
#endif
if (_journal.Count == 0)
@@ -216,93 +213,11 @@ private void RenderSelectedItemContent(INavigationViewItem viewItem, object? dat
UpdateContent(pageInstance, dataContext);
}
- private void UpdateContent(object? content, object? dataContext)
+ private void UpdateContent(object? content, object? dataContext = null)
{
if (dataContext != null && content is FrameworkElement frameworkViewContent)
frameworkViewContent.DataContext = dataContext;
NavigationViewContentPresenter.Navigate(content);
}
-
- private void UpdateSelectionForMenuItems()
- {
- if (MenuItems is IEnumerable enumerableMenuItems)
- {
- foreach (var singleMenuItem in enumerableMenuItems)
- {
- if (singleMenuItem is not NavigationViewItem navigationViewItem)
- continue;
-
- if (navigationViewItem == SelectedItem)
- {
- navigationViewItem.IsActive = true;
-
- if (navigationViewItem.Icon is SymbolIcon symbolIcon && PaneDisplayMode == NavigationViewPaneDisplayMode.LeftFluent)
- symbolIcon.Filled = true;
- }
- else
- {
- navigationViewItem.IsActive = false;
-
- if (navigationViewItem.Icon is SymbolIcon symbolIcon && PaneDisplayMode == NavigationViewPaneDisplayMode.LeftFluent)
- symbolIcon.Filled = false;
- }
-
- if (navigationViewItem.MenuItems is IEnumerable enumerableSubMenuItems)
- {
- foreach (var singleSubMenuItem in enumerableSubMenuItems)
- {
- if (singleSubMenuItem is not NavigationViewItem navigationViewSubItem)
- continue;
-
- if (!navigationViewItem.IsExpanded && navigationViewSubItem == SelectedItem)
- {
- navigationViewItem.IsExpanded = true;
- //navigationViewItem.BringIntoView();
- }
-
- navigationViewSubItem.IsActive = navigationViewSubItem == SelectedItem;
- }
- }
- }
- }
-
- if (FooterMenuItems is IEnumerable enumerableFooterMenuItems)
- {
- foreach (var singleFooterMenuItem in enumerableFooterMenuItems)
- {
- if (singleFooterMenuItem is not NavigationViewItem navigationViewItem)
- continue;
-
- if (navigationViewItem == SelectedItem)
- {
- navigationViewItem.IsActive = true;
-
- if (navigationViewItem.Icon is SymbolIcon symbolIcon && PaneDisplayMode == NavigationViewPaneDisplayMode.LeftFluent)
- symbolIcon.Filled = true;
- }
- else
- {
- navigationViewItem.IsActive = false;
- }
-
- if (navigationViewItem.MenuItems is IEnumerable enumerableSubMenuItems)
- {
- foreach (var singleSubMenuItem in enumerableSubMenuItems)
- {
- if (singleSubMenuItem is not NavigationViewItem navigationViewSubItem)
- continue;
-
- if (!navigationViewItem.IsExpanded && navigationViewSubItem == SelectedItem)
- {
- navigationViewItem.IsExpanded = true;
- //navigationViewItem.BringIntoView();
- }
-
- navigationViewSubItem.IsActive = navigationViewSubItem == SelectedItem;
- }
- }
- }
- }
- }
}
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationViewActivator.cs b/src/Wpf.Ui/Controls/Navigation/NavigationViewActivator.cs
index 59bbde6f2..5d4a2ecbc 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationViewActivator.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationViewActivator.cs
@@ -17,23 +17,13 @@ namespace Wpf.Ui.Controls.Navigation;
///
internal static class NavigationViewActivator
{
- ///
- /// Creates new instance of type derived from .
- ///
- /// to instantiate.
- /// Instance of the object or .
- public static FrameworkElement CreateInstance(Type pageType)
- {
- return CreateInstance(pageType, null!);
- }
-
///
/// Creates new instance of type derived from .
///
/// to instantiate.
/// Additional context to set.
/// Instance of the object or .
- public static FrameworkElement CreateInstance(Type pageType, object? dataContext)
+ public static FrameworkElement? CreateInstance(Type pageType, object? dataContext = null)
{
if (!typeof(FrameworkElement).IsAssignableFrom(pageType))
throw new InvalidCastException(
@@ -42,7 +32,7 @@ public static FrameworkElement CreateInstance(Type pageType, object? dataContext
if (DesignerHelper.IsInDesignMode)
return new Page { Content = new TextBlock { Text = "Pages are not rendered while using the Designer. Edit the page template directly." } };
- var instance = null as FrameworkElement;
+ FrameworkElement? instance;
#if NET48_OR_GREATER || NETCOREAPP3_0_OR_GREATER
if (ControlsServices.ControlsServiceProvider != null)
From 19d338fc9b84689470b8d554496a9176603005ee Mon Sep 17 00:00:00 2001
From: Ivan Dmitriev <42055372+IvanDmitriev1@users.noreply.github.com>
Date: Thu, 26 Jan 2023 12:52:40 +0600
Subject: [PATCH 08/27] stared implementing navigation stack
---
.../Navigation/INavigationViewItem.cs | 2 +-
.../Navigation/NavigationView.Base.cs | 85 +-------
.../Navigation/NavigationView.Navigation.cs | 203 +++++++++++++-----
.../Navigation/NavigationView.Properties.cs | 22 +-
.../Controls/Navigation/NavigationViewItem.cs | 2 +-
5 files changed, 156 insertions(+), 158 deletions(-)
diff --git a/src/Wpf.Ui/Controls/Navigation/INavigationViewItem.cs b/src/Wpf.Ui/Controls/Navigation/INavigationViewItem.cs
index 82ea73cf0..41e74ff73 100644
--- a/src/Wpf.Ui/Controls/Navigation/INavigationViewItem.cs
+++ b/src/Wpf.Ui/Controls/Navigation/INavigationViewItem.cs
@@ -48,7 +48,7 @@ public interface INavigationViewItem
///
/// Gets information whether the current element is active.
///
- bool IsActive { get; }
+ bool IsActive { get; set; }
///
/// Gets information whether the sub- are expanded.
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs b/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs
index e5dba3100..3aeb99786 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs
@@ -33,7 +33,7 @@ public partial class NavigationView : System.Windows.Controls.Control, INavigati
protected Dictionary PageTypeNavigationViewsDictionary = new();
///
- public INavigationViewItem? SelectedItem { get; private set; }
+ public INavigationViewItem? SelectedItem { get; protected set; }
///
/// Static constructor which overrides default property metadata.
@@ -78,7 +78,7 @@ protected override void OnInitialized(EventArgs e)
UpdateLayout();
UpdateAutoSuggestBoxSuggestions();
- UpdateSelectionForMenuItems();
+ //UpdateSelectionForMenuItems();
AddItemsToDictionaries();
}
@@ -97,6 +97,11 @@ protected virtual void OnUnloaded(object sender, RoutedEventArgs e)
Unloaded -= OnUnloaded;
SizeChanged -= OnSizeChanged;
+ PageIdOrTargetTagNavigationViewsDictionary.Clear();
+ PageTypeNavigationViewsDictionary.Clear();
+
+ ClearJournal();
+
if (AutoSuggestBox is not null)
AutoSuggestBox.SuggestionChosen -= AutoSuggestBoxOnSuggestionChosen;
@@ -127,32 +132,6 @@ protected virtual void OnToggleButtonClick(object sender, RoutedEventArgs e)
Debug.WriteLine("Toggle");
}
- ///
- /// This virtual method is called when source of the menu items is changed.
- ///
- protected virtual void OnMenuItemsChanged()
- {
- InvalidateArrange();
- InvalidateVisual();
- UpdateLayout();
-
- UpdateAutoSuggestBoxSuggestions();
- UpdateSelectionForMenuItems();
-
- AddItemsToDictionaries(MenuItems);
- }
-
- ///
- /// This virtual method is called when source of the footer menu items is changed.
- ///
- protected virtual void OnFooterMenuItemsChanged()
- {
- UpdateAutoSuggestBoxSuggestions();
- UpdateSelectionForMenuItems();
-
- AddItemsToDictionaries(FooterMenuItems);
- }
-
///
/// This virtual method is called when is changed.
///
@@ -326,54 +305,4 @@ protected virtual void UpdateMenuItemsTemplate()
UpdateMenuItemsTemplate(MenuItems);
UpdateMenuItemsTemplate(FooterMenuItems);
}
-
- protected virtual void UpdateSelectionForMenuItems(IList? list)
- {
- if (list is null)
- return;
-
- foreach (var singleMenuItem in list)
- {
- if (singleMenuItem is not NavigationViewItem navigationViewItem)
- continue;
-
- if (navigationViewItem == SelectedItem)
- {
- navigationViewItem.IsActive = true;
-
- if (navigationViewItem.Icon is SymbolIcon symbolIcon && PaneDisplayMode == NavigationViewPaneDisplayMode.LeftFluent)
- symbolIcon.Filled = true;
- }
- else
- {
- navigationViewItem.IsActive = false;
-
- if (navigationViewItem.Icon is SymbolIcon symbolIcon && PaneDisplayMode == NavigationViewPaneDisplayMode.LeftFluent)
- symbolIcon.Filled = false;
- }
-
- if (navigationViewItem.MenuItems is not IEnumerable enumerableSubMenuItems)
- continue;
-
- foreach (var singleSubMenuItem in enumerableSubMenuItems)
- {
- if (singleSubMenuItem is not NavigationViewItem navigationViewSubItem)
- continue;
-
- if (!navigationViewItem.IsExpanded && navigationViewSubItem == SelectedItem)
- {
- navigationViewItem.IsExpanded = true;
- //navigationViewItem.BringIntoView();
- }
-
- navigationViewSubItem.IsActive = navigationViewSubItem == SelectedItem;
- }
- }
- }
-
- protected virtual void UpdateSelectionForMenuItems()
- {
- UpdateSelectionForMenuItems(MenuItems);
- UpdateSelectionForMenuItems(FooterMenuItems);
- }
}
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs b/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
index c63421d61..86b18b120 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
@@ -10,6 +10,8 @@
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
+using System.Linq;
+using System.Reflection;
using System.Windows;
using Wpf.Ui.Contracts;
@@ -17,16 +19,20 @@ namespace Wpf.Ui.Controls.Navigation;
public partial class NavigationView
{
- private readonly List _journal = new();
+ protected readonly List Journal = new();
+ protected readonly List NavigationStack = new();
+
+ private readonly Dictionary _complexNavigationStackHistory = new();
private IServiceProvider? _serviceProvider;
private IPageService? _pageService;
- private int _currentIndexInJournal = 0;
+ private int _currentIndexInJournal;
+ private bool _isBackwardsNavigated;
///
public bool CanGoBack
- => _journal.Count > 1 && _currentIndexInJournal >= 0;
+ => Journal.Count > 1 && _currentIndexInJournal >= 0;
///
public void SetPageService(IPageService pageService)
@@ -37,7 +43,7 @@ public void SetServiceProvider(IServiceProvider serviceProvider)
=> _serviceProvider = serviceProvider;
///
- public bool Navigate(Type pageType, object? dataContext = null)
+ public virtual bool Navigate(Type pageType, object? dataContext = null)
{
if (!PageTypeNavigationViewsDictionary.TryGetValue(pageType, out var navigationViewItem))
return false;
@@ -46,7 +52,7 @@ public bool Navigate(Type pageType, object? dataContext = null)
}
///
- public bool Navigate(string pageIdOrTargetTag, object? dataContext = null)
+ public virtual bool Navigate(string pageIdOrTargetTag, object? dataContext = null)
{
if (!PageIdOrTargetTagNavigationViewsDictionary.TryGetValue(pageIdOrTargetTag, out var navigationViewItem))
return false;
@@ -55,7 +61,7 @@ public bool Navigate(string pageIdOrTargetTag, object? dataContext = null)
}
///
- public bool ReplaceContent(Type? pageTypeToEmbed)
+ public virtual bool ReplaceContent(Type? pageTypeToEmbed)
{
if (pageTypeToEmbed == null)
return false;
@@ -76,7 +82,7 @@ public bool ReplaceContent(Type? pageTypeToEmbed)
}
///
- public bool ReplaceContent(UIElement pageInstanceToEmbed, object? dataContext = null)
+ public virtual bool ReplaceContent(UIElement pageInstanceToEmbed, object? dataContext = null)
{
UpdateContent(pageInstanceToEmbed, dataContext);
@@ -84,49 +90,44 @@ public bool ReplaceContent(UIElement pageInstanceToEmbed, object? dataContext =
}
///
- public bool GoForward()
+ public virtual bool GoForward()
{
- if (_journal.Count <= 1)
+ if (Journal.Count <= 1)
return false;
_currentIndexInJournal += 1;
- if (_currentIndexInJournal > _journal.Count - 1)
+ if (_currentIndexInJournal > Journal.Count - 1)
return false;
- return Navigate(_journal[_currentIndexInJournal]);
+ return Navigate(Journal[_currentIndexInJournal]);
}
///
- public bool GoBack()
+ public virtual bool GoBack()
{
- if (_journal.Count <= 1)
+ if (Journal.Count <= 1)
return false;
- _currentIndexInJournal -= 1;
-
- if (_currentIndexInJournal < 0)
- return false;
-
- return Navigate(_journal[_currentIndexInJournal], null!);
+ var itemId = Journal[Journal.Count - 2];
+ _isBackwardsNavigated = true;
+ return Navigate(itemId);
}
///
- public void ClearJournal()
+ public virtual void ClearJournal()
{
- _journal.Clear();
+ Journal.Clear();
+ NavigationStack.Clear();
+ _complexNavigationStackHistory.Clear();
_currentIndexInJournal = 0;
}
private bool NavigateInternal(INavigationViewItem viewItem, object? dataContext, bool notifyAboutUpdate, bool bringIntoView)
{
- if (viewItem == SelectedItem)
+ if (NavigationStack.Count > 0 && NavigationStack[NavigationStack.Count -1] == viewItem)
return false;
- UpdateJournal(viewItem);
-
- IsBackEnabled = _journal.Count > 0;
-
Debug.WriteLine($"DEBUG | {viewItem.Id} - {viewItem.TargetPageTag ?? "NO_TAG"} | NAVIGATED");
RenderSelectedItemContent(viewItem, dataContext);
@@ -134,11 +135,10 @@ private bool NavigateInternal(INavigationViewItem viewItem, object? dataContext,
if (!notifyAboutUpdate)
return true;
- SelectedItem = viewItem;
-
- UpdateSelectionForMenuItems(MenuItems);
- UpdateSelectionForMenuItems(FooterMenuItems);
+ UpdateCurrentNavigationStackItem(viewItem);
+ AddToJournal(viewItem);
+ UpdateSelectionForMenuItem(viewItem);
OnSelectionChanged();
if (bringIntoView && viewItem is FrameworkElement frameworkElement)
@@ -150,34 +150,10 @@ private bool NavigateInternal(INavigationViewItem viewItem, object? dataContext,
return true;
}
- private void UpdateJournal(INavigationViewItem viewItem)
+ private void AddToJournal(INavigationViewItem viewItem)
{
-#if DEBUG
- Debug.WriteLine($"JOURNAL INDEX {_currentIndexInJournal}");
-
- if (_journal.Count > 0)
- Debug.WriteLine($"JOURNAL LAST ELEMENT {_journal[_journal.Count - 1]}");
-#endif
-
- if (_journal.Count == 0)
- {
- _currentIndexInJournal = 0;
- _journal.Add(viewItem.Id);
-
- return;
- }
-
- // TODO: Fix at last position
-
- if (_currentIndexInJournal == _journal.Count - 1)
- {
- _journal.Add(viewItem.Id);
-
- _currentIndexInJournal++;
- }
-
- if (_journal.Count > 20)
- _journal.RemoveAt(0);
+ Journal.Add(viewItem.Id);
+ IsBackEnabled = CanGoBack;
}
private void RenderSelectedItemContent(INavigationViewItem viewItem, object? dataContext)
@@ -215,9 +191,120 @@ private void RenderSelectedItemContent(INavigationViewItem viewItem, object? dat
private void UpdateContent(object? content, object? dataContext = null)
{
- if (dataContext != null && content is FrameworkElement frameworkViewContent)
+ if (dataContext is not null && content is FrameworkElement frameworkViewContent)
frameworkViewContent.DataContext = dataContext;
NavigationViewContentPresenter.Navigate(content);
}
+
+ private void AddToNavigationStack(INavigationViewItem viewItem)
+ {
+ if (!NavigationStack.Contains(viewItem))
+ NavigationStack.Add(viewItem);
+
+ if (NavigationStack.Count > 1)
+ AddToNavigationStackHistory(viewItem);
+
+ SelectedItem = NavigationStack[NavigationStack.Count - 1];
+ }
+
+ private void UpdateCurrentNavigationStackItem(INavigationViewItem viewItem)
+ {
+ if (NavigationStack.Contains(viewItem))
+ return;
+
+ if (NavigationStack.Count == 0)
+ {
+ NavigationStack.Add(viewItem);
+ }
+ else
+ {
+ NavigationStack[0] = viewItem;
+ }
+
+ SelectedItem = NavigationStack[0];
+ ClearNavigationStack(1);
+ }
+
+ private void RecreateBreadcrumbsFromHistory(INavigationViewItem item)
+ {
+
+ }
+
+ private void AddToNavigationStackHistory(INavigationViewItem viewItem)
+ {
+ var lastItem = NavigationStack[NavigationStack.Count - 1];
+ var startIndex = NavigationStack.IndexOf(viewItem);
+
+ if (startIndex < 0)
+ startIndex = 0;
+
+ _complexNavigationStackHistory.Add(lastItem, new INavigationViewItem[NavigationStack.Count - 1 - startIndex]);
+
+ int i = 0;
+ for (int j = startIndex; j < NavigationStack.Count - 1; j++)
+ {
+ _complexNavigationStackHistory[lastItem][i] = NavigationStack[j];
+ i++;
+ }
+ }
+
+ private void ClearNavigationStack(int navigationStackItemIndex)
+ {
+ var navigationStackCount = NavigationStack.Count;
+ var length = navigationStackCount - navigationStackItemIndex;
+
+ if (length == 0)
+ return;
+
+ INavigationViewItem[] buffer;
+
+#if NET6_0_OR_GREATER
+
+ buffer = System.Buffers.ArrayPool.Shared.Rent(length);
+#else
+ buffer = new INavigationViewItem[length];
+#endif
+
+ int i = 0;
+ for (int j = navigationStackItemIndex; j <= navigationStackCount - 1; j++)
+ {
+ buffer[i] = NavigationStack[j];
+ i++;
+ }
+
+ for (var index = 0; index < length; index++)
+ {
+ var item = buffer[index];
+ NavigationStack.Remove(item);
+ }
+
+#if NET6_0_OR_GREATER
+ System.Buffers.ArrayPool.Shared.Return(buffer, true);
+#endif
+ }
+
+ private void ClearNavigationStack(INavigationViewItem item)
+ {
+
+ }
+
+ private void UpdateSelectionForMenuItem(INavigationViewItem viewItem)
+ {
+ viewItem.IsActive = true;
+
+ if (viewItem.Icon is SymbolIcon symbolIcon && PaneDisplayMode == NavigationViewPaneDisplayMode.LeftFluent)
+ symbolIcon.Filled = true;
+
+ if (Journal.Count == 1)
+ return;
+
+ if (!PageIdOrTargetTagNavigationViewsDictionary.TryGetValue(Journal[Journal.Count - 2], out var previousItem))
+ return;
+
+ previousItem.IsActive = false;
+
+ if (previousItem.Icon is SymbolIcon previousSymbolIcon && PaneDisplayMode == NavigationViewPaneDisplayMode.LeftFluent)
+ previousSymbolIcon.Filled = false;
+ }
}
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationView.Properties.cs b/src/Wpf.Ui/Controls/Navigation/NavigationView.Properties.cs
index 7ecd95a06..f1c7175c0 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationView.Properties.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationView.Properties.cs
@@ -42,8 +42,7 @@ public partial class NavigationView
/// Property for .
///
public static readonly DependencyProperty MenuItemsProperty = DependencyProperty.Register(nameof(MenuItems),
- typeof(IList), typeof(NavigationView),
- new PropertyMetadata(OnMenuItemsPropertyChanged));
+ typeof(IList), typeof(NavigationView));
///
/// Property for .
@@ -56,8 +55,7 @@ public partial class NavigationView
/// Property for .
///
public static readonly DependencyProperty FooterMenuItemsProperty = DependencyProperty.Register(nameof(FooterMenuItemsProperty),
- typeof(IList), typeof(NavigationView),
- new PropertyMetadata(OnFooterMenuItemsPropertyChanged));
+ typeof(IList), typeof(NavigationView));
///
/// Property for .
@@ -343,14 +341,6 @@ public TransitionType TransitionType
set => SetValue(TransitionTypeProperty, value);
}
- private static void OnMenuItemsPropertyChanged(DependencyObject? d, DependencyPropertyChangedEventArgs e)
- {
- if (d is not NavigationView { IsInitialized: true } navigationView)
- return;
-
- navigationView.OnMenuItemsChanged();
- }
-
private static void OnMenuItemsSourcePropertyChanged(DependencyObject? d, DependencyPropertyChangedEventArgs e)
{
if (d is not NavigationView navigationView || e.NewValue is not IList enumerableNewValue)
@@ -359,14 +349,6 @@ private static void OnMenuItemsSourcePropertyChanged(DependencyObject? d, Depend
navigationView.MenuItems = enumerableNewValue;
}
- private static void OnFooterMenuItemsPropertyChanged(DependencyObject? d, DependencyPropertyChangedEventArgs e)
- {
- if (d is not NavigationView { IsInitialized: true } navigationView)
- return;
-
- navigationView.OnFooterMenuItemsChanged();
- }
-
private static void OnFooterMenuItemsSourcePropertyChanged(DependencyObject? d, DependencyPropertyChangedEventArgs e)
{
if (d is not NavigationView navigationView || e.NewValue is not IList enumerableNewValue)
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationViewItem.cs b/src/Wpf.Ui/Controls/Navigation/NavigationViewItem.cs
index cdbe14364..d69934740 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationViewItem.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationViewItem.cs
@@ -113,7 +113,7 @@ public bool HasMenuItems
public bool IsActive
{
get => (bool)GetValue(IsActiveProperty);
- internal set => SetValue(IsActiveProperty, value);
+ set => SetValue(IsActiveProperty, value);
}
///
From 837553b14165dabfee155a082d9ec50597b92a19 Mon Sep 17 00:00:00 2001
From: Ivan Dmitriev <42055372+IvanDmitriev1@users.noreply.github.com>
Date: Thu, 26 Jan 2023 13:38:54 +0600
Subject: [PATCH 09/27] fixed backwards navigation
---
.../Navigation/NavigationView.Navigation.cs | 63 ++++++++++++++-----
1 file changed, 48 insertions(+), 15 deletions(-)
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs b/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
index 86b18b120..968c5de51 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
@@ -19,7 +19,7 @@ namespace Wpf.Ui.Controls.Navigation;
public partial class NavigationView
{
- protected readonly List Journal = new();
+ protected readonly List Journal = new(200);
protected readonly List NavigationStack = new();
private readonly Dictionary _complexNavigationStackHistory = new();
@@ -27,8 +27,8 @@ public partial class NavigationView
private IServiceProvider? _serviceProvider;
private IPageService? _pageService;
- private int _currentIndexInJournal;
private bool _isBackwardsNavigated;
+ private int _currentIndexInJournal;
///
public bool CanGoBack
@@ -92,6 +92,8 @@ public virtual bool ReplaceContent(UIElement pageInstanceToEmbed, object? dataCo
///
public virtual bool GoForward()
{
+ throw new NotImplementedException();
+
if (Journal.Count <= 1)
return false;
@@ -109,8 +111,12 @@ public virtual bool GoBack()
if (Journal.Count <= 1)
return false;
- var itemId = Journal[Journal.Count - 2];
+ if (_currentIndexInJournal <= 1)
+ return false;
+
+ var itemId = Journal[_currentIndexInJournal - 2];
_isBackwardsNavigated = true;
+
return Navigate(itemId);
}
@@ -135,11 +141,9 @@ private bool NavigateInternal(INavigationViewItem viewItem, object? dataContext,
if (!notifyAboutUpdate)
return true;
- UpdateCurrentNavigationStackItem(viewItem);
AddToJournal(viewItem);
-
- UpdateSelectionForMenuItem(viewItem);
- OnSelectionChanged();
+ UpdateCurrentNavigationStackItem(viewItem);
+
if (bringIntoView && viewItem is FrameworkElement frameworkElement)
{
@@ -152,7 +156,25 @@ private bool NavigateInternal(INavigationViewItem viewItem, object? dataContext,
private void AddToJournal(INavigationViewItem viewItem)
{
+#if DEBUG
+ Debug.WriteLine($"JOURNAL INDEX {_currentIndexInJournal}");
+ if (Journal.Count > 0)
+ Debug.WriteLine($"JOURNAL LAST ELEMENT {Journal[Journal.Count - 1]}");
+#endif
+
+ if (_isBackwardsNavigated)
+ {
+ _isBackwardsNavigated = false;
+
+ Journal.RemoveAt(Journal.LastIndexOf(Journal[Journal.Count - 2]));
+ Journal.RemoveAt(Journal.LastIndexOf(Journal[Journal.Count - 1]));
+
+ _currentIndexInJournal -= 2;
+ }
+
Journal.Add(viewItem.Id);
+ _currentIndexInJournal++;
+
IsBackEnabled = CanGoBack;
}
@@ -200,7 +222,11 @@ private void UpdateContent(object? content, object? dataContext = null)
private void AddToNavigationStack(INavigationViewItem viewItem)
{
if (!NavigationStack.Contains(viewItem))
+ {
+ ActivateMenuItem(viewItem);
NavigationStack.Add(viewItem);
+ _breadcrumbBarItems.Add(new NavigationViewBreadcrumbItem(viewItem));
+ }
if (NavigationStack.Count > 1)
AddToNavigationStackHistory(viewItem);
@@ -215,14 +241,22 @@ private void UpdateCurrentNavigationStackItem(INavigationViewItem viewItem)
if (NavigationStack.Count == 0)
{
+ ActivateMenuItem(viewItem);
NavigationStack.Add(viewItem);
+ _breadcrumbBarItems.Add(new NavigationViewBreadcrumbItem(viewItem));
}
else
{
+ DeactivateMenuItem(NavigationStack[0]);
NavigationStack[0] = viewItem;
+ ActivateMenuItem(NavigationStack[0]);
+
+ _breadcrumbBarItems[0] = new NavigationViewBreadcrumbItem(viewItem);
}
SelectedItem = NavigationStack[0];
+ OnSelectionChanged();
+
ClearNavigationStack(1);
}
@@ -289,22 +323,21 @@ private void ClearNavigationStack(INavigationViewItem item)
}
- private void UpdateSelectionForMenuItem(INavigationViewItem viewItem)
+ private void ActivateMenuItem(INavigationViewItem viewItem)
{
viewItem.IsActive = true;
if (viewItem.Icon is SymbolIcon symbolIcon && PaneDisplayMode == NavigationViewPaneDisplayMode.LeftFluent)
symbolIcon.Filled = true;
- if (Journal.Count == 1)
- return;
+ }
- if (!PageIdOrTargetTagNavigationViewsDictionary.TryGetValue(Journal[Journal.Count - 2], out var previousItem))
- return;
+ private void DeactivateMenuItem(INavigationViewItem viewItem)
+ {
+ viewItem.IsActive = false;
- previousItem.IsActive = false;
+ if (viewItem.Icon is SymbolIcon symbolIcon && PaneDisplayMode == NavigationViewPaneDisplayMode.LeftFluent)
+ symbolIcon.Filled = false;
- if (previousItem.Icon is SymbolIcon previousSymbolIcon && PaneDisplayMode == NavigationViewPaneDisplayMode.LeftFluent)
- previousSymbolIcon.Filled = false;
}
}
From 3ff6db0737233f81d9fd35e94ff21f1fda660d25 Mon Sep 17 00:00:00 2001
From: Ivan Dmitriev <42055372+IvanDmitriev1@users.noreply.github.com>
Date: Thu, 26 Jan 2023 15:00:09 +0600
Subject: [PATCH 10/27] added multilevel navigation demo page
---
src/Wpf.Ui.Gallery/App.xaml.cs | 7 ++++
.../ViewModels/Windows/MainWindowViewModel.cs | 1 +
.../Navigation/MultilevelNavigationPage.xaml | 20 +++++++++++
.../MultilevelNavigationPage.xaml.cs | 21 ++++++++++++
.../MultilevelNavigationSamplePage1.xaml | 21 ++++++++++++
.../MultilevelNavigationSamplePage1.xaml.cs | 20 +++++++++++
.../MultilevelNavigationSamplePage2.xaml | 21 ++++++++++++
.../MultilevelNavigationSamplePage2.xaml.cs | 20 +++++++++++
.../MultilevelNavigationSamplePage3.xaml | 21 ++++++++++++
.../MultilevelNavigationSamplePage3.xaml.cs | 20 +++++++++++
src/Wpf.Ui/Contracts/INavigationService.cs | 14 ++++++++
.../Controls/Navigation/INavigationView.cs | 16 +++++++++
.../Navigation/NavigationView.Base.cs | 4 +--
.../Navigation/NavigationView.Navigation.cs | 34 ++++++++++++++-----
.../Navigation/NavigationView.Properties.cs | 26 ++++++++++++--
src/Wpf.Ui/Services/NavigationService.cs | 24 +++++++++++--
16 files changed, 275 insertions(+), 15 deletions(-)
create mode 100644 src/Wpf.Ui.Gallery/Views/Pages/Navigation/MultilevelNavigationPage.xaml
create mode 100644 src/Wpf.Ui.Gallery/Views/Pages/Navigation/MultilevelNavigationPage.xaml.cs
create mode 100644 src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage1.xaml
create mode 100644 src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage1.xaml.cs
create mode 100644 src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage2.xaml
create mode 100644 src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage2.xaml.cs
create mode 100644 src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage3.xaml
create mode 100644 src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage3.xaml.cs
diff --git a/src/Wpf.Ui.Gallery/App.xaml.cs b/src/Wpf.Ui.Gallery/App.xaml.cs
index b3fa34b84..79014b74e 100644
--- a/src/Wpf.Ui.Gallery/App.xaml.cs
+++ b/src/Wpf.Ui.Gallery/App.xaml.cs
@@ -29,6 +29,7 @@
using Wpf.Ui.Gallery.Views.Pages.Icons;
using Wpf.Ui.Gallery.Views.Pages.Media;
using Wpf.Ui.Gallery.Views.Pages.Navigation;
+using Wpf.Ui.Gallery.Views.Pages.Samples;
using Wpf.Ui.Gallery.Views.Pages.StatusAndInfo;
using Wpf.Ui.Gallery.Views.Pages.Text;
using Wpf.Ui.Gallery.Views.Pages.Windows;
@@ -149,10 +150,16 @@ public partial class App : Application
services.AddTransient();
services.AddTransient();
services.AddTransient();
+ services.AddTransient();
services.AddTransient();
services.AddTransient();
services.AddTransient();
+ // Multilevel navigation sample Pages
+ services.AddTransient();
+ services.AddTransient();
+ services.AddTransient();
+
// Status and Info
services.AddTransient();
services.AddTransient();
diff --git a/src/Wpf.Ui.Gallery/ViewModels/Windows/MainWindowViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Windows/MainWindowViewModel.cs
index 3a64ec25c..f5078271a 100644
--- a/src/Wpf.Ui.Gallery/ViewModels/Windows/MainWindowViewModel.cs
+++ b/src/Wpf.Ui.Gallery/ViewModels/Windows/MainWindowViewModel.cs
@@ -91,6 +91,7 @@ public MainWindowViewModel(IServiceProvider serviceProvider)
{
new NavigationViewItem { Content = "BreadcrumbBar", TargetPageType = typeof(BreadcrumbBarPage) },
new NavigationViewItem { Content = "NavigationView", TargetPageType = typeof(NavigationViewPage) },
+ new NavigationViewItem { Content = "Multilevel navigation demo", TargetPageType = typeof(MultilevelNavigationPage) },
new NavigationViewItem { Content = "TabControl", TargetPageType = typeof(TabControlPage) },
}},
new NavigationViewItem {Content = "Status and Info", Icon = new SymbolIcon { Symbol = SymbolRegular.ChatBubblesQuestion24 }, TargetPageType = typeof(StatusAndInfoPage), MenuItems = new ObservableCollection
diff --git a/src/Wpf.Ui.Gallery/Views/Pages/Navigation/MultilevelNavigationPage.xaml b/src/Wpf.Ui.Gallery/Views/Pages/Navigation/MultilevelNavigationPage.xaml
new file mode 100644
index 000000000..40bdaeaef
--- /dev/null
+++ b/src/Wpf.Ui.Gallery/Views/Pages/Navigation/MultilevelNavigationPage.xaml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
diff --git a/src/Wpf.Ui.Gallery/Views/Pages/Navigation/MultilevelNavigationPage.xaml.cs b/src/Wpf.Ui.Gallery/Views/Pages/Navigation/MultilevelNavigationPage.xaml.cs
new file mode 100644
index 000000000..102cb9b82
--- /dev/null
+++ b/src/Wpf.Ui.Gallery/Views/Pages/Navigation/MultilevelNavigationPage.xaml.cs
@@ -0,0 +1,21 @@
+using System.Windows;
+using System.Windows.Controls;
+using Wpf.Ui.Gallery.Views.Pages.Samples;
+
+namespace Wpf.Ui.Gallery.Views.Pages.Navigation;
+
+public partial class MultilevelNavigationPage : Page
+{
+ public MultilevelNavigationPage(INavigationService navigationService)
+ {
+ _navigationService = navigationService;
+ InitializeComponent();
+ }
+
+ private readonly INavigationService _navigationService;
+
+ private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
+ {
+ _navigationService.NavigateWithHierarchy(typeof(MultilevelNavigationSamplePage1));
+ }
+}
diff --git a/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage1.xaml b/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage1.xaml
new file mode 100644
index 000000000..cb843551e
--- /dev/null
+++ b/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage1.xaml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
diff --git a/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage1.xaml.cs b/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage1.xaml.cs
new file mode 100644
index 000000000..0bc09c9db
--- /dev/null
+++ b/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage1.xaml.cs
@@ -0,0 +1,20 @@
+using System.Windows;
+using System.Windows.Controls;
+
+namespace Wpf.Ui.Gallery.Views.Pages.Samples;
+
+public partial class MultilevelNavigationSamplePage1 : Page
+{
+ public MultilevelNavigationSamplePage1(INavigationService navigationService)
+ {
+ _navigationService = navigationService;
+ InitializeComponent();
+ }
+
+ private readonly INavigationService _navigationService;
+
+ private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
+ {
+ _navigationService.NavigateWithHierarchy(typeof(MultilevelNavigationSamplePage2));
+ }
+}
diff --git a/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage2.xaml b/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage2.xaml
new file mode 100644
index 000000000..48ce7810c
--- /dev/null
+++ b/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage2.xaml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
diff --git a/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage2.xaml.cs b/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage2.xaml.cs
new file mode 100644
index 000000000..1f240111f
--- /dev/null
+++ b/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage2.xaml.cs
@@ -0,0 +1,20 @@
+using System.Windows;
+using System.Windows.Controls;
+
+namespace Wpf.Ui.Gallery.Views.Pages.Samples;
+
+public partial class MultilevelNavigationSamplePage2 : Page
+{
+ private readonly INavigationService _navigationService;
+
+ public MultilevelNavigationSamplePage2(INavigationService navigationService)
+ {
+ _navigationService = navigationService;
+ InitializeComponent();
+ }
+
+ private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
+ {
+ _navigationService.NavigateWithHierarchy(typeof(MultilevelNavigationSamplePage3));
+ }
+}
diff --git a/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage3.xaml b/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage3.xaml
new file mode 100644
index 000000000..aef021688
--- /dev/null
+++ b/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage3.xaml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
diff --git a/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage3.xaml.cs b/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage3.xaml.cs
new file mode 100644
index 000000000..7ca3e8a0f
--- /dev/null
+++ b/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage3.xaml.cs
@@ -0,0 +1,20 @@
+using System.Windows;
+using System.Windows.Controls;
+
+namespace Wpf.Ui.Gallery.Views.Pages.Samples;
+
+public partial class MultilevelNavigationSamplePage3 : Page
+{
+ private readonly INavigationService _navigationService;
+
+ public MultilevelNavigationSamplePage3(INavigationService navigationService)
+ {
+ _navigationService = navigationService;
+ InitializeComponent();
+ }
+
+ private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
+ {
+ _navigationService.NavigateWithHierarchy(typeof(MultilevelNavigationSamplePage1));
+ }
+}
diff --git a/src/Wpf.Ui/Contracts/INavigationService.cs b/src/Wpf.Ui/Contracts/INavigationService.cs
index 11f5272c0..8382f9419 100644
--- a/src/Wpf.Ui/Contracts/INavigationService.cs
+++ b/src/Wpf.Ui/Contracts/INavigationService.cs
@@ -43,4 +43,18 @@ public interface INavigationService
///
/// Id or tag of the page.
bool Navigate(string pageIdOrTargetTag);
+
+ ///
+ /// In work
+ ///
+ ///
+ ///
+ bool NavigateWithHierarchy(Type pageType);
+
+ ///
+ /// In work
+ ///
+ ///
+ ///
+ bool NavigateWithHierarchy(string pageIdOrTargetTag);
}
diff --git a/src/Wpf.Ui/Controls/Navigation/INavigationView.cs b/src/Wpf.Ui/Controls/Navigation/INavigationView.cs
index 819425342..51767e3b0 100644
--- a/src/Wpf.Ui/Controls/Navigation/INavigationView.cs
+++ b/src/Wpf.Ui/Controls/Navigation/INavigationView.cs
@@ -179,6 +179,22 @@ public interface INavigationView
///
bool Navigate(string pageIdOrTargetTag, object? dataContext = null);
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ bool NavigateWithHierarchy(Type pageType, object? dataContext = null);
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ bool NavigateWithHierarchy(string pageIdOrTargetTag, object? dataContext = null);
+
///
/// Replaces the contents of the navigation frame, without changing the currently selected item or triggering an .
///
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs b/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs
index 3aeb99786..9688c783e 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs
@@ -163,7 +163,7 @@ internal void OnNavigationViewItemClick(NavigationViewItem navigationViewItem)
{
OnItemInvoked();
- NavigateInternal(navigationViewItem, null, true, false);
+ NavigateInternal(navigationViewItem, null, true, false, false);
}
protected virtual void BreadcrumbBarOnItemClicked(BreadcrumbBar sender, BreadcrumbBarItemClickedEventArgs e)
@@ -269,7 +269,7 @@ protected virtual bool NavigateToMenuItemFromAutoSuggestBox(IList? list, string
if (singleNavigationViewItem.Content is string content && content == selectedSuggestBoxItem)
{
- NavigateInternal(singleNavigationViewItem, null, true, false);
+ NavigateInternal(singleNavigationViewItem, null, true, false, false);
singleNavigationViewItem.BringIntoView();
singleNavigationViewItem.Focus();
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs b/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
index 968c5de51..709ef2399 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
@@ -7,12 +7,10 @@
// All Rights Reserved.
using System;
-using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
-using System.Linq;
-using System.Reflection;
using System.Windows;
+using System.Windows.Controls;
using Wpf.Ui.Contracts;
namespace Wpf.Ui.Controls.Navigation;
@@ -48,7 +46,7 @@ public virtual bool Navigate(Type pageType, object? dataContext = null)
if (!PageTypeNavigationViewsDictionary.TryGetValue(pageType, out var navigationViewItem))
return false;
- return NavigateInternal(navigationViewItem, dataContext, true, true);
+ return NavigateInternal(navigationViewItem, dataContext, true, true, false);
}
///
@@ -57,7 +55,23 @@ public virtual bool Navigate(string pageIdOrTargetTag, object? dataContext = nul
if (!PageIdOrTargetTagNavigationViewsDictionary.TryGetValue(pageIdOrTargetTag, out var navigationViewItem))
return false;
- return NavigateInternal(navigationViewItem, dataContext, true, true);
+ return NavigateInternal(navigationViewItem, dataContext, true, true, false);
+ }
+
+ public virtual bool NavigateWithHierarchy(Type pageType, object? dataContext = null)
+ {
+ if (!PageTypeNavigationViewsDictionary.TryGetValue(pageType, out var navigationViewItem))
+ return false;
+
+ return NavigateInternal(navigationViewItem, dataContext, true, true, true);
+ }
+
+ public virtual bool NavigateWithHierarchy(string pageIdOrTargetTag, object? dataContext = null)
+ {
+ if (!PageIdOrTargetTagNavigationViewsDictionary.TryGetValue(pageIdOrTargetTag, out var navigationViewItem))
+ return false;
+
+ return NavigateInternal(navigationViewItem, dataContext, true, true, true);
}
///
@@ -129,7 +143,7 @@ public virtual void ClearJournal()
_currentIndexInJournal = 0;
}
- private bool NavigateInternal(INavigationViewItem viewItem, object? dataContext, bool notifyAboutUpdate, bool bringIntoView)
+ private bool NavigateInternal(INavigationViewItem viewItem, object? dataContext, bool notifyAboutUpdate, bool bringIntoView, bool addToNavigationStack)
{
if (NavigationStack.Count > 0 && NavigationStack[NavigationStack.Count -1] == viewItem)
return false;
@@ -142,8 +156,12 @@ private bool NavigateInternal(INavigationViewItem viewItem, object? dataContext,
return true;
AddToJournal(viewItem);
- UpdateCurrentNavigationStackItem(viewItem);
-
+
+ if (addToNavigationStack)
+ AddToNavigationStack(viewItem);
+ else
+ UpdateCurrentNavigationStackItem(viewItem);
+
if (bringIntoView && viewItem is FrameworkElement frameworkElement)
{
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationView.Properties.cs b/src/Wpf.Ui/Controls/Navigation/NavigationView.Properties.cs
index f1c7175c0..b3a368a5a 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationView.Properties.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationView.Properties.cs
@@ -7,7 +7,7 @@
// All Rights Reserved.
using System.Collections;
-using System.Collections.Specialized;
+using System.Collections.Generic;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
@@ -64,6 +64,14 @@ public partial class NavigationView
typeof(object), typeof(NavigationView),
new FrameworkPropertyMetadata(null, OnFooterMenuItemsSourcePropertyChanged));
+ ///
+ /// Property for .
+ ///
+ public static readonly DependencyProperty HiddenItemsSourceProperty = DependencyProperty.Register(
+ nameof(HiddenItemsSource),
+ typeof(IReadOnlyList), typeof(NavigationView),
+ new FrameworkPropertyMetadata(null));
+
///
/// Property for .
///
@@ -154,7 +162,7 @@ public partial class NavigationView
public static readonly DependencyProperty ItemTemplateProperty = DependencyProperty.Register(nameof(ItemTemplate),
typeof(ControlTemplate), typeof(NavigationView),
new FrameworkPropertyMetadata(
- (ControlTemplate)null!, // default value
+ null,
FrameworkPropertyMetadataOptions.AffectsMeasure,
new PropertyChangedCallback(OnItemTemplatePropertyChanged)));
@@ -235,6 +243,20 @@ public object? FooterMenuItemsSource
}
}
+ ///
+ [Bindable(true)]
+ public IReadOnlyList? HiddenItemsSource
+ {
+ get => (IReadOnlyList?)GetValue(HiddenItemsSourceProperty);
+ set
+ {
+ if (value == null)
+ ClearValue(HiddenItemsSourceProperty);
+ else
+ SetValue(HiddenItemsSourceProperty, value);
+ }
+ }
+
///
public object? ContentOverlay
{
diff --git a/src/Wpf.Ui/Services/NavigationService.cs b/src/Wpf.Ui/Services/NavigationService.cs
index 52978f758..f918d3905 100644
--- a/src/Wpf.Ui/Services/NavigationService.cs
+++ b/src/Wpf.Ui/Services/NavigationService.cs
@@ -22,12 +22,12 @@ public partial class NavigationService : INavigationService
///
/// Locally attached page service.
///
- private IPageService _pageService;
+ private IPageService? _pageService;
///
/// Control representing navigation.
///
- protected INavigationView NavigationControl;
+ protected INavigationView? NavigationControl;
public NavigationService(IServiceProvider serviceProvider)
{
@@ -37,7 +37,7 @@ public NavigationService(IServiceProvider serviceProvider)
///
public INavigationView GetNavigationControl()
{
- return NavigationControl;
+ return NavigationControl ?? throw new ArgumentNullException(nameof(NavigationControl));
}
///
@@ -85,4 +85,22 @@ public bool Navigate(string pageTag)
return NavigationControl.Navigate(pageTag);
}
+
+ ///
+ public bool NavigateWithHierarchy(Type pageType)
+ {
+ if (NavigationControl == null)
+ return false;
+
+ return NavigationControl.NavigateWithHierarchy(pageType);
+ }
+
+ ///
+ public bool NavigateWithHierarchy(string pageIdOrTargetTag)
+ {
+ if (NavigationControl == null)
+ return false;
+
+ return NavigationControl.NavigateWithHierarchy(pageIdOrTargetTag);
+ }
}
From 1b86771f9ac6c571f0a082ae5fc39e3c7b3743d4 Mon Sep 17 00:00:00 2001
From: Ivan Dmitriev <42055372+IvanDmitriev1@users.noreply.github.com>
Date: Thu, 26 Jan 2023 16:43:22 +0600
Subject: [PATCH 11/27] implemented navigation without INavigationViewItem,
added attached HeaderContent property
---
.../MultilevelNavigationSamplePage1.xaml | 2 +
.../MultilevelNavigationSamplePage2.xaml | 2 +
.../MultilevelNavigationSamplePage3.xaml | 2 +
src/Wpf.Ui/Contracts/INavigationService.cs | 7 --
.../Controls/Navigation/INavigationView.cs | 8 --
.../Navigation/INavigationViewItem.cs | 8 +-
.../NavigationView.AttachedProperties.cs | 19 +++++
.../Navigation/NavigationView.Navigation.cs | 73 ++++++++++---------
.../Navigation/NavigationView.Properties.cs | 22 ------
.../Controls/Navigation/NavigationViewItem.cs | 9 ++-
src/Wpf.Ui/Services/NavigationService.cs | 9 ---
11 files changed, 73 insertions(+), 88 deletions(-)
create mode 100644 src/Wpf.Ui/Controls/Navigation/NavigationView.AttachedProperties.cs
diff --git a/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage1.xaml b/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage1.xaml
index cb843551e..d54794494 100644
--- a/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage1.xaml
+++ b/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage1.xaml
@@ -5,9 +5,11 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Wpf.Ui.Gallery.Views.Pages.Samples"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
Title="MultilevelNavigationSamplePage"
d:DesignHeight="450"
d:DesignWidth="800"
+ ui:NavigationView.HeaderContent="Page 1"
mc:Ignorable="d">
diff --git a/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage2.xaml b/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage2.xaml
index 48ce7810c..1894e2c32 100644
--- a/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage2.xaml
+++ b/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage2.xaml
@@ -5,9 +5,11 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Wpf.Ui.Gallery.Views.Pages.Samples"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
Title="MultilevelNavigationSamplePage2"
d:DesignHeight="450"
d:DesignWidth="800"
+ ui:NavigationView.HeaderContent="Page 2"
mc:Ignorable="d">
diff --git a/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage3.xaml b/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage3.xaml
index aef021688..d1aafe17f 100644
--- a/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage3.xaml
+++ b/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage3.xaml
@@ -5,9 +5,11 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Wpf.Ui.Gallery.Views.Pages.Samples"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
Title="MultilevelNavigationSamplePage3"
d:DesignHeight="450"
d:DesignWidth="800"
+ ui:NavigationView.HeaderContent="Page 3"
mc:Ignorable="d">
diff --git a/src/Wpf.Ui/Contracts/INavigationService.cs b/src/Wpf.Ui/Contracts/INavigationService.cs
index 8382f9419..1b682e730 100644
--- a/src/Wpf.Ui/Contracts/INavigationService.cs
+++ b/src/Wpf.Ui/Contracts/INavigationService.cs
@@ -50,11 +50,4 @@ public interface INavigationService
///
///
bool NavigateWithHierarchy(Type pageType);
-
- ///
- /// In work
- ///
- ///
- ///
- bool NavigateWithHierarchy(string pageIdOrTargetTag);
}
diff --git a/src/Wpf.Ui/Controls/Navigation/INavigationView.cs b/src/Wpf.Ui/Controls/Navigation/INavigationView.cs
index 51767e3b0..89b3c4029 100644
--- a/src/Wpf.Ui/Controls/Navigation/INavigationView.cs
+++ b/src/Wpf.Ui/Controls/Navigation/INavigationView.cs
@@ -187,14 +187,6 @@ public interface INavigationView
///
bool NavigateWithHierarchy(Type pageType, object? dataContext = null);
- ///
- ///
- ///
- ///
- ///
- ///
- bool NavigateWithHierarchy(string pageIdOrTargetTag, object? dataContext = null);
-
///
/// Replaces the contents of the navigation frame, without changing the currently selected item or triggering an .
///
diff --git a/src/Wpf.Ui/Controls/Navigation/INavigationViewItem.cs b/src/Wpf.Ui/Controls/Navigation/INavigationViewItem.cs
index 41e74ff73..824d90e89 100644
--- a/src/Wpf.Ui/Controls/Navigation/INavigationViewItem.cs
+++ b/src/Wpf.Ui/Controls/Navigation/INavigationViewItem.cs
@@ -20,14 +20,14 @@ namespace Wpf.Ui.Controls.Navigation;
public interface INavigationViewItem
{
///
- /// Get or sets content
+ /// Unique identifier that allows the item to be located in the navigation.
///
- object Content { get; }
+ string Id { get; }
///
- /// Unique identifier that allows the item to be located in the navigation.
+ /// Get or sets content
///
- string Id { get; }
+ object Content { get; set; }
///
/// Gets or sets the icon displayed in the MenuItem object.
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationView.AttachedProperties.cs b/src/Wpf.Ui/Controls/Navigation/NavigationView.AttachedProperties.cs
new file mode 100644
index 000000000..5d9b95dd8
--- /dev/null
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationView.AttachedProperties.cs
@@ -0,0 +1,19 @@
+using System.Windows;
+
+namespace Wpf.Ui.Controls.Navigation;
+
+public partial class NavigationView
+{
+ public static readonly DependencyProperty HeaderContentProperty =
+ DependencyProperty.RegisterAttached(
+ "HeaderContent",
+ typeof(object),
+ typeof(FrameworkElement),
+ new FrameworkPropertyMetadata(null)
+ );
+
+
+ public static object? GetHeaderContent(FrameworkElement target) => target.GetValue(HeaderContentProperty);
+
+ public static void SetHeaderContent(FrameworkElement target, object headerContent) => target.SetValue(HeaderContentProperty, headerContent);
+}
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs b/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
index 709ef2399..9ce86b4ca 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
@@ -10,7 +10,6 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows;
-using System.Windows.Controls;
using Wpf.Ui.Contracts;
namespace Wpf.Ui.Controls.Navigation;
@@ -44,7 +43,7 @@ public void SetServiceProvider(IServiceProvider serviceProvider)
public virtual bool Navigate(Type pageType, object? dataContext = null)
{
if (!PageTypeNavigationViewsDictionary.TryGetValue(pageType, out var navigationViewItem))
- return false;
+ return TryToNavigateWithoutINavigationViewItem(pageType, false, dataContext);
return NavigateInternal(navigationViewItem, dataContext, true, true, false);
}
@@ -61,15 +60,7 @@ public virtual bool Navigate(string pageIdOrTargetTag, object? dataContext = nul
public virtual bool NavigateWithHierarchy(Type pageType, object? dataContext = null)
{
if (!PageTypeNavigationViewsDictionary.TryGetValue(pageType, out var navigationViewItem))
- return false;
-
- return NavigateInternal(navigationViewItem, dataContext, true, true, true);
- }
-
- public virtual bool NavigateWithHierarchy(string pageIdOrTargetTag, object? dataContext = null)
- {
- if (!PageIdOrTargetTagNavigationViewsDictionary.TryGetValue(pageIdOrTargetTag, out var navigationViewItem))
- return false;
+ return TryToNavigateWithoutINavigationViewItem(pageType, true, dataContext);
return NavigateInternal(navigationViewItem, dataContext, true, true, true);
}
@@ -143,6 +134,19 @@ public virtual void ClearJournal()
_currentIndexInJournal = 0;
}
+ private bool TryToNavigateWithoutINavigationViewItem(Type pageType, bool addToNavigationStack, object? dataContext = null)
+ {
+ var navigationViewItem = new NavigationViewItem(pageType);
+
+ if (!NavigateInternal(navigationViewItem, dataContext, true, true, addToNavigationStack))
+ return false;
+
+ PageTypeNavigationViewsDictionary.Add(pageType, navigationViewItem);
+ PageIdOrTargetTagNavigationViewsDictionary.Add(navigationViewItem.Id, navigationViewItem);
+
+ return true;
+ }
+
private bool NavigateInternal(INavigationViewItem viewItem, object? dataContext, bool notifyAboutUpdate, bool bringIntoView, bool addToNavigationStack)
{
if (NavigationStack.Count > 0 && NavigationStack[NavigationStack.Count -1] == viewItem)
@@ -196,35 +200,32 @@ private void AddToJournal(INavigationViewItem viewItem)
IsBackEnabled = CanGoBack;
}
- private void RenderSelectedItemContent(INavigationViewItem viewItem, object? dataContext)
+ private object? GetNavigationItemInstance(INavigationViewItem viewItem)
{
- if (_serviceProvider != null)
- {
- if (viewItem.TargetPageType == null)
- return;
+ if (viewItem.TargetPageType is null)
+ return null;
- UpdateContent(_serviceProvider.GetService(viewItem.TargetPageType) ?? null!, dataContext);
-
- return;
+ if (_serviceProvider is not null)
+ {
+ return _serviceProvider.GetService(viewItem.TargetPageType);
}
- if (_pageService != null)
+ if (_pageService is not null)
{
- if (viewItem.TargetPageType == null)
- return;
-
- UpdateContent(_pageService.GetPage(viewItem.TargetPageType) ?? null!, dataContext);
-
- return;
+ return _pageService.GetPage(viewItem.TargetPageType);
}
- if (viewItem.TargetPageType == null)
- return;
+ return NavigationViewActivator.CreateInstance(viewItem.TargetPageType);
+ }
- var pageInstance = NavigationViewActivator.CreateInstance(viewItem.TargetPageType);
+ private void RenderSelectedItemContent(INavigationViewItem viewItem, object? dataContext)
+ {
+ var pageInstance = GetNavigationItemInstance(viewItem);
- if (pageInstance == null)
- return;
+ if (pageInstance is FrameworkElement frameworkElement && GetHeaderContent(frameworkElement) is {} headerContent)
+ {
+ viewItem.Content = headerContent;
+ }
UpdateContent(pageInstance, dataContext);
}
@@ -239,6 +240,9 @@ private void UpdateContent(object? content, object? dataContext = null)
private void AddToNavigationStack(INavigationViewItem viewItem)
{
+ if (_isBackwardsNavigated)
+ RecreateNavigationStackFromHistory(viewItem);
+
if (!NavigationStack.Contains(viewItem))
{
ActivateMenuItem(viewItem);
@@ -250,6 +254,9 @@ private void AddToNavigationStack(INavigationViewItem viewItem)
AddToNavigationStackHistory(viewItem);
SelectedItem = NavigationStack[NavigationStack.Count - 1];
+ OnSelectionChanged();
+
+ ClearNavigationStack(viewItem);
}
private void UpdateCurrentNavigationStackItem(INavigationViewItem viewItem)
@@ -278,7 +285,7 @@ private void UpdateCurrentNavigationStackItem(INavigationViewItem viewItem)
ClearNavigationStack(1);
}
- private void RecreateBreadcrumbsFromHistory(INavigationViewItem item)
+ private void RecreateNavigationStackFromHistory(INavigationViewItem item)
{
}
@@ -347,7 +354,6 @@ private void ActivateMenuItem(INavigationViewItem viewItem)
if (viewItem.Icon is SymbolIcon symbolIcon && PaneDisplayMode == NavigationViewPaneDisplayMode.LeftFluent)
symbolIcon.Filled = true;
-
}
private void DeactivateMenuItem(INavigationViewItem viewItem)
@@ -356,6 +362,5 @@ private void DeactivateMenuItem(INavigationViewItem viewItem)
if (viewItem.Icon is SymbolIcon symbolIcon && PaneDisplayMode == NavigationViewPaneDisplayMode.LeftFluent)
symbolIcon.Filled = false;
-
}
}
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationView.Properties.cs b/src/Wpf.Ui/Controls/Navigation/NavigationView.Properties.cs
index b3a368a5a..6d6007cfd 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationView.Properties.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationView.Properties.cs
@@ -64,14 +64,6 @@ public partial class NavigationView
typeof(object), typeof(NavigationView),
new FrameworkPropertyMetadata(null, OnFooterMenuItemsSourcePropertyChanged));
- ///
- /// Property for .
- ///
- public static readonly DependencyProperty HiddenItemsSourceProperty = DependencyProperty.Register(
- nameof(HiddenItemsSource),
- typeof(IReadOnlyList), typeof(NavigationView),
- new FrameworkPropertyMetadata(null));
-
///
/// Property for .
///
@@ -243,20 +235,6 @@ public object? FooterMenuItemsSource
}
}
- ///
- [Bindable(true)]
- public IReadOnlyList? HiddenItemsSource
- {
- get => (IReadOnlyList?)GetValue(HiddenItemsSourceProperty);
- set
- {
- if (value == null)
- ClearValue(HiddenItemsSourceProperty);
- else
- SetValue(HiddenItemsSourceProperty, value);
- }
- }
-
///
public object? ContentOverlay
{
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationViewItem.cs b/src/Wpf.Ui/Controls/Navigation/NavigationViewItem.cs
index d69934740..7b8fe7fec 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationViewItem.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationViewItem.cs
@@ -161,14 +161,15 @@ public NavigationViewItem()
SetValue(MenuItemsProperty, new ObservableCollection());
}
- public NavigationViewItem(string name, SymbolRegular icon, Type targetPageType)
+ public NavigationViewItem(Type targetPageType) : this()
{
- Id = Guid.NewGuid().ToString("n");
+ SetValue(TargetPageTypeProperty, targetPageType);
+ }
- SetValue(MenuItemsProperty, new ObservableCollection());
+ public NavigationViewItem(string name, SymbolRegular icon, Type targetPageType) : this(targetPageType)
+ {
SetValue(ContentProperty, name);
SetValue(IconProperty, new SymbolIcon { Symbol = icon });
- SetValue(TargetPageTypeProperty, targetPageType);
}
///
diff --git a/src/Wpf.Ui/Services/NavigationService.cs b/src/Wpf.Ui/Services/NavigationService.cs
index f918d3905..b87a9c274 100644
--- a/src/Wpf.Ui/Services/NavigationService.cs
+++ b/src/Wpf.Ui/Services/NavigationService.cs
@@ -94,13 +94,4 @@ public bool NavigateWithHierarchy(Type pageType)
return NavigationControl.NavigateWithHierarchy(pageType);
}
-
- ///
- public bool NavigateWithHierarchy(string pageIdOrTargetTag)
- {
- if (NavigationControl == null)
- return false;
-
- return NavigationControl.NavigateWithHierarchy(pageIdOrTargetTag);
- }
}
From e300d6e23c15ae01ff4ebbd15a1938fee09ef0f5 Mon Sep 17 00:00:00 2001
From: Ivan Dmitriev <42055372+IvanDmitriev1@users.noreply.github.com>
Date: Thu, 26 Jan 2023 18:11:48 +0600
Subject: [PATCH 12/27] implemented ClearNavigationStack method
---
.../NavigationView.AttachedProperties.cs | 2 -
.../Navigation/NavigationView.Base.cs | 31 ++++++++++++-
.../Navigation/NavigationView.Navigation.cs | 43 +++++++++++++++----
.../NavigationViewBreadcrumbItem.cs | 2 +-
4 files changed, 65 insertions(+), 13 deletions(-)
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationView.AttachedProperties.cs b/src/Wpf.Ui/Controls/Navigation/NavigationView.AttachedProperties.cs
index 5d9b95dd8..8e3841aaa 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationView.AttachedProperties.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationView.AttachedProperties.cs
@@ -12,8 +12,6 @@ public partial class NavigationView
new FrameworkPropertyMetadata(null)
);
-
public static object? GetHeaderContent(FrameworkElement target) => target.GetValue(HeaderContentProperty);
-
public static void SetHeaderContent(FrameworkElement target, object headerContent) => target.SetValue(HeaderContentProperty, headerContent);
}
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs b/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs
index 9688c783e..f6df84cbf 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs
@@ -10,6 +10,7 @@
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
+using System.Collections.Specialized;
using System.ComponentModel;
using System.Diagnostics;
using System.Windows;
@@ -85,6 +86,8 @@ protected override void OnInitialized(EventArgs e)
private void OnLoaded(object sender, RoutedEventArgs e)
{
+ NavigationStack.CollectionChanged += NavigationStackOnCollectionChanged;
+
// TODO: Refresh
}
@@ -97,6 +100,8 @@ protected virtual void OnUnloaded(object sender, RoutedEventArgs e)
Unloaded -= OnUnloaded;
SizeChanged -= OnSizeChanged;
+ NavigationStack.CollectionChanged -= NavigationStackOnCollectionChanged;
+
PageIdOrTargetTagNavigationViewsDictionary.Clear();
PageTypeNavigationViewsDictionary.Clear();
@@ -168,7 +173,8 @@ internal void OnNavigationViewItemClick(NavigationViewItem navigationViewItem)
protected virtual void BreadcrumbBarOnItemClicked(BreadcrumbBar sender, BreadcrumbBarItemClickedEventArgs e)
{
-
+ var item = (NavigationViewBreadcrumbItem)e.Item;
+ Navigate(item.PageId);
}
private void UpdateAutoSuggestBoxSuggestions()
@@ -305,4 +311,27 @@ protected virtual void UpdateMenuItemsTemplate()
UpdateMenuItemsTemplate(MenuItems);
UpdateMenuItemsTemplate(FooterMenuItems);
}
+
+ private void NavigationStackOnCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
+ {
+ switch (e.Action)
+ {
+ case NotifyCollectionChangedAction.Add:
+ _breadcrumbBarItems.Add(new NavigationViewBreadcrumbItem((INavigationViewItem)e.NewItems![0]!));
+ break;
+ case NotifyCollectionChangedAction.Remove:
+ _breadcrumbBarItems.RemoveAt(e.OldStartingIndex);
+ break;
+ case NotifyCollectionChangedAction.Replace:
+ _breadcrumbBarItems[0] = new NavigationViewBreadcrumbItem((INavigationViewItem)e.NewItems![0]!);
+ break;
+ case NotifyCollectionChangedAction.Move:
+ break;
+ case NotifyCollectionChangedAction.Reset:
+ _breadcrumbBarItems.Clear();
+ break;
+ default:
+ throw new ArgumentOutOfRangeException();
+ }
+ }
}
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs b/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
index 9ce86b4ca..950b35d4c 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
@@ -8,7 +8,9 @@
using System;
using System.Collections.Generic;
+using System.Collections.ObjectModel;
using System.Diagnostics;
+using System.Reflection;
using System.Windows;
using Wpf.Ui.Contracts;
@@ -17,7 +19,7 @@ namespace Wpf.Ui.Controls.Navigation;
public partial class NavigationView
{
protected readonly List Journal = new(200);
- protected readonly List NavigationStack = new();
+ protected readonly ObservableCollection NavigationStack = new();
private readonly Dictionary _complexNavigationStackHistory = new();
@@ -247,12 +249,8 @@ private void AddToNavigationStack(INavigationViewItem viewItem)
{
ActivateMenuItem(viewItem);
NavigationStack.Add(viewItem);
- _breadcrumbBarItems.Add(new NavigationViewBreadcrumbItem(viewItem));
}
- if (NavigationStack.Count > 1)
- AddToNavigationStackHistory(viewItem);
-
SelectedItem = NavigationStack[NavigationStack.Count - 1];
OnSelectionChanged();
@@ -262,21 +260,24 @@ private void AddToNavigationStack(INavigationViewItem viewItem)
private void UpdateCurrentNavigationStackItem(INavigationViewItem viewItem)
{
if (NavigationStack.Contains(viewItem))
+ {
+ ClearNavigationStack(1);
return;
+ }
+
+ if (NavigationStack.Count > 1)
+ AddToNavigationStackHistory(viewItem);
if (NavigationStack.Count == 0)
{
ActivateMenuItem(viewItem);
NavigationStack.Add(viewItem);
- _breadcrumbBarItems.Add(new NavigationViewBreadcrumbItem(viewItem));
}
else
{
DeactivateMenuItem(NavigationStack[0]);
NavigationStack[0] = viewItem;
ActivateMenuItem(NavigationStack[0]);
-
- _breadcrumbBarItems[0] = new NavigationViewBreadcrumbItem(viewItem);
}
SelectedItem = NavigationStack[0];
@@ -287,7 +288,19 @@ private void UpdateCurrentNavigationStackItem(INavigationViewItem viewItem)
private void RecreateNavigationStackFromHistory(INavigationViewItem item)
{
+ if (!_complexNavigationStackHistory.ContainsKey(item))
+ return;
+
+ var history = _complexNavigationStackHistory[item];
+ var startIndex = 0;
+ for (int i = 0; i < history.Length; i++)
+ {
+ AddToNavigationStack(history[i]);
+ }
+
+ _complexNavigationStackHistory.Remove(item);
+ AddToNavigationStack(item);
}
private void AddToNavigationStackHistory(INavigationViewItem viewItem)
@@ -298,6 +311,9 @@ private void AddToNavigationStackHistory(INavigationViewItem viewItem)
if (startIndex < 0)
startIndex = 0;
+ if (_complexNavigationStackHistory.ContainsKey(lastItem))
+ _complexNavigationStackHistory.Remove(lastItem);
+
_complexNavigationStackHistory.Add(lastItem, new INavigationViewItem[NavigationStack.Count - 1 - startIndex]);
int i = 0;
@@ -345,7 +361,16 @@ private void ClearNavigationStack(int navigationStackItemIndex)
private void ClearNavigationStack(INavigationViewItem item)
{
-
+ var navigationStackCount = NavigationStack.Count;
+ if (navigationStackCount <= 1)
+ return;
+
+ var index = NavigationStack.IndexOf(item);
+ if (index >= navigationStackCount - 1 || _complexNavigationStackHistory.ContainsKey(item))
+ return;
+
+ AddToNavigationStackHistory(item);
+ ClearNavigationStack(++index);
}
private void ActivateMenuItem(INavigationViewItem viewItem)
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationViewBreadcrumbItem.cs b/src/Wpf.Ui/Controls/Navigation/NavigationViewBreadcrumbItem.cs
index 96fbd38f2..822fba5f2 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationViewBreadcrumbItem.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationViewBreadcrumbItem.cs
@@ -9,5 +9,5 @@ public NavigationViewBreadcrumbItem(INavigationViewItem item)
}
public object Content { get; }
- public object PageId { get; }
+ public string PageId { get; }
}
From f5691fe76046bd9a06e256bb64fd78c4db7d1d45 Mon Sep 17 00:00:00 2001
From: Ivan Dmitriev <42055372+IvanDmitriev1@users.noreply.github.com>
Date: Thu, 26 Jan 2023 19:32:40 +0600
Subject: [PATCH 13/27] almost implemented RecreateNavigationStackFromHistory
method
---
.../Views/Windows/MainWindow.xaml | 2 +-
.../Navigation/INavigationViewItem.cs | 11 +++--
.../Navigation/NavigationView.Base.cs | 2 +
.../Navigation/NavigationView.Events.cs | 6 +++
.../Navigation/NavigationView.Navigation.cs | 44 +++++++++++--------
.../Controls/Navigation/NavigationViewItem.cs | 6 +++
6 files changed, 47 insertions(+), 24 deletions(-)
diff --git a/src/Wpf.Ui.Gallery/Views/Windows/MainWindow.xaml b/src/Wpf.Ui.Gallery/Views/Windows/MainWindow.xaml
index d95ac0e18..29fa18b81 100644
--- a/src/Wpf.Ui.Gallery/Views/Windows/MainWindow.xaml
+++ b/src/Wpf.Ui.Gallery/Views/Windows/MainWindow.xaml
@@ -29,7 +29,7 @@
x:Name="NavigationView"
Grid.Row="1"
FooterMenuItemsSource="{Binding ViewModel.FooterMenuItems, Mode=OneWay}"
- IsBackButtonVisible="Collapsed"
+ IsBackButtonVisible="Visible"
IsPaneToggleVisible="False"
MenuItemsSource="{Binding ViewModel.MenuItems, Mode=OneWay}"
PaneDisplayMode="Left"
diff --git a/src/Wpf.Ui/Controls/Navigation/INavigationViewItem.cs b/src/Wpf.Ui/Controls/Navigation/INavigationViewItem.cs
index 824d90e89..201524678 100644
--- a/src/Wpf.Ui/Controls/Navigation/INavigationViewItem.cs
+++ b/src/Wpf.Ui/Controls/Navigation/INavigationViewItem.cs
@@ -58,22 +58,25 @@ public interface INavigationViewItem
///
/// A unique tag used by the parent navigation system for the purpose of searching and navigating.
///
- public string TargetPageTag { get; set; }
+ string TargetPageTag { get; set; }
///
/// The type of the page to be navigated. (Should be derived from ).
///
- public Type? TargetPageType { get; set; }
+ Type? TargetPageType { get; set; }
///
/// Template Property
///
- public ControlTemplate? Template { get; set; }
+ ControlTemplate? Template { get; set; }
///
/// Add / Remove ClickEvent handler.
///
[Category("Behavior")]
- public event RoutedEventHandler Click;
+ event RoutedEventHandler Click;
+
+ internal bool WasInNavigationStack { get; set; }
+ internal bool IsMenuElement {get; set; }
}
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs b/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs
index f6df84cbf..8fc90f4eb 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs
@@ -223,6 +223,7 @@ protected virtual void AddItemsToDictionaries(IList? list)
if (singleNavigationViewItem.TargetPageType is not null && !PageTypeNavigationViewsDictionary.ContainsKey(singleNavigationViewItem.TargetPageType))
PageTypeNavigationViewsDictionary.Add(singleNavigationViewItem.TargetPageType, singleNavigationViewItem);
+ singleNavigationViewItem.IsMenuElement = true;
if (!(singleNavigationViewItem.MenuItems?.Count > 0))
continue;
@@ -312,6 +313,7 @@ protected virtual void UpdateMenuItemsTemplate()
UpdateMenuItemsTemplate(FooterMenuItems);
}
+ [DebuggerStepThrough]
private void NavigationStackOnCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
{
switch (e.Action)
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationView.Events.cs b/src/Wpf.Ui/Controls/Navigation/NavigationView.Events.cs
index 07e01bc64..bfc4253ea 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationView.Events.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationView.Events.cs
@@ -6,6 +6,7 @@
// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
// All Rights Reserved.
+using System.Diagnostics;
using System.Windows;
namespace Wpf.Ui.Controls.Navigation;
@@ -80,6 +81,7 @@ public event NavigationViewEvent BackRequested
///
/// Raises the pane opened event.
///
+ [DebuggerStepThrough]
protected virtual void OnPaneOpened()
{
RaiseEvent(new RoutedEventArgs(PaneOpenedEvent));
@@ -88,6 +90,7 @@ protected virtual void OnPaneOpened()
///
/// Raises the pane closed event.
///
+ [DebuggerStepThrough]
protected virtual void OnPaneClosed()
{
RaiseEvent(new RoutedEventArgs(PaneClosedEvent));
@@ -96,6 +99,7 @@ protected virtual void OnPaneClosed()
///
/// Raises the selection changed event.
///
+ [DebuggerStepThrough]
protected virtual void OnSelectionChanged()
{
RaiseEvent(new RoutedEventArgs(SelectionChangedEvent));
@@ -104,6 +108,7 @@ protected virtual void OnSelectionChanged()
///
/// Raises the item invoked event.
///
+ [DebuggerStepThrough]
protected virtual void OnItemInvoked()
{
RaiseEvent(new RoutedEventArgs(ItemInvokedEvent));
@@ -112,6 +117,7 @@ protected virtual void OnItemInvoked()
///
/// Raises the back requested event.
///
+ [DebuggerStepThrough]
protected virtual void OnBackRequested()
{
RaiseEvent(new RoutedEventArgs(BackRequestedEvent));
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs b/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
index 950b35d4c..552968b2d 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
@@ -161,20 +161,16 @@ private bool NavigateInternal(INavigationViewItem viewItem, object? dataContext,
if (!notifyAboutUpdate)
return true;
+ AddToNavigationStack(viewItem, addToNavigationStack, _isBackwardsNavigated);
AddToJournal(viewItem);
- if (addToNavigationStack)
- AddToNavigationStack(viewItem);
- else
- UpdateCurrentNavigationStackItem(viewItem);
-
-
if (bringIntoView && viewItem is FrameworkElement frameworkElement)
{
frameworkElement.BringIntoView();
frameworkElement.Focus(); // TODO: Element or content?
}
+ _isBackwardsNavigated = false;
return true;
}
@@ -240,17 +236,21 @@ private void UpdateContent(object? content, object? dataContext = null)
NavigationViewContentPresenter.Navigate(content);
}
- private void AddToNavigationStack(INavigationViewItem viewItem)
+ private void AddToNavigationStack(INavigationViewItem viewItem, bool addToNavigationStack, bool isBackwardsNavigated)
{
- if (_isBackwardsNavigated)
+ if (isBackwardsNavigated)
RecreateNavigationStackFromHistory(viewItem);
- if (!NavigationStack.Contains(viewItem))
+ if (addToNavigationStack && !NavigationStack.Contains(viewItem))
{
ActivateMenuItem(viewItem);
NavigationStack.Add(viewItem);
+ //viewItem.WasInNavigationStack = true;
}
+ if (!addToNavigationStack)
+ UpdateCurrentNavigationStackItem(viewItem);
+
SelectedItem = NavigationStack[NavigationStack.Count - 1];
OnSelectionChanged();
@@ -260,10 +260,7 @@ private void AddToNavigationStack(INavigationViewItem viewItem)
private void UpdateCurrentNavigationStackItem(INavigationViewItem viewItem)
{
if (NavigationStack.Contains(viewItem))
- {
- ClearNavigationStack(1);
return;
- }
if (NavigationStack.Count > 1)
AddToNavigationStackHistory(viewItem);
@@ -280,27 +277,36 @@ private void UpdateCurrentNavigationStackItem(INavigationViewItem viewItem)
ActivateMenuItem(NavigationStack[0]);
}
- SelectedItem = NavigationStack[0];
- OnSelectionChanged();
-
ClearNavigationStack(1);
}
private void RecreateNavigationStackFromHistory(INavigationViewItem item)
{
- if (!_complexNavigationStackHistory.ContainsKey(item))
+ if(!_complexNavigationStackHistory.ContainsKey(item))
return;
var history = _complexNavigationStackHistory[item];
var startIndex = 0;
- for (int i = 0; i < history.Length; i++)
+ if (history[0].IsMenuElement)
{
- AddToNavigationStack(history[i]);
+ startIndex = 1;
+
+ DeactivateMenuItem(NavigationStack[0]);
+ NavigationStack[0] = history[0];
+ ActivateMenuItem(NavigationStack[0]);
+ }
+
+ for (int i = startIndex; i < history.Length; i++)
+ {
+ var historyItem = history[i];
+
+ AddToNavigationStack(historyItem, true, false);
+ //historyItem.WasInNavigationStack = false;
}
_complexNavigationStackHistory.Remove(item);
- AddToNavigationStack(item);
+ AddToNavigationStack(item, true, false);
}
private void AddToNavigationStackHistory(INavigationViewItem viewItem)
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationViewItem.cs b/src/Wpf.Ui/Controls/Navigation/NavigationViewItem.cs
index 7b8fe7fec..7fdfaabf4 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationViewItem.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationViewItem.cs
@@ -146,6 +146,12 @@ public Type? TargetPageType
set => SetValue(TargetPageTypeProperty, value);
}
+ ///
+ public bool WasInNavigationStack { get; set; }
+
+ ///
+ public bool IsMenuElement { get; set; }
+
///
public string Id { get; }
From e52b0bd093e205b9803c701e8168c6451980e426 Mon Sep 17 00:00:00 2001
From: Ivan Dmitriev <42055372+IvanDmitriev1@users.noreply.github.com>
Date: Thu, 26 Jan 2023 19:52:14 +0600
Subject: [PATCH 14/27] added a real complex navigation stack history
---
.../Navigation/NavigationView.Navigation.cs | 37 +++++++++++--------
1 file changed, 21 insertions(+), 16 deletions(-)
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs b/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
index 552968b2d..a41d131b4 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
@@ -21,7 +21,7 @@ public partial class NavigationView
protected readonly List Journal = new(200);
protected readonly ObservableCollection NavigationStack = new();
- private readonly Dictionary _complexNavigationStackHistory = new();
+ private readonly Dictionary> _complexNavigationStackHistory = new();
private IServiceProvider? _serviceProvider;
private IPageService? _pageService;
@@ -245,7 +245,6 @@ private void AddToNavigationStack(INavigationViewItem viewItem, bool addToNaviga
{
ActivateMenuItem(viewItem);
NavigationStack.Add(viewItem);
- //viewItem.WasInNavigationStack = true;
}
if (!addToNavigationStack)
@@ -285,27 +284,29 @@ private void RecreateNavigationStackFromHistory(INavigationViewItem item)
if(!_complexNavigationStackHistory.ContainsKey(item))
return;
- var history = _complexNavigationStackHistory[item];
+ var historyList = _complexNavigationStackHistory[item];
+ var latestHistory = historyList[historyList.Count - 1];
+
var startIndex = 0;
- if (history[0].IsMenuElement)
+ if (latestHistory[0].IsMenuElement)
{
startIndex = 1;
DeactivateMenuItem(NavigationStack[0]);
- NavigationStack[0] = history[0];
+ NavigationStack[0] = latestHistory[0];
ActivateMenuItem(NavigationStack[0]);
}
- for (int i = startIndex; i < history.Length; i++)
+ for (int i = startIndex; i < latestHistory.Length; i++)
{
- var historyItem = history[i];
-
- AddToNavigationStack(historyItem, true, false);
- //historyItem.WasInNavigationStack = false;
+ AddToNavigationStack(latestHistory[i], true, false);
}
- _complexNavigationStackHistory.Remove(item);
+ historyList.Remove(latestHistory);
+ if (historyList.Count == 0)
+ _complexNavigationStackHistory.Remove(item);
+
AddToNavigationStack(item, true, false);
}
@@ -317,15 +318,19 @@ private void AddToNavigationStackHistory(INavigationViewItem viewItem)
if (startIndex < 0)
startIndex = 0;
- if (_complexNavigationStackHistory.ContainsKey(lastItem))
- _complexNavigationStackHistory.Remove(lastItem);
+ if (!_complexNavigationStackHistory.TryGetValue(lastItem, out var historyList))
+ {
+ historyList = new List(5);
+ _complexNavigationStackHistory.Add(lastItem, historyList);
+ }
- _complexNavigationStackHistory.Add(lastItem, new INavigationViewItem[NavigationStack.Count - 1 - startIndex]);
+ historyList.Add(new INavigationViewItem[NavigationStack.Count - 1 - startIndex]);
+ var latestHistory = historyList[historyList.Count - 1];
int i = 0;
for (int j = startIndex; j < NavigationStack.Count - 1; j++)
{
- _complexNavigationStackHistory[lastItem][i] = NavigationStack[j];
+ latestHistory[i] = NavigationStack[j];
i++;
}
}
@@ -372,7 +377,7 @@ private void ClearNavigationStack(INavigationViewItem item)
return;
var index = NavigationStack.IndexOf(item);
- if (index >= navigationStackCount - 1 || _complexNavigationStackHistory.ContainsKey(item))
+ if (index >= navigationStackCount - 1)
return;
AddToNavigationStackHistory(item);
From dc2705a5547d43f9911639933bdda475d7f398d8 Mon Sep 17 00:00:00 2001
From: Ivan Dmitriev <42055372+IvanDmitriev1@users.noreply.github.com>
Date: Thu, 26 Jan 2023 20:30:12 +0600
Subject: [PATCH 15/27] moved ActivateMenuItem to the INavigationViewItem
---
.../Navigation/INavigationViewItem.cs | 15 +++--
.../Navigation/NavigationView.Navigation.cs | 49 ++++++-----------
.../Controls/Navigation/NavigationViewItem.cs | 55 ++++++++++++++-----
3 files changed, 71 insertions(+), 48 deletions(-)
diff --git a/src/Wpf.Ui/Controls/Navigation/INavigationViewItem.cs b/src/Wpf.Ui/Controls/Navigation/INavigationViewItem.cs
index 201524678..bdf266386 100644
--- a/src/Wpf.Ui/Controls/Navigation/INavigationViewItem.cs
+++ b/src/Wpf.Ui/Controls/Navigation/INavigationViewItem.cs
@@ -38,7 +38,7 @@ public interface INavigationViewItem
///
/// Gets the collection of menu items displayed in the NavigationView.
///
- IList? MenuItems { get; set; }
+ IList MenuItems { get; set; }
///
/// Gets or sets an object source used to generate the content of the NavigationView menu.
@@ -48,12 +48,12 @@ public interface INavigationViewItem
///
/// Gets information whether the current element is active.
///
- bool IsActive { get; set; }
+ bool IsActive { get; }
///
/// Gets information whether the sub- are expanded.
///
- bool IsExpanded { get; }
+ bool IsExpanded { get; internal set; }
///
/// A unique tag used by the parent navigation system for the purpose of searching and navigating.
@@ -70,13 +70,20 @@ public interface INavigationViewItem
///
ControlTemplate? Template { get; set; }
+ ///
+ /// Gets parent if in collection
+ ///
+ INavigationViewItem? NavigationViewItemParent { get; internal set; }
+
///
/// Add / Remove ClickEvent handler.
///
[Category("Behavior")]
event RoutedEventHandler Click;
- internal bool WasInNavigationStack { get; set; }
internal bool IsMenuElement {get; set; }
+
+ void Activate(NavigationViewPaneDisplayMode paneDisplayMode);
+ void Deactivate(NavigationViewPaneDisplayMode paneDisplayMode);
}
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs b/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
index a41d131b4..2246a4ffd 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
@@ -118,10 +118,7 @@ public virtual bool GoBack()
if (Journal.Count <= 1)
return false;
- if (_currentIndexInJournal <= 1)
- return false;
-
- var itemId = Journal[_currentIndexInJournal - 2];
+ var itemId = Journal[Journal.Count - 2];
_isBackwardsNavigated = true;
return Navigate(itemId);
@@ -176,12 +173,6 @@ private bool NavigateInternal(INavigationViewItem viewItem, object? dataContext,
private void AddToJournal(INavigationViewItem viewItem)
{
-#if DEBUG
- Debug.WriteLine($"JOURNAL INDEX {_currentIndexInJournal}");
- if (Journal.Count > 0)
- Debug.WriteLine($"JOURNAL LAST ELEMENT {Journal[Journal.Count - 1]}");
-#endif
-
if (_isBackwardsNavigated)
{
_isBackwardsNavigated = false;
@@ -196,6 +187,12 @@ private void AddToJournal(INavigationViewItem viewItem)
_currentIndexInJournal++;
IsBackEnabled = CanGoBack;
+
+#if DEBUG
+ Debug.WriteLine($"JOURNAL INDEX {_currentIndexInJournal}");
+ if (Journal.Count > 0)
+ Debug.WriteLine($"JOURNAL LAST ELEMENT {Journal[Journal.Count - 1]}");
+#endif
}
private object? GetNavigationItemInstance(INavigationViewItem viewItem)
@@ -236,6 +233,8 @@ private void UpdateContent(object? content, object? dataContext = null)
NavigationViewContentPresenter.Navigate(content);
}
+ #region Navigation stack methods
+
private void AddToNavigationStack(INavigationViewItem viewItem, bool addToNavigationStack, bool isBackwardsNavigated)
{
if (isBackwardsNavigated)
@@ -243,7 +242,7 @@ private void AddToNavigationStack(INavigationViewItem viewItem, bool addToNaviga
if (addToNavigationStack && !NavigationStack.Contains(viewItem))
{
- ActivateMenuItem(viewItem);
+ viewItem.Activate(PaneDisplayMode);
NavigationStack.Add(viewItem);
}
@@ -266,14 +265,12 @@ private void UpdateCurrentNavigationStackItem(INavigationViewItem viewItem)
if (NavigationStack.Count == 0)
{
- ActivateMenuItem(viewItem);
+ viewItem.Activate(PaneDisplayMode);
NavigationStack.Add(viewItem);
}
else
{
- DeactivateMenuItem(NavigationStack[0]);
- NavigationStack[0] = viewItem;
- ActivateMenuItem(NavigationStack[0]);
+ ReplaceThirstElementInNavigationStack(viewItem);
}
ClearNavigationStack(1);
@@ -292,10 +289,7 @@ private void RecreateNavigationStackFromHistory(INavigationViewItem item)
if (latestHistory[0].IsMenuElement)
{
startIndex = 1;
-
- DeactivateMenuItem(NavigationStack[0]);
- NavigationStack[0] = latestHistory[0];
- ActivateMenuItem(NavigationStack[0]);
+ ReplaceThirstElementInNavigationStack(latestHistory[0]);
}
for (int i = startIndex; i < latestHistory.Length; i++)
@@ -384,19 +378,12 @@ private void ClearNavigationStack(INavigationViewItem item)
ClearNavigationStack(++index);
}
- private void ActivateMenuItem(INavigationViewItem viewItem)
+ private void ReplaceThirstElementInNavigationStack(INavigationViewItem newItem)
{
- viewItem.IsActive = true;
-
- if (viewItem.Icon is SymbolIcon symbolIcon && PaneDisplayMode == NavigationViewPaneDisplayMode.LeftFluent)
- symbolIcon.Filled = true;
+ NavigationStack[0].Deactivate(PaneDisplayMode);
+ NavigationStack[0] = newItem;
+ NavigationStack[0].Activate(PaneDisplayMode);
}
- private void DeactivateMenuItem(INavigationViewItem viewItem)
- {
- viewItem.IsActive = false;
-
- if (viewItem.Icon is SymbolIcon symbolIcon && PaneDisplayMode == NavigationViewPaneDisplayMode.LeftFluent)
- symbolIcon.Filled = false;
- }
+ #endregion
}
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationViewItem.cs b/src/Wpf.Ui/Controls/Navigation/NavigationViewItem.cs
index 7fdfaabf4..47de50774 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationViewItem.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationViewItem.cs
@@ -31,14 +31,14 @@ public class NavigationViewItem : System.Windows.Controls.Primitives.ButtonBase,
///
public static readonly DependencyProperty MenuItemsProperty = DependencyProperty.Register(nameof(MenuItems),
typeof(IList), typeof(NavigationViewItem),
- new PropertyMetadata(OnMenuItemsPropertyChanged));
+ new PropertyMetadata(new ObservableCollection(), OnMenuItemsPropertyChanged));
///
/// Property for .
///
public static readonly DependencyProperty MenuItemsSourceProperty = DependencyProperty.Register(nameof(MenuItemsSource),
typeof(object), typeof(NavigationViewItem),
- new PropertyMetadata(((object)null!), OnMenuItemsSourcePropertyChanged));
+ new PropertyMetadata(null, OnMenuItemsSourcePropertyChanged));
///
/// Property for .
@@ -63,24 +63,24 @@ public class NavigationViewItem : System.Windows.Controls.Primitives.ButtonBase,
///
public static readonly DependencyProperty IconProperty = DependencyProperty.Register(nameof(Icon),
typeof(object), typeof(NavigationViewItem),
- new PropertyMetadata((object)null!));
+ new PropertyMetadata(null));
///
/// Property for .
///
public static readonly DependencyProperty TargetPageTagProperty = DependencyProperty.Register(nameof(TargetPageTag),
- typeof(string), typeof(NavigationViewItem), new PropertyMetadata(String.Empty));
+ typeof(string), typeof(NavigationViewItem), new PropertyMetadata(string.Empty));
///
/// Property for .
///
public static readonly DependencyProperty TargetPageTypeProperty = DependencyProperty.Register(nameof(TargetPageType),
- typeof(Type), typeof(NavigationViewItem), new PropertyMetadata((Type)null!));
+ typeof(Type), typeof(NavigationViewItem), new PropertyMetadata(null));
///
- public IList? MenuItems
+ public IList MenuItems
{
- get => (IList?)GetValue(MenuItemsProperty);
+ get => (IList)GetValue(MenuItemsProperty);
set => SetValue(MenuItemsProperty, value);
}
@@ -121,7 +121,7 @@ public bool IsActive
public bool IsExpanded
{
get => (bool)GetValue(IsExpandedProperty);
- internal set => SetValue(IsExpandedProperty, value);
+ set => SetValue(IsExpandedProperty, value);
}
///
@@ -147,7 +147,7 @@ public Type? TargetPageType
}
///
- public bool WasInNavigationStack { get; set; }
+ public INavigationViewItem? NavigationViewItemParent { get; set; }
///
public bool IsMenuElement { get; set; }
@@ -164,7 +164,8 @@ public NavigationViewItem()
{
Id = Guid.NewGuid().ToString("n");
- SetValue(MenuItemsProperty, new ObservableCollection());
+ //Just in case
+ Unloaded += static (sender, _) => ((NavigationViewItem)sender).NavigationViewItemParent = null;
}
public NavigationViewItem(Type targetPageType) : this()
@@ -178,13 +179,33 @@ public NavigationViewItem(string name, SymbolRegular icon, Type targetPageType)
SetValue(IconProperty, new SymbolIcon { Symbol = icon });
}
+ ///
+ public void Activate(NavigationViewPaneDisplayMode paneDisplayMode)
+ {
+ IsActive = true;
+
+ if (Icon is SymbolIcon symbolIcon && paneDisplayMode == NavigationViewPaneDisplayMode.LeftFluent)
+ symbolIcon.Filled = true;
+
+ if (NavigationViewItemParent is not null)
+ NavigationViewItemParent.IsExpanded = true;
+ }
+
+ public void Deactivate(NavigationViewPaneDisplayMode paneDisplayMode)
+ {
+ IsActive = false;
+
+ if (Icon is SymbolIcon symbolIcon && paneDisplayMode == NavigationViewPaneDisplayMode.LeftFluent)
+ symbolIcon.Filled = false;
+ }
+
///
protected override void OnInitialized(EventArgs e)
{
base.OnInitialized(e);
if (string.IsNullOrWhiteSpace(TargetPageTag))
- TargetPageTag = Content?.ToString().ToLower().Trim() ?? string.Empty;
+ TargetPageTag = Content as string ?? Content.ToString()?.ToLower().Trim() ?? string.Empty;
}
///
@@ -246,7 +267,15 @@ private static void OnMenuItemsPropertyChanged(DependencyObject d, DependencyPro
if (d is not NavigationViewItem navigationViewItem)
return;
- navigationViewItem.HasMenuItems = navigationViewItem.MenuItems?.Count > 0;
+ navigationViewItem.HasMenuItems = navigationViewItem.MenuItems.Count > 0;
+
+ foreach (var menuItem in navigationViewItem.MenuItems)
+ {
+ if (menuItem is not INavigationViewItem item)
+ continue;
+
+ item.NavigationViewItemParent = navigationViewItem;
+ }
}
private static void OnMenuItemsSourcePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
@@ -256,7 +285,7 @@ private static void OnMenuItemsSourcePropertyChanged(DependencyObject d, Depende
navigationViewItem.MenuItems = enumerableNewValue;
- if (navigationViewItem.MenuItems?.Count > 0)
+ if (navigationViewItem.MenuItems.Count > 0)
navigationViewItem.HasMenuItems = true;
}
}
From 3ff75fd99a6627e2565466942bd6b95d034efecd Mon Sep 17 00:00:00 2001
From: Ivan Dmitriev <42055372+IvanDmitriev1@users.noreply.github.com>
Date: Thu, 26 Jan 2023 21:05:42 +0600
Subject: [PATCH 16/27] added default value for the MenuItems and
FooterMenuItems properties
---
.../Controls/Navigation/INavigationView.cs | 4 ++--
.../Navigation/INavigationViewItem.cs | 9 +++++++++
.../Navigation/NavigationView.Base.cs | 20 ++++---------------
.../Navigation/NavigationView.Navigation.cs | 5 +++--
.../Navigation/NavigationView.Properties.cs | 19 ++++++++++--------
.../Controls/Navigation/NavigationViewItem.cs | 5 ++++-
6 files changed, 33 insertions(+), 29 deletions(-)
diff --git a/src/Wpf.Ui/Controls/Navigation/INavigationView.cs b/src/Wpf.Ui/Controls/Navigation/INavigationView.cs
index 89b3c4029..e3c1777b0 100644
--- a/src/Wpf.Ui/Controls/Navigation/INavigationView.cs
+++ b/src/Wpf.Ui/Controls/Navigation/INavigationView.cs
@@ -38,7 +38,7 @@ public interface INavigationView
///
/// Gets the collection of menu items displayed in the NavigationView.
///
- IList? MenuItems { get; set; }
+ IList MenuItems { get; set; }
///
/// Gets or sets an object source used to generate the content of the NavigationView menu.
@@ -48,7 +48,7 @@ public interface INavigationView
///
/// Gets the list of objects to be used as navigation items in the footer menu.
///
- IList? FooterMenuItems { get; set; }
+ IList FooterMenuItems { get; set; }
///
/// Gets or sets the object that represents the navigation items to be used in the footer menu.
diff --git a/src/Wpf.Ui/Controls/Navigation/INavigationViewItem.cs b/src/Wpf.Ui/Controls/Navigation/INavigationViewItem.cs
index bdf266386..7b4d780ed 100644
--- a/src/Wpf.Ui/Controls/Navigation/INavigationViewItem.cs
+++ b/src/Wpf.Ui/Controls/Navigation/INavigationViewItem.cs
@@ -83,7 +83,16 @@ public interface INavigationViewItem
internal bool IsMenuElement {get; set; }
+ ///
+ /// Correctly activates
+ ///
+ ///
void Activate(NavigationViewPaneDisplayMode paneDisplayMode);
+
+ ///
+ /// Correctly deactivates
+ ///
+ ///
void Deactivate(NavigationViewPaneDisplayMode paneDisplayMode);
}
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs b/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs
index 8fc90f4eb..69f52408b 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs
@@ -204,11 +204,8 @@ private void AutoSuggestBoxOnSuggestionChosen(object sender, RoutedEventArgs e)
NavigateToMenuItemFromAutoSuggestBox(FooterMenuItems, selectedSuggestBoxItem);
}
- protected virtual void AddItemsToDictionaries(IList? list)
+ protected virtual void AddItemsToDictionaries(IList list)
{
- if (list is null)
- return;
-
foreach (var singleMenuItem in list)
{
if (singleMenuItem is not INavigationViewItem singleNavigationViewItem)
@@ -238,11 +235,8 @@ protected virtual void AddItemsToDictionaries()
AddItemsToDictionaries(FooterMenuItems);
}
- protected virtual void AddItemsToAutoSuggestBoxItems(IList? list)
+ protected virtual void AddItemsToAutoSuggestBoxItems(IList list)
{
- if (list is null)
- return;
-
foreach (var singleMenuItem in list)
{
if (singleMenuItem is not NavigationViewItem singleNavigationViewItem)
@@ -264,11 +258,8 @@ protected virtual void AddItemsToAutoSuggestBoxItems()
AddItemsToAutoSuggestBoxItems(FooterMenuItems);
}
- protected virtual bool NavigateToMenuItemFromAutoSuggestBox(IList? list, string selectedSuggestBoxItem)
+ protected virtual bool NavigateToMenuItemFromAutoSuggestBox(IList list, string selectedSuggestBoxItem)
{
- if (list is null)
- return false;
-
foreach (var singleMenuItem in list)
{
if (singleMenuItem is not NavigationViewItem singleNavigationViewItem)
@@ -292,11 +283,8 @@ protected virtual bool NavigateToMenuItemFromAutoSuggestBox(IList? list, string
return false;
}
- protected virtual void UpdateMenuItemsTemplate(IList? list)
+ protected virtual void UpdateMenuItemsTemplate(IList list)
{
- if (list is null)
- return;
-
foreach (var singleMenuItem in list)
{
if (singleMenuItem is not NavigationViewItem singleNavigationViewItem)
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs b/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
index 2246a4ffd..5b760d987 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
@@ -18,7 +18,7 @@ namespace Wpf.Ui.Controls.Navigation;
public partial class NavigationView
{
- protected readonly List Journal = new(200);
+ protected readonly List Journal = new(50);
protected readonly ObservableCollection NavigationStack = new();
private readonly Dictionary> _complexNavigationStackHistory = new();
@@ -127,10 +127,11 @@ public virtual bool GoBack()
///
public virtual void ClearJournal()
{
+ _currentIndexInJournal = 0;
+
Journal.Clear();
NavigationStack.Clear();
_complexNavigationStackHistory.Clear();
- _currentIndexInJournal = 0;
}
private bool TryToNavigateWithoutINavigationViewItem(Type pageType, bool addToNavigationStack, object? dataContext = null)
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationView.Properties.cs b/src/Wpf.Ui/Controls/Navigation/NavigationView.Properties.cs
index 6d6007cfd..56804c876 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationView.Properties.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationView.Properties.cs
@@ -6,6 +6,7 @@
// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
// All Rights Reserved.
+using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
@@ -42,20 +43,22 @@ public partial class NavigationView
/// Property for .
///
public static readonly DependencyProperty MenuItemsProperty = DependencyProperty.Register(nameof(MenuItems),
- typeof(IList), typeof(NavigationView));
+ typeof(IList), typeof(NavigationView), new FrameworkPropertyMetadata(Array.Empty()));
///
/// Property for .
///
- public static readonly DependencyProperty MenuItemsSourceProperty = DependencyProperty.Register(nameof(MenuItemsSource),
+ public static readonly DependencyProperty MenuItemsSourceProperty = DependencyProperty.Register(
+ nameof(MenuItemsSource),
typeof(object), typeof(NavigationView),
new FrameworkPropertyMetadata(null, OnMenuItemsSourcePropertyChanged));
///
/// Property for .
///
- public static readonly DependencyProperty FooterMenuItemsProperty = DependencyProperty.Register(nameof(FooterMenuItemsProperty),
- typeof(IList), typeof(NavigationView));
+ public static readonly DependencyProperty FooterMenuItemsProperty = DependencyProperty.Register(
+ nameof(FooterMenuItemsProperty),
+ typeof(IList), typeof(NavigationView), new FrameworkPropertyMetadata(Array.Empty()));
///
/// Property for .
@@ -194,9 +197,9 @@ public bool AlwaysShowHeader
}
///
- public IList? MenuItems
+ public IList MenuItems
{
- get => (IList?)GetValue(MenuItemsProperty);
+ get => (IList)GetValue(MenuItemsProperty);
set => SetValue(MenuItemsProperty, value);
}
@@ -215,9 +218,9 @@ public object? MenuItemsSource
}
///
- public IList? FooterMenuItems
+ public IList FooterMenuItems
{
- get => (IList?)GetValue(FooterMenuItemsProperty);
+ get => (IList)GetValue(FooterMenuItemsProperty);
set => SetValue(FooterMenuItemsProperty, value);
}
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationViewItem.cs b/src/Wpf.Ui/Controls/Navigation/NavigationViewItem.cs
index 47de50774..ab051cf92 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationViewItem.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationViewItem.cs
@@ -191,6 +191,7 @@ public void Activate(NavigationViewPaneDisplayMode paneDisplayMode)
NavigationViewItemParent.IsExpanded = true;
}
+ ///
public void Deactivate(NavigationViewPaneDisplayMode paneDisplayMode)
{
IsActive = false;
@@ -204,8 +205,10 @@ protected override void OnInitialized(EventArgs e)
{
base.OnInitialized(e);
- if (string.IsNullOrWhiteSpace(TargetPageTag))
+ if (string.IsNullOrWhiteSpace(TargetPageTag) && Content is not null)
+ {
TargetPageTag = Content as string ?? Content.ToString()?.ToLower().Trim() ?? string.Empty;
+ }
}
///
From 994740d0549e04447667406a1f10d3fc5329703c Mon Sep 17 00:00:00 2001
From: Ivan Dmitriev <42055372+IvanDmitriev1@users.noreply.github.com>
Date: Thu, 26 Jan 2023 21:27:46 +0600
Subject: [PATCH 17/27] optimized ClearNavigationStack method
---
.../Navigation/NavigationView.Navigation.cs | 26 +++----------------
1 file changed, 3 insertions(+), 23 deletions(-)
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs b/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
index 5b760d987..c4170e4d7 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
@@ -319,6 +319,7 @@ private void AddToNavigationStackHistory(INavigationViewItem viewItem)
_complexNavigationStackHistory.Add(lastItem, historyList);
}
+ //Initializing an array every time well... not an ideal
historyList.Add(new INavigationViewItem[NavigationStack.Count - 1 - startIndex]);
var latestHistory = historyList[historyList.Count - 1];
@@ -338,31 +339,10 @@ private void ClearNavigationStack(int navigationStackItemIndex)
if (length == 0)
return;
- INavigationViewItem[] buffer;
-
-#if NET6_0_OR_GREATER
-
- buffer = System.Buffers.ArrayPool.Shared.Rent(length);
-#else
- buffer = new INavigationViewItem[length];
-#endif
-
- int i = 0;
- for (int j = navigationStackItemIndex; j <= navigationStackCount - 1; j++)
+ for (int j = navigationStackCount - 1; j >= navigationStackCount - length; j--)
{
- buffer[i] = NavigationStack[j];
- i++;
+ NavigationStack.Remove(NavigationStack[j]);
}
-
- for (var index = 0; index < length; index++)
- {
- var item = buffer[index];
- NavigationStack.Remove(item);
- }
-
-#if NET6_0_OR_GREATER
- System.Buffers.ArrayPool.Shared.Return(buffer, true);
-#endif
}
private void ClearNavigationStack(INavigationViewItem item)
From c3438f2b0795d7d8a0ee2a15512c70137f097f0a Mon Sep 17 00:00:00 2001
From: Ivan Dmitriev <42055372+IvanDmitriev1@users.noreply.github.com>
Date: Thu, 26 Jan 2023 21:57:40 +0600
Subject: [PATCH 18/27] improved multilevel navigation demo
---
src/Wpf.Ui.Gallery/App.xaml.cs | 2 +
.../Navigation/MultilevelNavigationSample.cs | 23 +++++++++++
.../Navigation/MultilevelNavigationPage.xaml | 12 +++++-
.../MultilevelNavigationPage.xaml.cs | 20 ++++-----
.../MultilevelNavigationSamplePage1.xaml | 22 ++++++++--
.../MultilevelNavigationSamplePage1.xaml.cs | 19 ++++-----
.../MultilevelNavigationSamplePage2.xaml | 20 ++++++++-
.../MultilevelNavigationSamplePage2.xaml.cs | 19 ++++-----
.../MultilevelNavigationSamplePage3.xaml | 22 ++++++++--
.../MultilevelNavigationSamplePage3.xaml.cs | 19 ++++-----
src/Wpf.Ui/Contracts/INavigationService.cs | 6 +++
.../Navigation/NavigationView.Base.cs | 1 -
src/Wpf.Ui/Services/NavigationService.cs | 41 ++++++++++++++-----
13 files changed, 160 insertions(+), 66 deletions(-)
create mode 100644 src/Wpf.Ui.Gallery/ViewModels/Pages/Navigation/MultilevelNavigationSample.cs
diff --git a/src/Wpf.Ui.Gallery/App.xaml.cs b/src/Wpf.Ui.Gallery/App.xaml.cs
index 79014b74e..e54ac024a 100644
--- a/src/Wpf.Ui.Gallery/App.xaml.cs
+++ b/src/Wpf.Ui.Gallery/App.xaml.cs
@@ -17,6 +17,7 @@
using Wpf.Ui.Gallery.ViewModels.Pages.Icons;
using Wpf.Ui.Gallery.ViewModels.Pages.Media;
using Wpf.Ui.Gallery.ViewModels.Pages.Navigation;
+using Wpf.Ui.Gallery.ViewModels.Pages.Samples;
using Wpf.Ui.Gallery.ViewModels.Pages.StatusAndInfo;
using Wpf.Ui.Gallery.ViewModels.Pages.Text;
using Wpf.Ui.Gallery.ViewModels.Pages.Windows;
@@ -156,6 +157,7 @@ public partial class App : Application
services.AddTransient();
// Multilevel navigation sample Pages
+ services.AddTransient();
services.AddTransient();
services.AddTransient();
services.AddTransient();
diff --git a/src/Wpf.Ui.Gallery/ViewModels/Pages/Navigation/MultilevelNavigationSample.cs b/src/Wpf.Ui.Gallery/ViewModels/Pages/Navigation/MultilevelNavigationSample.cs
new file mode 100644
index 000000000..e60d89199
--- /dev/null
+++ b/src/Wpf.Ui.Gallery/ViewModels/Pages/Navigation/MultilevelNavigationSample.cs
@@ -0,0 +1,23 @@
+namespace Wpf.Ui.Gallery.ViewModels.Pages.Samples;
+
+public partial class MultilevelNavigationSample
+{
+ public MultilevelNavigationSample(INavigationService navigationService)
+ {
+ _navigationService = navigationService;
+ }
+
+ private readonly INavigationService _navigationService;
+
+ [RelayCommand]
+ private void NavigateForward(Type type)
+ {
+ _navigationService.NavigateWithHierarchy(type);
+ }
+
+ [RelayCommand]
+ private void NavigateBack()
+ {
+ _navigationService.GoBack();
+ }
+}
diff --git a/src/Wpf.Ui.Gallery/Views/Pages/Navigation/MultilevelNavigationPage.xaml b/src/Wpf.Ui.Gallery/Views/Pages/Navigation/MultilevelNavigationPage.xaml
index 40bdaeaef..e9e003476 100644
--- a/src/Wpf.Ui.Gallery/Views/Pages/Navigation/MultilevelNavigationPage.xaml
+++ b/src/Wpf.Ui.Gallery/Views/Pages/Navigation/MultilevelNavigationPage.xaml
@@ -5,8 +5,12 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Wpf.Ui.Gallery.Views.Pages.Navigation"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:samples="clr-namespace:Wpf.Ui.Gallery.ViewModels.Pages.Samples"
+ xmlns:samples1="clr-namespace:Wpf.Ui.Gallery.Views.Pages.Samples"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
Title="MultilevelNavigationPage"
+ d:DataContext="{d:DesignInstance samples:MultilevelNavigationSample,
+ IsDesignTimeCreatable=False}"
d:DesignHeight="450"
d:DesignWidth="800"
ui:Design.Background="{DynamicResource ApplicationBackgroundBrush}"
@@ -15,6 +19,12 @@
mc:Ignorable="d">
-
+
diff --git a/src/Wpf.Ui.Gallery/Views/Pages/Navigation/MultilevelNavigationPage.xaml.cs b/src/Wpf.Ui.Gallery/Views/Pages/Navigation/MultilevelNavigationPage.xaml.cs
index 102cb9b82..3f27027e1 100644
--- a/src/Wpf.Ui.Gallery/Views/Pages/Navigation/MultilevelNavigationPage.xaml.cs
+++ b/src/Wpf.Ui.Gallery/Views/Pages/Navigation/MultilevelNavigationPage.xaml.cs
@@ -1,21 +1,17 @@
-using System.Windows;
-using System.Windows.Controls;
-using Wpf.Ui.Gallery.Views.Pages.Samples;
+using Wpf.Ui.Controls.Navigation;
+using Wpf.Ui.Gallery.ViewModels.Pages.Samples;
namespace Wpf.Ui.Gallery.Views.Pages.Navigation;
-public partial class MultilevelNavigationPage : Page
+public partial class MultilevelNavigationPage : INavigableView
{
- public MultilevelNavigationPage(INavigationService navigationService)
+ public MultilevelNavigationPage(MultilevelNavigationSample viewModel)
{
- _navigationService = navigationService;
+ ViewModel = viewModel;
+ DataContext = viewModel;
+
InitializeComponent();
}
- private readonly INavigationService _navigationService;
-
- private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
- {
- _navigationService.NavigateWithHierarchy(typeof(MultilevelNavigationSamplePage1));
- }
+ public MultilevelNavigationSample ViewModel { get; }
}
diff --git a/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage1.xaml b/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage1.xaml
index d54794494..a760fee21 100644
--- a/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage1.xaml
+++ b/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage1.xaml
@@ -3,20 +3,36 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:local="clr-namespace:Wpf.Ui.Gallery.Views.Pages.Samples"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:samples="clr-namespace:Wpf.Ui.Gallery.ViewModels.Pages.Samples"
+ xmlns:samples1="clr-namespace:Wpf.Ui.Gallery.Views.Pages.Samples"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
Title="MultilevelNavigationSamplePage"
+ d:DataContext="{d:DesignInstance samples:MultilevelNavigationSample,
+ IsDesignTimeCreatable=False}"
d:DesignHeight="450"
d:DesignWidth="800"
ui:NavigationView.HeaderContent="Page 1"
mc:Ignorable="d">
+
+
+
+
+
+
+
diff --git a/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage1.xaml.cs b/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage1.xaml.cs
index 0bc09c9db..d6d8ff659 100644
--- a/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage1.xaml.cs
+++ b/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage1.xaml.cs
@@ -1,20 +1,17 @@
-using System.Windows;
-using System.Windows.Controls;
+using Wpf.Ui.Controls.Navigation;
+using Wpf.Ui.Gallery.ViewModels.Pages.Samples;
namespace Wpf.Ui.Gallery.Views.Pages.Samples;
-public partial class MultilevelNavigationSamplePage1 : Page
+public partial class MultilevelNavigationSamplePage1 : INavigableView
{
- public MultilevelNavigationSamplePage1(INavigationService navigationService)
+ public MultilevelNavigationSamplePage1(MultilevelNavigationSample viewModel)
{
- _navigationService = navigationService;
+ ViewModel = viewModel;
+ DataContext = viewModel;
+
InitializeComponent();
}
- private readonly INavigationService _navigationService;
-
- private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
- {
- _navigationService.NavigateWithHierarchy(typeof(MultilevelNavigationSamplePage2));
- }
+ public MultilevelNavigationSample ViewModel { get; }
}
diff --git a/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage2.xaml b/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage2.xaml
index 1894e2c32..e417a1ca8 100644
--- a/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage2.xaml
+++ b/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage2.xaml
@@ -5,18 +5,34 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Wpf.Ui.Gallery.Views.Pages.Samples"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:samples="clr-namespace:Wpf.Ui.Gallery.ViewModels.Pages.Samples"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
Title="MultilevelNavigationSamplePage2"
+ d:DataContext="{d:DesignInstance samples:MultilevelNavigationSample,
+ IsDesignTimeCreatable=False}"
d:DesignHeight="450"
d:DesignWidth="800"
ui:NavigationView.HeaderContent="Page 2"
mc:Ignorable="d">
+
+
+
+
+
+
+
diff --git a/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage2.xaml.cs b/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage2.xaml.cs
index 1f240111f..348f45c0a 100644
--- a/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage2.xaml.cs
+++ b/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage2.xaml.cs
@@ -1,20 +1,17 @@
-using System.Windows;
-using System.Windows.Controls;
+using Wpf.Ui.Controls.Navigation;
+using Wpf.Ui.Gallery.ViewModels.Pages.Samples;
namespace Wpf.Ui.Gallery.Views.Pages.Samples;
-public partial class MultilevelNavigationSamplePage2 : Page
+public partial class MultilevelNavigationSamplePage2 : INavigableView
{
- private readonly INavigationService _navigationService;
-
- public MultilevelNavigationSamplePage2(INavigationService navigationService)
+ public MultilevelNavigationSamplePage2(MultilevelNavigationSample viewModel)
{
- _navigationService = navigationService;
+ ViewModel = viewModel;
+ DataContext = viewModel;
+
InitializeComponent();
}
- private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
- {
- _navigationService.NavigateWithHierarchy(typeof(MultilevelNavigationSamplePage3));
- }
+ public MultilevelNavigationSample ViewModel { get; }
}
diff --git a/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage3.xaml b/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage3.xaml
index d1aafe17f..52169358a 100644
--- a/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage3.xaml
+++ b/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage3.xaml
@@ -5,19 +5,35 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Wpf.Ui.Gallery.Views.Pages.Samples"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:samples="clr-namespace:Wpf.Ui.Gallery.ViewModels.Pages.Samples"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
Title="MultilevelNavigationSamplePage3"
+ d:DataContext="{d:DesignInstance samples:MultilevelNavigationSample,
+ IsDesignTimeCreatable=False}"
d:DesignHeight="450"
d:DesignWidth="800"
ui:NavigationView.HeaderContent="Page 3"
mc:Ignorable="d">
+
+
+
+
+
+
+
diff --git a/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage3.xaml.cs b/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage3.xaml.cs
index 7ca3e8a0f..1db06245c 100644
--- a/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage3.xaml.cs
+++ b/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage3.xaml.cs
@@ -1,20 +1,17 @@
-using System.Windows;
-using System.Windows.Controls;
+using Wpf.Ui.Controls.Navigation;
+using Wpf.Ui.Gallery.ViewModels.Pages.Samples;
namespace Wpf.Ui.Gallery.Views.Pages.Samples;
-public partial class MultilevelNavigationSamplePage3 : Page
+public partial class MultilevelNavigationSamplePage3 : INavigableView
{
- private readonly INavigationService _navigationService;
-
- public MultilevelNavigationSamplePage3(INavigationService navigationService)
+ public MultilevelNavigationSamplePage3(MultilevelNavigationSample viewModel)
{
- _navigationService = navigationService;
+ ViewModel = viewModel;
+ DataContext = viewModel;
+
InitializeComponent();
}
- private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
- {
- _navigationService.NavigateWithHierarchy(typeof(MultilevelNavigationSamplePage1));
- }
+ public MultilevelNavigationSample ViewModel { get; }
}
diff --git a/src/Wpf.Ui/Contracts/INavigationService.cs b/src/Wpf.Ui/Contracts/INavigationService.cs
index 1b682e730..737a19515 100644
--- a/src/Wpf.Ui/Contracts/INavigationService.cs
+++ b/src/Wpf.Ui/Contracts/INavigationService.cs
@@ -44,6 +44,12 @@ public interface INavigationService
/// Id or tag of the page.
bool Navigate(string pageIdOrTargetTag);
+ ///
+ /// Navigates the NavigationView to the previous journal entry.
+ ///
+ ///
+ bool GoBack();
+
///
/// In work
///
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs b/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs
index 69f52408b..6d9f236dd 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs
@@ -79,7 +79,6 @@ protected override void OnInitialized(EventArgs e)
UpdateLayout();
UpdateAutoSuggestBoxSuggestions();
- //UpdateSelectionForMenuItems();
AddItemsToDictionaries();
}
diff --git a/src/Wpf.Ui/Services/NavigationService.cs b/src/Wpf.Ui/Services/NavigationService.cs
index b87a9c274..9aac962bf 100644
--- a/src/Wpf.Ui/Services/NavigationService.cs
+++ b/src/Wpf.Ui/Services/NavigationService.cs
@@ -4,6 +4,7 @@
// All Rights Reserved.
using System;
+using System.Diagnostics.CodeAnalysis;
using Wpf.Ui.Contracts;
using Wpf.Ui.Controls.Navigation;
@@ -61,37 +62,55 @@ public void SetPageService(IPageService pageService)
if (NavigationControl == null)
{
_pageService = pageService;
-
return;
}
- NavigationControl.SetPageService(_pageService);
+ ThrowIfPageServiceIsNull();
+
+ NavigationControl.SetPageService(_pageService!);
}
///
public bool Navigate(Type pageType)
{
- if (NavigationControl == null)
- return false;
+ ThrowIfNavigationControlIsNull();
- return NavigationControl.Navigate(pageType);
+ return NavigationControl!.Navigate(pageType);
}
///
public bool Navigate(string pageTag)
{
- if (NavigationControl == null)
- return false;
+ ThrowIfNavigationControlIsNull();
+
+ return NavigationControl!.Navigate(pageTag);
+ }
+
+ ///
+ public bool GoBack()
+ {
+ ThrowIfNavigationControlIsNull();
- return NavigationControl.Navigate(pageTag);
+ return NavigationControl!.GoBack();
}
///
public bool NavigateWithHierarchy(Type pageType)
{
- if (NavigationControl == null)
- return false;
+ ThrowIfNavigationControlIsNull();
+
+ return NavigationControl!.NavigateWithHierarchy(pageType);
+ }
- return NavigationControl.NavigateWithHierarchy(pageType);
+ private void ThrowIfNavigationControlIsNull()
+ {
+ if (NavigationControl is null)
+ throw new ArgumentNullException(nameof(NavigationControl));
+ }
+
+ private void ThrowIfPageServiceIsNull()
+ {
+ if (_pageService is null)
+ throw new ArgumentNullException(nameof(_pageService));
}
}
From 56dad5e3b16773b1c64b7d492561161a0a6063d3 Mon Sep 17 00:00:00 2001
From: Ivan Dmitriev <42055372+IvanDmitriev1@users.noreply.github.com>
Date: Thu, 26 Jan 2023 22:45:42 +0600
Subject: [PATCH 19/27] added Navigating event
---
src/Wpf.Ui/Common/TypedEventHandler.cs | 22 ++++++++
.../Controls/Navigation/INavigationView.cs | 16 ++++--
.../Navigation/NavigationView.Events.cs | 56 ++++++++++++++-----
.../Navigation/NavigationView.Navigation.cs | 27 +++++----
...iewEvent.cs => NavigationViewEventArgs.cs} | 20 +++----
5 files changed, 102 insertions(+), 39 deletions(-)
create mode 100644 src/Wpf.Ui/Common/TypedEventHandler.cs
rename src/Wpf.Ui/Controls/Navigation/{NavigationViewEvent.cs => NavigationViewEventArgs.cs} (54%)
diff --git a/src/Wpf.Ui/Common/TypedEventHandler.cs b/src/Wpf.Ui/Common/TypedEventHandler.cs
new file mode 100644
index 000000000..b08cc263d
--- /dev/null
+++ b/src/Wpf.Ui/Common/TypedEventHandler.cs
@@ -0,0 +1,22 @@
+// Based on Windows UI Library
+// Copyright(c) Microsoft Corporation.All rights reserved.
+
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT.
+// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
+// All Rights Reserved.
+
+using System.Windows;
+
+namespace Wpf.Ui.Common;
+
+///
+/// Represents a method that handles general events.
+///
+///
+///
+///
+///
+public delegate void TypedEventHandler(TSender sender, TArgs args)
+ where TSender : DependencyObject
+ where TArgs : RoutedEventArgs;
diff --git a/src/Wpf.Ui/Controls/Navigation/INavigationView.cs b/src/Wpf.Ui/Controls/Navigation/INavigationView.cs
index e3c1777b0..f3374f79d 100644
--- a/src/Wpf.Ui/Controls/Navigation/INavigationView.cs
+++ b/src/Wpf.Ui/Controls/Navigation/INavigationView.cs
@@ -11,6 +11,7 @@
using System.Windows;
using System.Windows.Controls;
using Wpf.Ui.Animations;
+using Wpf.Ui.Common;
using Wpf.Ui.Contracts;
namespace Wpf.Ui.Controls.Navigation;
@@ -140,27 +141,32 @@ public interface INavigationView
///
/// Occurs when the NavigationView pane is opened.
///
- event NavigationViewEvent PaneOpened;
+ event TypedEventHandler PaneOpened;
///
/// Occurs when the NavigationView pane is closed.
///
- event NavigationViewEvent PaneClosed;
+ event TypedEventHandler PaneClosed;
///
/// Occurs when the currently selected item changes.
///
- event NavigationViewEvent SelectionChanged;
+ event TypedEventHandler SelectionChanged;
///
/// Occurs when an item in the menu receives an interaction such as a click or tap.
///
- event NavigationViewEvent ItemInvoked;
+ event TypedEventHandler ItemInvoked;
///
/// Occurs when the back button receives an interaction such as a click or tap.
///
- event NavigationViewEvent BackRequested;
+ event TypedEventHandler BackRequested;
+
+ ///
+ /// Occurs when a new navigation is requested
+ ///
+ event TypedEventHandler Navigating;
///
/// Gets a value that indicates whether there is at least one entry in back navigation history.
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationView.Events.cs b/src/Wpf.Ui/Controls/Navigation/NavigationView.Events.cs
index bfc4253ea..c5111849a 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationView.Events.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationView.Events.cs
@@ -8,6 +8,7 @@
using System.Diagnostics;
using System.Windows;
+using Wpf.Ui.Common;
namespace Wpf.Ui.Controls.Navigation;
@@ -17,74 +18,86 @@ public partial class NavigationView
/// Property for .
///
public static readonly RoutedEvent PaneOpenedEvent = EventManager.RegisterRoutedEvent(nameof(PaneOpened),
- RoutingStrategy.Bubble, typeof(NavigationViewEvent), typeof(NavigationView));
+ RoutingStrategy.Bubble, typeof(TypedEventHandler), typeof(NavigationView));
///
/// Property for .
///
public static readonly RoutedEvent PaneClosedEvent = EventManager.RegisterRoutedEvent(nameof(PaneClosed),
- RoutingStrategy.Bubble, typeof(NavigationViewEvent), typeof(NavigationView));
+ RoutingStrategy.Bubble, typeof(TypedEventHandler), typeof(NavigationView));
///
/// Property for .
///
public static readonly RoutedEvent SelectionChangedEvent = EventManager.RegisterRoutedEvent(nameof(SelectionChanged),
- RoutingStrategy.Bubble, typeof(NavigationViewEvent), typeof(NavigationView));
+ RoutingStrategy.Bubble, typeof(TypedEventHandler), typeof(NavigationView));
///
/// Property for .
///
public static readonly RoutedEvent ItemInvokedEvent = EventManager.RegisterRoutedEvent(nameof(ItemInvoked),
- RoutingStrategy.Bubble, typeof(NavigationViewEvent), typeof(NavigationView));
+ RoutingStrategy.Bubble, typeof(TypedEventHandler), typeof(NavigationView));
///
/// Property for .
///
public static readonly RoutedEvent BackRequestedEvent = EventManager.RegisterRoutedEvent(nameof(BackRequested),
- RoutingStrategy.Bubble, typeof(NavigationViewEvent), typeof(NavigationView));
+ RoutingStrategy.Bubble, typeof(TypedEventHandler), typeof(NavigationView));
+ ///
+ /// Property for .
+ ///
+ public static readonly RoutedEvent NavigatingEvent = EventManager.RegisterRoutedEvent(nameof(Navigating),
+ RoutingStrategy.Bubble, typeof(TypedEventHandler), typeof(NavigationView));
///
- public event NavigationViewEvent PaneOpened
+ public event TypedEventHandler PaneOpened
{
add => AddHandler(PaneOpenedEvent, value);
remove => RemoveHandler(PaneOpenedEvent, value);
}
///
- public event NavigationViewEvent PaneClosed
+ public event TypedEventHandler PaneClosed
{
add => AddHandler(PaneClosedEvent, value);
remove => RemoveHandler(PaneClosedEvent, value);
}
///
- public event NavigationViewEvent SelectionChanged
+ public event TypedEventHandler SelectionChanged
{
add => AddHandler(SelectionChangedEvent, value);
remove => RemoveHandler(SelectionChangedEvent, value);
}
///
- public event NavigationViewEvent ItemInvoked
+ public event TypedEventHandler ItemInvoked
{
add => AddHandler(ItemInvokedEvent, value);
remove => RemoveHandler(ItemInvokedEvent, value);
}
///
- public event NavigationViewEvent BackRequested
+ public event TypedEventHandler BackRequested
{
add => AddHandler(BackRequestedEvent, value);
remove => RemoveHandler(BackRequestedEvent, value);
}
+ ///
+ public event TypedEventHandler Navigating
+ {
+ add => AddHandler(NavigatingEvent, value);
+ remove => RemoveHandler(NavigatingEvent, value);
+ }
+
///
/// Raises the pane opened event.
///
[DebuggerStepThrough]
protected virtual void OnPaneOpened()
{
- RaiseEvent(new RoutedEventArgs(PaneOpenedEvent));
+ RaiseEvent(new RoutedEventArgs(PaneOpenedEvent, this));
}
///
@@ -93,7 +106,7 @@ protected virtual void OnPaneOpened()
[DebuggerStepThrough]
protected virtual void OnPaneClosed()
{
- RaiseEvent(new RoutedEventArgs(PaneClosedEvent));
+ RaiseEvent(new RoutedEventArgs(PaneClosedEvent, this));
}
///
@@ -102,7 +115,7 @@ protected virtual void OnPaneClosed()
[DebuggerStepThrough]
protected virtual void OnSelectionChanged()
{
- RaiseEvent(new RoutedEventArgs(SelectionChangedEvent));
+ RaiseEvent(new RoutedEventArgs(SelectionChangedEvent, this));
}
///
@@ -111,7 +124,7 @@ protected virtual void OnSelectionChanged()
[DebuggerStepThrough]
protected virtual void OnItemInvoked()
{
- RaiseEvent(new RoutedEventArgs(ItemInvokedEvent));
+ RaiseEvent(new RoutedEventArgs(ItemInvokedEvent, this));
}
///
@@ -122,4 +135,19 @@ protected virtual void OnBackRequested()
{
RaiseEvent(new RoutedEventArgs(BackRequestedEvent));
}
+
+ ///
+ /// Raises the navigating requested event.
+ ///
+ ///
+ ///
+ [DebuggerStepThrough]
+ protected virtual bool OnNavigating(object sourcePageType)
+ {
+ var eventArgs = new NavigatingCancelEventArgs(NavigatingEvent, this, sourcePageType);
+
+ RaiseEvent(eventArgs);
+
+ return eventArgs.Cancel;
+ }
}
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs b/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
index c4170e4d7..047f9a600 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
@@ -10,7 +10,6 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
-using System.Reflection;
using System.Windows;
using Wpf.Ui.Contracts;
@@ -154,7 +153,8 @@ private bool NavigateInternal(INavigationViewItem viewItem, object? dataContext,
Debug.WriteLine($"DEBUG | {viewItem.Id} - {viewItem.TargetPageTag ?? "NO_TAG"} | NAVIGATED");
- RenderSelectedItemContent(viewItem, dataContext);
+ if (!RenderSelectedItemContent(viewItem, dataContext))
+ return false;
if (!notifyAboutUpdate)
return true;
@@ -196,34 +196,41 @@ private void AddToJournal(INavigationViewItem viewItem)
#endif
}
- private object? GetNavigationItemInstance(INavigationViewItem viewItem)
+ private object GetNavigationItemInstance(INavigationViewItem viewItem)
{
if (viewItem.TargetPageType is null)
- return null;
+ throw new ArgumentNullException(nameof(viewItem.TargetPageType));
if (_serviceProvider is not null)
{
- return _serviceProvider.GetService(viewItem.TargetPageType);
+ return _serviceProvider.GetService(viewItem.TargetPageType) ??
+ new ArgumentNullException($"{nameof(_serviceProvider.GetService)} returned null");
}
if (_pageService is not null)
{
- return _pageService.GetPage(viewItem.TargetPageType);
+ return _pageService.GetPage(viewItem.TargetPageType) ??
+ throw new ArgumentNullException($"{nameof(_pageService.GetPage)} returned null");
}
- return NavigationViewActivator.CreateInstance(viewItem.TargetPageType);
+ return NavigationViewActivator.CreateInstance(viewItem.TargetPageType) ??
+ throw new ArgumentException("Failed to create instance of the page");
}
- private void RenderSelectedItemContent(INavigationViewItem viewItem, object? dataContext)
+ private bool RenderSelectedItemContent(INavigationViewItem viewItem, object? dataContext)
{
var pageInstance = GetNavigationItemInstance(viewItem);
+ if (OnNavigating(pageInstance))
+ {
+ Debug.WriteLine("Navigation canceled");
+ return false;
+ }
if (pageInstance is FrameworkElement frameworkElement && GetHeaderContent(frameworkElement) is {} headerContent)
- {
viewItem.Content = headerContent;
- }
UpdateContent(pageInstance, dataContext);
+ return true;
}
private void UpdateContent(object? content, object? dataContext = null)
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationViewEvent.cs b/src/Wpf.Ui/Controls/Navigation/NavigationViewEventArgs.cs
similarity index 54%
rename from src/Wpf.Ui/Controls/Navigation/NavigationViewEvent.cs
rename to src/Wpf.Ui/Controls/Navigation/NavigationViewEventArgs.cs
index eacce83bf..4c9b544bf 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationViewEvent.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationViewEventArgs.cs
@@ -6,17 +6,17 @@
// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
// All Rights Reserved.
-using System.Diagnostics.CodeAnalysis;
using System.Windows;
namespace Wpf.Ui.Controls.Navigation;
-///
-/// Event triggered by NavigationView.
-///
-/// Current navigation instance.
-#if NET5_0_OR_GREATER
-public delegate void NavigationViewEvent([NotNull] object sender, RoutedEventArgs e);
-#else
-public delegate void NavigationViewEvent(object sender, RoutedEventArgs e);
-#endif
+public class NavigatingCancelEventArgs : RoutedEventArgs
+{
+ public NavigatingCancelEventArgs(RoutedEvent routedEvent, object source, object sourcePageType) : base(routedEvent, source)
+ {
+ SourcePageType = sourcePageType;
+ }
+
+ public bool Cancel { get; set; }
+ public object SourcePageType { get; }
+}
From dba5cef370c463820fe0af5411859ae6ecf33f68 Mon Sep 17 00:00:00 2001
From: Ivan Dmitriev <42055372+IvanDmitriev1@users.noreply.github.com>
Date: Fri, 27 Jan 2023 09:49:45 +0600
Subject: [PATCH 20/27] added license
---
src/Wpf.Ui.Gallery/App.xaml.cs | 1 -
.../Navigation/MultilevelNavigationSample.cs | 7 ++++-
.../Navigation/MultilevelNavigationPage.xaml | 4 +--
.../MultilevelNavigationPage.xaml.cs | 9 ++++--
.../MultilevelNavigationSamplePage1.xaml | 4 +--
.../MultilevelNavigationSamplePage1.xaml.cs | 9 ++++--
.../MultilevelNavigationSamplePage2.xaml | 4 +--
.../MultilevelNavigationSamplePage2.xaml.cs | 9 ++++--
.../MultilevelNavigationSamplePage3.xaml | 4 +--
.../MultilevelNavigationSamplePage3.xaml.cs | 9 ++++--
src/Wpf.Ui/Contracts/INavigationService.cs | 2 +-
.../Controls/Navigation/INavigationView.cs | 2 +-
.../Navigation/NavigationView.Base.cs | 28 +++++++++++++------
.../Navigation/NavigationView.Navigation.cs | 4 ++-
.../NavigationViewBreadcrumbItem.cs | 7 ++++-
15 files changed, 73 insertions(+), 30 deletions(-)
diff --git a/src/Wpf.Ui.Gallery/App.xaml.cs b/src/Wpf.Ui.Gallery/App.xaml.cs
index e54ac024a..c7aa99d54 100644
--- a/src/Wpf.Ui.Gallery/App.xaml.cs
+++ b/src/Wpf.Ui.Gallery/App.xaml.cs
@@ -17,7 +17,6 @@
using Wpf.Ui.Gallery.ViewModels.Pages.Icons;
using Wpf.Ui.Gallery.ViewModels.Pages.Media;
using Wpf.Ui.Gallery.ViewModels.Pages.Navigation;
-using Wpf.Ui.Gallery.ViewModels.Pages.Samples;
using Wpf.Ui.Gallery.ViewModels.Pages.StatusAndInfo;
using Wpf.Ui.Gallery.ViewModels.Pages.Text;
using Wpf.Ui.Gallery.ViewModels.Pages.Windows;
diff --git a/src/Wpf.Ui.Gallery/ViewModels/Pages/Navigation/MultilevelNavigationSample.cs b/src/Wpf.Ui.Gallery/ViewModels/Pages/Navigation/MultilevelNavigationSample.cs
index e60d89199..976ded1d2 100644
--- a/src/Wpf.Ui.Gallery/ViewModels/Pages/Navigation/MultilevelNavigationSample.cs
+++ b/src/Wpf.Ui.Gallery/ViewModels/Pages/Navigation/MultilevelNavigationSample.cs
@@ -1,4 +1,9 @@
-namespace Wpf.Ui.Gallery.ViewModels.Pages.Samples;
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT.
+// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
+// All Rights Reserved.
+
+namespace Wpf.Ui.Gallery.ViewModels.Pages.Navigation;
public partial class MultilevelNavigationSample
{
diff --git a/src/Wpf.Ui.Gallery/Views/Pages/Navigation/MultilevelNavigationPage.xaml b/src/Wpf.Ui.Gallery/Views/Pages/Navigation/MultilevelNavigationPage.xaml
index e9e003476..d3e8a0668 100644
--- a/src/Wpf.Ui.Gallery/Views/Pages/Navigation/MultilevelNavigationPage.xaml
+++ b/src/Wpf.Ui.Gallery/Views/Pages/Navigation/MultilevelNavigationPage.xaml
@@ -5,11 +5,11 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Wpf.Ui.Gallery.Views.Pages.Navigation"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:samples="clr-namespace:Wpf.Ui.Gallery.ViewModels.Pages.Samples"
+ xmlns:navigation="clr-namespace:Wpf.Ui.Gallery.ViewModels.Pages.Navigation"
xmlns:samples1="clr-namespace:Wpf.Ui.Gallery.Views.Pages.Samples"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
Title="MultilevelNavigationPage"
- d:DataContext="{d:DesignInstance samples:MultilevelNavigationSample,
+ d:DataContext="{d:DesignInstance navigation:MultilevelNavigationSample,
IsDesignTimeCreatable=False}"
d:DesignHeight="450"
d:DesignWidth="800"
diff --git a/src/Wpf.Ui.Gallery/Views/Pages/Navigation/MultilevelNavigationPage.xaml.cs b/src/Wpf.Ui.Gallery/Views/Pages/Navigation/MultilevelNavigationPage.xaml.cs
index 3f27027e1..493b9245e 100644
--- a/src/Wpf.Ui.Gallery/Views/Pages/Navigation/MultilevelNavigationPage.xaml.cs
+++ b/src/Wpf.Ui.Gallery/Views/Pages/Navigation/MultilevelNavigationPage.xaml.cs
@@ -1,5 +1,10 @@
-using Wpf.Ui.Controls.Navigation;
-using Wpf.Ui.Gallery.ViewModels.Pages.Samples;
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT.
+// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
+// All Rights Reserved.
+
+using Wpf.Ui.Controls.Navigation;
+using Wpf.Ui.Gallery.ViewModels.Pages.Navigation;
namespace Wpf.Ui.Gallery.Views.Pages.Navigation;
diff --git a/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage1.xaml b/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage1.xaml
index a760fee21..78357bc1a 100644
--- a/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage1.xaml
+++ b/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage1.xaml
@@ -4,11 +4,11 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:samples="clr-namespace:Wpf.Ui.Gallery.ViewModels.Pages.Samples"
+ xmlns:navigation="clr-namespace:Wpf.Ui.Gallery.ViewModels.Pages.Navigation"
xmlns:samples1="clr-namespace:Wpf.Ui.Gallery.Views.Pages.Samples"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
Title="MultilevelNavigationSamplePage"
- d:DataContext="{d:DesignInstance samples:MultilevelNavigationSample,
+ d:DataContext="{d:DesignInstance navigation:MultilevelNavigationSample,
IsDesignTimeCreatable=False}"
d:DesignHeight="450"
d:DesignWidth="800"
diff --git a/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage1.xaml.cs b/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage1.xaml.cs
index d6d8ff659..fce80d4bc 100644
--- a/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage1.xaml.cs
+++ b/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage1.xaml.cs
@@ -1,5 +1,10 @@
-using Wpf.Ui.Controls.Navigation;
-using Wpf.Ui.Gallery.ViewModels.Pages.Samples;
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT.
+// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
+// All Rights Reserved.
+
+using Wpf.Ui.Controls.Navigation;
+using Wpf.Ui.Gallery.ViewModels.Pages.Navigation;
namespace Wpf.Ui.Gallery.Views.Pages.Samples;
diff --git a/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage2.xaml b/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage2.xaml
index e417a1ca8..7a2b47bc0 100644
--- a/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage2.xaml
+++ b/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage2.xaml
@@ -5,10 +5,10 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Wpf.Ui.Gallery.Views.Pages.Samples"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:samples="clr-namespace:Wpf.Ui.Gallery.ViewModels.Pages.Samples"
+ xmlns:navigation="clr-namespace:Wpf.Ui.Gallery.ViewModels.Pages.Navigation"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
Title="MultilevelNavigationSamplePage2"
- d:DataContext="{d:DesignInstance samples:MultilevelNavigationSample,
+ d:DataContext="{d:DesignInstance navigation:MultilevelNavigationSample,
IsDesignTimeCreatable=False}"
d:DesignHeight="450"
d:DesignWidth="800"
diff --git a/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage2.xaml.cs b/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage2.xaml.cs
index 348f45c0a..65c9a2116 100644
--- a/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage2.xaml.cs
+++ b/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage2.xaml.cs
@@ -1,5 +1,10 @@
-using Wpf.Ui.Controls.Navigation;
-using Wpf.Ui.Gallery.ViewModels.Pages.Samples;
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT.
+// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
+// All Rights Reserved.
+
+using Wpf.Ui.Controls.Navigation;
+using Wpf.Ui.Gallery.ViewModels.Pages.Navigation;
namespace Wpf.Ui.Gallery.Views.Pages.Samples;
diff --git a/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage3.xaml b/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage3.xaml
index 52169358a..a15cd4dd1 100644
--- a/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage3.xaml
+++ b/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage3.xaml
@@ -5,10 +5,10 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Wpf.Ui.Gallery.Views.Pages.Samples"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:samples="clr-namespace:Wpf.Ui.Gallery.ViewModels.Pages.Samples"
+ xmlns:navigation="clr-namespace:Wpf.Ui.Gallery.ViewModels.Pages.Navigation"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
Title="MultilevelNavigationSamplePage3"
- d:DataContext="{d:DesignInstance samples:MultilevelNavigationSample,
+ d:DataContext="{d:DesignInstance navigation:MultilevelNavigationSample,
IsDesignTimeCreatable=False}"
d:DesignHeight="450"
d:DesignWidth="800"
diff --git a/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage3.xaml.cs b/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage3.xaml.cs
index 1db06245c..548529966 100644
--- a/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage3.xaml.cs
+++ b/src/Wpf.Ui.Gallery/Views/Pages/Samples/MultilevelNavigationSamplePage3.xaml.cs
@@ -1,5 +1,10 @@
-using Wpf.Ui.Controls.Navigation;
-using Wpf.Ui.Gallery.ViewModels.Pages.Samples;
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT.
+// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
+// All Rights Reserved.
+
+using Wpf.Ui.Controls.Navigation;
+using Wpf.Ui.Gallery.ViewModels.Pages.Navigation;
namespace Wpf.Ui.Gallery.Views.Pages.Samples;
diff --git a/src/Wpf.Ui/Contracts/INavigationService.cs b/src/Wpf.Ui/Contracts/INavigationService.cs
index 737a19515..e7fa730c6 100644
--- a/src/Wpf.Ui/Contracts/INavigationService.cs
+++ b/src/Wpf.Ui/Contracts/INavigationService.cs
@@ -51,7 +51,7 @@ public interface INavigationService
bool GoBack();
///
- /// In work
+ /// Synchronously adds an element to the navigation stack and navigates current navigation Frame to the
///
///
///
diff --git a/src/Wpf.Ui/Controls/Navigation/INavigationView.cs b/src/Wpf.Ui/Controls/Navigation/INavigationView.cs
index f3374f79d..f1eea75ce 100644
--- a/src/Wpf.Ui/Controls/Navigation/INavigationView.cs
+++ b/src/Wpf.Ui/Controls/Navigation/INavigationView.cs
@@ -186,7 +186,7 @@ public interface INavigationView
bool Navigate(string pageIdOrTargetTag, object? dataContext = null);
///
- ///
+ /// Synchronously adds an element to the navigation stack and navigates current navigation Frame to the
///
///
///
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs b/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs
index 6d9f236dd..2389f1e22 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs
@@ -205,8 +205,10 @@ private void AutoSuggestBoxOnSuggestionChosen(object sender, RoutedEventArgs e)
protected virtual void AddItemsToDictionaries(IList list)
{
- foreach (var singleMenuItem in list)
+ for (var i = 0; i < list.Count; i++)
{
+ var singleMenuItem = list[i];
+
if (singleMenuItem is not INavigationViewItem singleNavigationViewItem)
continue;
@@ -214,10 +216,13 @@ protected virtual void AddItemsToDictionaries(IList list)
PageIdOrTargetTagNavigationViewsDictionary.Add(singleNavigationViewItem.Id, singleNavigationViewItem);
if (!PageIdOrTargetTagNavigationViewsDictionary.ContainsKey(singleNavigationViewItem.TargetPageTag))
- PageIdOrTargetTagNavigationViewsDictionary.Add(singleNavigationViewItem.TargetPageTag, singleNavigationViewItem);
+ PageIdOrTargetTagNavigationViewsDictionary.Add(singleNavigationViewItem.TargetPageTag,
+ singleNavigationViewItem);
- if (singleNavigationViewItem.TargetPageType is not null && !PageTypeNavigationViewsDictionary.ContainsKey(singleNavigationViewItem.TargetPageType))
- PageTypeNavigationViewsDictionary.Add(singleNavigationViewItem.TargetPageType, singleNavigationViewItem);
+ if (singleNavigationViewItem.TargetPageType is not null &&
+ !PageTypeNavigationViewsDictionary.ContainsKey(singleNavigationViewItem.TargetPageType))
+ PageTypeNavigationViewsDictionary.Add(singleNavigationViewItem.TargetPageType,
+ singleNavigationViewItem);
singleNavigationViewItem.IsMenuElement = true;
@@ -236,12 +241,15 @@ protected virtual void AddItemsToDictionaries()
protected virtual void AddItemsToAutoSuggestBoxItems(IList list)
{
- foreach (var singleMenuItem in list)
+ for (var i = 0; i < list.Count; i++)
{
+ var singleMenuItem = list[i];
+
if (singleMenuItem is not NavigationViewItem singleNavigationViewItem)
continue;
- if (singleNavigationViewItem is { Content: string content, TargetPageType: { } } && !string.IsNullOrWhiteSpace(content))
+ if (singleNavigationViewItem is { Content: string content, TargetPageType: { } } &&
+ !string.IsNullOrWhiteSpace(content))
_autoSuggestBoxItems.Add(content);
if (!(singleNavigationViewItem.MenuItems?.Count > 0))
@@ -259,8 +267,10 @@ protected virtual void AddItemsToAutoSuggestBoxItems()
protected virtual bool NavigateToMenuItemFromAutoSuggestBox(IList list, string selectedSuggestBoxItem)
{
- foreach (var singleMenuItem in list)
+ for (var i = 0; i < list.Count; i++)
{
+ var singleMenuItem = list[i];
+
if (singleMenuItem is not NavigationViewItem singleNavigationViewItem)
continue;
@@ -284,8 +294,10 @@ protected virtual bool NavigateToMenuItemFromAutoSuggestBox(IList list, string s
protected virtual void UpdateMenuItemsTemplate(IList list)
{
- foreach (var singleMenuItem in list)
+ for (var i = 0; i < list.Count; i++)
{
+ var singleMenuItem = list[i];
+
if (singleMenuItem is not NavigationViewItem singleNavigationViewItem)
continue;
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs b/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
index 047f9a600..7e68519e5 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
@@ -58,6 +58,7 @@ public virtual bool Navigate(string pageIdOrTargetTag, object? dataContext = nul
return NavigateInternal(navigationViewItem, dataContext, true, true, false);
}
+ ///
public virtual bool NavigateWithHierarchy(Type pageType, object? dataContext = null)
{
if (!PageTypeNavigationViewsDictionary.TryGetValue(pageType, out var navigationViewItem))
@@ -119,6 +120,7 @@ public virtual bool GoBack()
var itemId = Journal[Journal.Count - 2];
_isBackwardsNavigated = true;
+ OnBackRequested();
return Navigate(itemId);
}
@@ -151,7 +153,7 @@ private bool NavigateInternal(INavigationViewItem viewItem, object? dataContext,
if (NavigationStack.Count > 0 && NavigationStack[NavigationStack.Count -1] == viewItem)
return false;
- Debug.WriteLine($"DEBUG | {viewItem.Id} - {viewItem.TargetPageTag ?? "NO_TAG"} | NAVIGATED");
+ Debug.WriteLine($"DEBUG | {viewItem.Id} - {(string.IsNullOrEmpty(viewItem.TargetPageTag) ? "NO_TAG" : viewItem.TargetPageTag)} - {viewItem.TargetPageType} | NAVIGATED");
if (!RenderSelectedItemContent(viewItem, dataContext))
return false;
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationViewBreadcrumbItem.cs b/src/Wpf.Ui/Controls/Navigation/NavigationViewBreadcrumbItem.cs
index 822fba5f2..3db4041e3 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationViewBreadcrumbItem.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationViewBreadcrumbItem.cs
@@ -1,4 +1,9 @@
-namespace Wpf.Ui.Controls.Navigation;
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT.
+// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
+// All Rights Reserved.
+
+namespace Wpf.Ui.Controls.Navigation;
internal class NavigationViewBreadcrumbItem
{
From 6588c1ebaaf358d68814bc43fffb1ffef0c2fcad Mon Sep 17 00:00:00 2001
From: Ivan Dmitriev <42055372+IvanDmitriev1@users.noreply.github.com>
Date: Fri, 27 Jan 2023 09:56:45 +0600
Subject: [PATCH 21/27] added EnableDebugMessages property
---
.../Views/Windows/MainWindow.xaml | 1 +
.../Controls/Navigation/NavigationView.Base.cs | 8 ++++++--
.../Navigation/NavigationView.Navigation.cs | 9 ++++-----
.../Navigation/NavigationView.Properties.cs | 17 ++++++++++++++++-
4 files changed, 27 insertions(+), 8 deletions(-)
diff --git a/src/Wpf.Ui.Gallery/Views/Windows/MainWindow.xaml b/src/Wpf.Ui.Gallery/Views/Windows/MainWindow.xaml
index 29fa18b81..c1f8cd485 100644
--- a/src/Wpf.Ui.Gallery/Views/Windows/MainWindow.xaml
+++ b/src/Wpf.Ui.Gallery/Views/Windows/MainWindow.xaml
@@ -28,6 +28,7 @@
/// This virtual method is called when is clicked.
///
- protected virtual void OnBackButtonClick(object sender, RoutedEventArgs e) => GoBack();
+ protected virtual void OnBackButtonClick(object sender, RoutedEventArgs e)
+ {
+ GoBack();
+ OnBackRequested();
+ }
///
/// This virtual method is called when is clicked.
///
protected virtual void OnToggleButtonClick(object sender, RoutedEventArgs e)
{
- Debug.WriteLine("Toggle");
+ Debug.WriteLine(EnableDebugMessages, "Toggle");
}
///
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs b/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
index 7e68519e5..d1a12ea4d 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
@@ -120,7 +120,6 @@ public virtual bool GoBack()
var itemId = Journal[Journal.Count - 2];
_isBackwardsNavigated = true;
- OnBackRequested();
return Navigate(itemId);
}
@@ -153,7 +152,7 @@ private bool NavigateInternal(INavigationViewItem viewItem, object? dataContext,
if (NavigationStack.Count > 0 && NavigationStack[NavigationStack.Count -1] == viewItem)
return false;
- Debug.WriteLine($"DEBUG | {viewItem.Id} - {(string.IsNullOrEmpty(viewItem.TargetPageTag) ? "NO_TAG" : viewItem.TargetPageTag)} - {viewItem.TargetPageType} | NAVIGATED");
+ Debug.WriteLineIf(EnableDebugMessages, $"DEBUG | {viewItem.Id} - {(string.IsNullOrEmpty(viewItem.TargetPageTag) ? "NO_TAG" : viewItem.TargetPageTag)} - {viewItem.TargetPageType} | NAVIGATED");
if (!RenderSelectedItemContent(viewItem, dataContext))
return false;
@@ -192,9 +191,9 @@ private void AddToJournal(INavigationViewItem viewItem)
IsBackEnabled = CanGoBack;
#if DEBUG
- Debug.WriteLine($"JOURNAL INDEX {_currentIndexInJournal}");
+ Debug.WriteLineIf(EnableDebugMessages, $"JOURNAL INDEX {_currentIndexInJournal}");
if (Journal.Count > 0)
- Debug.WriteLine($"JOURNAL LAST ELEMENT {Journal[Journal.Count - 1]}");
+ Debug.WriteLineIf(EnableDebugMessages, $"JOURNAL LAST ELEMENT {Journal[Journal.Count - 1]}");
#endif
}
@@ -224,7 +223,7 @@ private bool RenderSelectedItemContent(INavigationViewItem viewItem, object? dat
var pageInstance = GetNavigationItemInstance(viewItem);
if (OnNavigating(pageInstance))
{
- Debug.WriteLine("Navigation canceled");
+ Debug.WriteLineIf(EnableDebugMessages, "Navigation canceled");
return false;
}
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationView.Properties.cs b/src/Wpf.Ui/Controls/Navigation/NavigationView.Properties.cs
index 56804c876..007a06bea 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationView.Properties.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationView.Properties.cs
@@ -8,7 +8,6 @@
using System;
using System.Collections;
-using System.Collections.Generic;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
@@ -18,6 +17,13 @@ namespace Wpf.Ui.Controls.Navigation;
public partial class NavigationView
{
+ ///
+ /// Property for .
+ ///
+ public static readonly DependencyProperty EnableDebugMessagesProperty =
+ DependencyProperty.Register(nameof(EnableDebugMessages), typeof(bool), typeof(NavigationView),
+ new FrameworkPropertyMetadata(false));
+
///
/// Property for .
///
@@ -175,6 +181,15 @@ public partial class NavigationView
typeof(TransitionType), typeof(NavigationView),
new FrameworkPropertyMetadata(TransitionType.FadeInWithSlide));
+ ///
+ /// Enables or disables debugging messages for this control
+ ///
+ public bool EnableDebugMessages
+ {
+ get => (bool) GetValue(EnableDebugMessagesProperty);
+ set => SetValue(EnableDebugMessagesProperty, value);
+ }
+
///
public object? Header
{
From 216ff0ba012192fad5696509560f455a83f7e91d Mon Sep 17 00:00:00 2001
From: Ivan Dmitriev <42055372+IvanDmitriev1@users.noreply.github.com>
Date: Fri, 27 Jan 2023 10:34:24 +0600
Subject: [PATCH 22/27] start using System.Buffers.ArrayPool
---
src/Wpf.Ui.Gallery/App.xaml.cs | 2 +-
.../Navigation/NavigationView.Navigation.cs | 35 +++++++++++++++----
2 files changed, 29 insertions(+), 8 deletions(-)
diff --git a/src/Wpf.Ui.Gallery/App.xaml.cs b/src/Wpf.Ui.Gallery/App.xaml.cs
index c7aa99d54..c3311f208 100644
--- a/src/Wpf.Ui.Gallery/App.xaml.cs
+++ b/src/Wpf.Ui.Gallery/App.xaml.cs
@@ -50,7 +50,7 @@ public partial class App : Application
// https://docs.microsoft.com/dotnet/core/extensions/logging
private static readonly IHost _host = Host
.CreateDefaultBuilder()
- .ConfigureAppConfiguration(c => { c.SetBasePath(Path.GetDirectoryName(Assembly.GetEntryAssembly()!.Location)); })
+ .ConfigureAppConfiguration(c => { c.SetBasePath(AppContext.BaseDirectory); })
.ConfigureServices((context, services) =>
{
// App Host
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs b/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
index d1a12ea4d..f6ea931de 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
@@ -20,7 +20,7 @@ public partial class NavigationView
protected readonly List Journal = new(50);
protected readonly ObservableCollection NavigationStack = new();
- private readonly Dictionary> _complexNavigationStackHistory = new();
+ private readonly Dictionary> _complexNavigationStackHistory = new();
private IServiceProvider? _serviceProvider;
private IPageService? _pageService;
@@ -291,24 +291,35 @@ private void RecreateNavigationStackFromHistory(INavigationViewItem item)
return;
var historyList = _complexNavigationStackHistory[item];
+ if (historyList.Count == 0)
+ return;
+
var latestHistory = historyList[historyList.Count - 1];
var startIndex = 0;
- if (latestHistory[0].IsMenuElement)
+ if (latestHistory[0]!.IsMenuElement)
{
startIndex = 1;
- ReplaceThirstElementInNavigationStack(latestHistory[0]);
+ ReplaceThirstElementInNavigationStack(latestHistory[0]!);
}
for (int i = startIndex; i < latestHistory.Length; i++)
{
- AddToNavigationStack(latestHistory[i], true, false);
+ if (latestHistory[i] is null)
+ break;
+
+ AddToNavigationStack(latestHistory[i]!, true, false);
}
+#if NET6_0_OR_GREATER
+ System.Buffers.ArrayPool.Shared.Return(latestHistory!, true);
+#endif
+
historyList.Remove(latestHistory);
- if (historyList.Count == 0)
+ /*if (historyList.Count == 0)
_complexNavigationStackHistory.Remove(item);
+ */
AddToNavigationStack(item, true, false);
}
@@ -323,12 +334,22 @@ private void AddToNavigationStackHistory(INavigationViewItem viewItem)
if (!_complexNavigationStackHistory.TryGetValue(lastItem, out var historyList))
{
- historyList = new List(5);
+ historyList = new List(5);
_complexNavigationStackHistory.Add(lastItem, historyList);
}
+ int arrayLength = NavigationStack.Count - 1 - startIndex;
+ INavigationViewItem[] array;
+
//Initializing an array every time well... not an ideal
- historyList.Add(new INavigationViewItem[NavigationStack.Count - 1 - startIndex]);
+
+#if NET6_0_OR_GREATER
+ array = System.Buffers.ArrayPool.Shared.Rent(arrayLength);
+#else
+ array = new INavigationViewItem[arrayLength];
+#endif
+
+ historyList.Add(array);
var latestHistory = historyList[historyList.Count - 1];
int i = 0;
From 370894ae9f4739ae6e182b3620e5c469af63cec6 Mon Sep 17 00:00:00 2001
From: Ivan Dmitriev <42055372+IvanDmitriev1@users.noreply.github.com>
Date: Fri, 27 Jan 2023 10:46:30 +0600
Subject: [PATCH 23/27] small changes
---
.../Navigation/NavigationView.Base.cs | 21 +++++++++++--------
.../Navigation/NavigationView.Navigation.cs | 8 +++----
2 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs b/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs
index 5d48ef4c6..09615428d 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs
@@ -217,20 +217,23 @@ protected virtual void AddItemsToDictionaries(IList list)
continue;
if (!PageIdOrTargetTagNavigationViewsDictionary.ContainsKey(singleNavigationViewItem.Id))
+ {
PageIdOrTargetTagNavigationViewsDictionary.Add(singleNavigationViewItem.Id, singleNavigationViewItem);
+ }
if (!PageIdOrTargetTagNavigationViewsDictionary.ContainsKey(singleNavigationViewItem.TargetPageTag))
- PageIdOrTargetTagNavigationViewsDictionary.Add(singleNavigationViewItem.TargetPageTag,
- singleNavigationViewItem);
+ {
+ PageIdOrTargetTagNavigationViewsDictionary.Add(singleNavigationViewItem.TargetPageTag, singleNavigationViewItem);
+ }
- if (singleNavigationViewItem.TargetPageType is not null &&
- !PageTypeNavigationViewsDictionary.ContainsKey(singleNavigationViewItem.TargetPageType))
- PageTypeNavigationViewsDictionary.Add(singleNavigationViewItem.TargetPageType,
- singleNavigationViewItem);
+ if (singleNavigationViewItem.TargetPageType is not null && !PageTypeNavigationViewsDictionary.ContainsKey(singleNavigationViewItem.TargetPageType))
+ {
+ PageTypeNavigationViewsDictionary.Add(singleNavigationViewItem.TargetPageType, singleNavigationViewItem);
+ }
singleNavigationViewItem.IsMenuElement = true;
- if (!(singleNavigationViewItem.MenuItems?.Count > 0))
+ if (singleNavigationViewItem.MenuItems.Count <= 0)
continue;
AddItemsToDictionaries(singleNavigationViewItem.MenuItems);
@@ -256,7 +259,7 @@ protected virtual void AddItemsToAutoSuggestBoxItems(IList list)
!string.IsNullOrWhiteSpace(content))
_autoSuggestBoxItems.Add(content);
- if (!(singleNavigationViewItem.MenuItems?.Count > 0))
+ if (singleNavigationViewItem.MenuItems.Count <= 0)
continue;
AddItemsToAutoSuggestBoxItems(singleNavigationViewItem.MenuItems);
@@ -287,7 +290,7 @@ protected virtual bool NavigateToMenuItemFromAutoSuggestBox(IList list, string s
return true;
}
- if (!(singleNavigationViewItem.MenuItems?.Count > 0))
+ if (singleNavigationViewItem.MenuItems.Count <= 0)
continue;
NavigateToMenuItemFromAutoSuggestBox(singleNavigationViewItem.MenuItems, selectedSuggestBoxItem);
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs b/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
index f6ea931de..cb414a309 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
@@ -312,15 +312,15 @@ private void RecreateNavigationStackFromHistory(INavigationViewItem item)
AddToNavigationStack(latestHistory[i]!, true, false);
}
-#if NET6_0_OR_GREATER
- System.Buffers.ArrayPool.Shared.Return(latestHistory!, true);
-#endif
-
historyList.Remove(latestHistory);
/*if (historyList.Count == 0)
_complexNavigationStackHistory.Remove(item);
*/
+#if NET6_0_OR_GREATER
+ System.Buffers.ArrayPool.Shared.Return(latestHistory!, true);
+#endif
+
AddToNavigationStack(item, true, false);
}
From 023143869703302ff19f45bda12a799e909ead80 Mon Sep 17 00:00:00 2001
From: Ivan Dmitriev <42055372+IvanDmitriev1@users.noreply.github.com>
Date: Fri, 27 Jan 2023 10:56:17 +0600
Subject: [PATCH 24/27] added license
---
.../Navigation/NavigationView.AttachedProperties.cs | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationView.AttachedProperties.cs b/src/Wpf.Ui/Controls/Navigation/NavigationView.AttachedProperties.cs
index 8e3841aaa..6d25f6bd7 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationView.AttachedProperties.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationView.AttachedProperties.cs
@@ -1,4 +1,9 @@
-using System.Windows;
+// This Source Code Form is subject to the terms of the MIT License.
+// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT.
+// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
+// All Rights Reserved.
+
+using System.Windows;
namespace Wpf.Ui.Controls.Navigation;
From 5f588bba9eb5e2059af4c9ca48bdd6dd5a752ba3 Mon Sep 17 00:00:00 2001
From: Ivan Dmitriev <42055372+IvanDmitriev1@users.noreply.github.com>
Date: Fri, 27 Jan 2023 14:59:35 +0600
Subject: [PATCH 25/27] SelectedItem changed when it from menu
---
.../Navigation/NavigationView.Navigation.cs | 48 +++++++++++--------
1 file changed, 27 insertions(+), 21 deletions(-)
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs b/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
index cb414a309..54fac31b2 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
@@ -130,7 +130,6 @@ public virtual void ClearJournal()
_currentIndexInJournal = 0;
Journal.Clear();
- NavigationStack.Clear();
_complexNavigationStackHistory.Clear();
}
@@ -154,21 +153,32 @@ private bool NavigateInternal(INavigationViewItem viewItem, object? dataContext,
Debug.WriteLineIf(EnableDebugMessages, $"DEBUG | {viewItem.Id} - {(string.IsNullOrEmpty(viewItem.TargetPageTag) ? "NO_TAG" : viewItem.TargetPageTag)} - {viewItem.TargetPageType} | NAVIGATED");
- if (!RenderSelectedItemContent(viewItem, dataContext))
+ var pageInstance = GetNavigationItemInstance(viewItem);
+
+ if (OnNavigating(pageInstance))
+ {
+ Debug.WriteLineIf(EnableDebugMessages, "Navigation canceled");
return false;
+ }
- if (!notifyAboutUpdate)
- return true;
+ ApplyAttachedProperties(viewItem, pageInstance);
+ UpdateContent(pageInstance, dataContext);
AddToNavigationStack(viewItem, addToNavigationStack, _isBackwardsNavigated);
AddToJournal(viewItem);
- if (bringIntoView && viewItem is FrameworkElement frameworkElement)
+ if (!notifyAboutUpdate)
+ return true;
+
+ if (SelectedItem != NavigationStack[0] && NavigationStack[0].IsMenuElement)
{
- frameworkElement.BringIntoView();
- frameworkElement.Focus(); // TODO: Element or content?
+ SelectedItem = NavigationStack[0];
+ OnSelectionChanged();
}
+ if (bringIntoView)
+ BringIntoViewNavigationViewItem(viewItem);
+
_isBackwardsNavigated = false;
return true;
}
@@ -218,20 +228,10 @@ private object GetNavigationItemInstance(INavigationViewItem viewItem)
throw new ArgumentException("Failed to create instance of the page");
}
- private bool RenderSelectedItemContent(INavigationViewItem viewItem, object? dataContext)
+ private static void ApplyAttachedProperties(INavigationViewItem viewItem, object pageInstance)
{
- var pageInstance = GetNavigationItemInstance(viewItem);
- if (OnNavigating(pageInstance))
- {
- Debug.WriteLineIf(EnableDebugMessages, "Navigation canceled");
- return false;
- }
-
if (pageInstance is FrameworkElement frameworkElement && GetHeaderContent(frameworkElement) is {} headerContent)
viewItem.Content = headerContent;
-
- UpdateContent(pageInstance, dataContext);
- return true;
}
private void UpdateContent(object? content, object? dataContext = null)
@@ -242,6 +242,15 @@ private void UpdateContent(object? content, object? dataContext = null)
NavigationViewContentPresenter.Navigate(content);
}
+ private static void BringIntoViewNavigationViewItem(INavigationViewItem viewItem)
+ {
+ if (viewItem is not FrameworkElement frameworkElement)
+ return;
+
+ frameworkElement.BringIntoView();
+ frameworkElement.Focus(); // TODO: Element or content?
+ }
+
#region Navigation stack methods
private void AddToNavigationStack(INavigationViewItem viewItem, bool addToNavigationStack, bool isBackwardsNavigated)
@@ -258,9 +267,6 @@ private void AddToNavigationStack(INavigationViewItem viewItem, bool addToNaviga
if (!addToNavigationStack)
UpdateCurrentNavigationStackItem(viewItem);
- SelectedItem = NavigationStack[NavigationStack.Count - 1];
- OnSelectionChanged();
-
ClearNavigationStack(viewItem);
}
From ac32a6753da8132a0fef9e96d6fa34b2f4fcb73a Mon Sep 17 00:00:00 2001
From: Ivan Dmitriev <42055372+IvanDmitriev1@users.noreply.github.com>
Date: Sat, 28 Jan 2023 09:20:02 +0600
Subject: [PATCH 26/27] Clean up
---
.../Navigation/NavigationView.Base.cs | 6 +--
.../Navigation/NavigationView.Navigation.cs | 51 +++++--------------
2 files changed, 16 insertions(+), 41 deletions(-)
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs b/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs
index 09615428d..9ac3ae058 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationView.Base.cs
@@ -171,7 +171,7 @@ internal void OnNavigationViewItemClick(NavigationViewItem navigationViewItem)
{
OnItemInvoked();
- NavigateInternal(navigationViewItem, null, true, false, false);
+ NavigateInternal(navigationViewItem);
}
protected virtual void BreadcrumbBarOnItemClicked(BreadcrumbBar sender, BreadcrumbBarItemClickedEventArgs e)
@@ -283,9 +283,9 @@ protected virtual bool NavigateToMenuItemFromAutoSuggestBox(IList list, string s
if (singleNavigationViewItem.Content is string content && content == selectedSuggestBoxItem)
{
- NavigateInternal(singleNavigationViewItem, null, true, false, false);
+ NavigateInternal(singleNavigationViewItem);
singleNavigationViewItem.BringIntoView();
- singleNavigationViewItem.Focus();
+ singleNavigationViewItem.Focus(); // TODO: Element or content?
return true;
}
diff --git a/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs b/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
index 54fac31b2..56412eecd 100644
--- a/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
+++ b/src/Wpf.Ui/Controls/Navigation/NavigationView.Navigation.cs
@@ -25,7 +25,6 @@ public partial class NavigationView
private IServiceProvider? _serviceProvider;
private IPageService? _pageService;
- private bool _isBackwardsNavigated;
private int _currentIndexInJournal;
///
@@ -46,7 +45,7 @@ public virtual bool Navigate(Type pageType, object? dataContext = null)
if (!PageTypeNavigationViewsDictionary.TryGetValue(pageType, out var navigationViewItem))
return TryToNavigateWithoutINavigationViewItem(pageType, false, dataContext);
- return NavigateInternal(navigationViewItem, dataContext, true, true, false);
+ return NavigateInternal(navigationViewItem, dataContext);
}
///
@@ -55,7 +54,7 @@ public virtual bool Navigate(string pageIdOrTargetTag, object? dataContext = nul
if (!PageIdOrTargetTagNavigationViewsDictionary.TryGetValue(pageIdOrTargetTag, out var navigationViewItem))
return false;
- return NavigateInternal(navigationViewItem, dataContext, true, true, false);
+ return NavigateInternal(navigationViewItem, dataContext);
}
///
@@ -64,7 +63,7 @@ public virtual bool NavigateWithHierarchy(Type pageType, object? dataContext = n
if (!PageTypeNavigationViewsDictionary.TryGetValue(pageType, out var navigationViewItem))
return TryToNavigateWithoutINavigationViewItem(pageType, true, dataContext);
- return NavigateInternal(navigationViewItem, dataContext, true, true, true);
+ return NavigateInternal(navigationViewItem, dataContext, true);
}
///
@@ -119,9 +118,8 @@ public virtual bool GoBack()
return false;
var itemId = Journal[Journal.Count - 2];
- _isBackwardsNavigated = true;
- return Navigate(itemId);
+ return NavigateInternal(PageIdOrTargetTagNavigationViewsDictionary[itemId], null, false, true);
}
///
@@ -137,7 +135,7 @@ private bool TryToNavigateWithoutINavigationViewItem(Type pageType, bool addToNa
{
var navigationViewItem = new NavigationViewItem(pageType);
- if (!NavigateInternal(navigationViewItem, dataContext, true, true, addToNavigationStack))
+ if (!NavigateInternal(navigationViewItem, dataContext, addToNavigationStack))
return false;
PageTypeNavigationViewsDictionary.Add(pageType, navigationViewItem);
@@ -146,7 +144,7 @@ private bool TryToNavigateWithoutINavigationViewItem(Type pageType, bool addToNa
return true;
}
- private bool NavigateInternal(INavigationViewItem viewItem, object? dataContext, bool notifyAboutUpdate, bool bringIntoView, bool addToNavigationStack)
+ private bool NavigateInternal(INavigationViewItem viewItem, object? dataContext = null, bool addToNavigationStack = false, bool isBackwardsNavigated = false)
{
if (NavigationStack.Count > 0 && NavigationStack[NavigationStack.Count -1] == viewItem)
return false;
@@ -164,31 +162,22 @@ private bool NavigateInternal(INavigationViewItem viewItem, object? dataContext,
ApplyAttachedProperties(viewItem, pageInstance);
UpdateContent(pageInstance, dataContext);
- AddToNavigationStack(viewItem, addToNavigationStack, _isBackwardsNavigated);
- AddToJournal(viewItem);
-
- if (!notifyAboutUpdate)
- return true;
+ AddToNavigationStack(viewItem, addToNavigationStack, isBackwardsNavigated);
+ AddToJournal(viewItem, isBackwardsNavigated);
if (SelectedItem != NavigationStack[0] && NavigationStack[0].IsMenuElement)
{
SelectedItem = NavigationStack[0];
OnSelectionChanged();
}
-
- if (bringIntoView)
- BringIntoViewNavigationViewItem(viewItem);
-
- _isBackwardsNavigated = false;
+
return true;
}
- private void AddToJournal(INavigationViewItem viewItem)
+ private void AddToJournal(INavigationViewItem viewItem, bool isBackwardsNavigated)
{
- if (_isBackwardsNavigated)
+ if (isBackwardsNavigated)
{
- _isBackwardsNavigated = false;
-
Journal.RemoveAt(Journal.LastIndexOf(Journal[Journal.Count - 2]));
Journal.RemoveAt(Journal.LastIndexOf(Journal[Journal.Count - 1]));
@@ -242,15 +231,6 @@ private void UpdateContent(object? content, object? dataContext = null)
NavigationViewContentPresenter.Navigate(content);
}
- private static void BringIntoViewNavigationViewItem(INavigationViewItem viewItem)
- {
- if (viewItem is not FrameworkElement frameworkElement)
- return;
-
- frameworkElement.BringIntoView();
- frameworkElement.Focus(); // TODO: Element or content?
- }
-
#region Navigation stack methods
private void AddToNavigationStack(INavigationViewItem viewItem, bool addToNavigationStack, bool isBackwardsNavigated)
@@ -293,15 +273,10 @@ private void UpdateCurrentNavigationStackItem(INavigationViewItem viewItem)
private void RecreateNavigationStackFromHistory(INavigationViewItem item)
{
- if(!_complexNavigationStackHistory.ContainsKey(item))
- return;
-
- var historyList = _complexNavigationStackHistory[item];
- if (historyList.Count == 0)
+ if (!_complexNavigationStackHistory.TryGetValue(item, out var historyList) || historyList.Count == 0)
return;
var latestHistory = historyList[historyList.Count - 1];
-
var startIndex = 0;
if (latestHistory[0]!.IsMenuElement)
@@ -337,7 +312,7 @@ private void AddToNavigationStackHistory(INavigationViewItem viewItem)
if (startIndex < 0)
startIndex = 0;
-
+
if (!_complexNavigationStackHistory.TryGetValue(lastItem, out var historyList))
{
historyList = new List(5);
From 37dffae75c6f278f6e5134065a18f9c4d2f91efb Mon Sep 17 00:00:00 2001
From: Ivan Dmitriev <42055372+IvanDmitriev1@users.noreply.github.com>
Date: Sun, 29 Jan 2023 21:47:26 +0600
Subject: [PATCH 27/27] Changed naming
---
src/Wpf.Ui.Gallery/ViewModels/Windows/MainWindowViewModel.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Wpf.Ui.Gallery/ViewModels/Windows/MainWindowViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Windows/MainWindowViewModel.cs
index f5078271a..502b8006f 100644
--- a/src/Wpf.Ui.Gallery/ViewModels/Windows/MainWindowViewModel.cs
+++ b/src/Wpf.Ui.Gallery/ViewModels/Windows/MainWindowViewModel.cs
@@ -91,7 +91,7 @@ public MainWindowViewModel(IServiceProvider serviceProvider)
{
new NavigationViewItem { Content = "BreadcrumbBar", TargetPageType = typeof(BreadcrumbBarPage) },
new NavigationViewItem { Content = "NavigationView", TargetPageType = typeof(NavigationViewPage) },
- new NavigationViewItem { Content = "Multilevel navigation demo", TargetPageType = typeof(MultilevelNavigationPage) },
+ new NavigationViewItem { Content = "Multilevel navigation", TargetPageType = typeof(MultilevelNavigationPage) },
new NavigationViewItem { Content = "TabControl", TargetPageType = typeof(TabControlPage) },
}},
new NavigationViewItem {Content = "Status and Info", Icon = new SymbolIcon { Symbol = SymbolRegular.ChatBubblesQuestion24 }, TargetPageType = typeof(StatusAndInfoPage), MenuItems = new ObservableCollection