Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/submenu navigation #1013

Merged
merged 5 commits into from
Mar 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions src/Wpf.Ui.Gallery/ViewModels/Windows/MainWindowViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public partial class MainWindowViewModel : ObservableObject
{
Content = "Design guidance",
Icon = new SymbolIcon { Symbol = SymbolRegular.DesignIdeas24 },
MenuItems = new object[]
MenuItemsSource = new object[]
{
new NavigationViewItem("Typography", SymbolRegular.TextFont24, typeof(TypographyPage)),
new NavigationViewItem("Icons", SymbolRegular.Diversity24, typeof(IconsPage)),
Expand All @@ -46,7 +46,7 @@ public partial class MainWindowViewModel : ObservableObject
new NavigationViewItemSeparator(),
new NavigationViewItem("Basic Input", SymbolRegular.CheckboxChecked24, typeof(BasicInputPage))
{
MenuItems = new object[]
MenuItemsSource = new object[]
{
new NavigationViewItem(nameof(Anchor), typeof(AnchorPage)),
new NavigationViewItem(nameof(Wpf.Ui.Controls.Button), typeof(ButtonPage)),
Expand All @@ -68,7 +68,7 @@ public partial class MainWindowViewModel : ObservableObject
Content = "Collections",
Icon = new SymbolIcon { Symbol = SymbolRegular.Table24 },
TargetPageType = typeof(CollectionsPage),
MenuItems = new object[]
MenuItemsSource = new object[]
{
new NavigationViewItem(nameof(System.Windows.Controls.DataGrid), typeof(DataGridPage)),
new NavigationViewItem(nameof(ListBox), typeof(ListBoxPage)),
Expand All @@ -81,7 +81,7 @@ public partial class MainWindowViewModel : ObservableObject
},
new NavigationViewItem("Date & time", SymbolRegular.CalendarClock24, typeof(DateAndTimePage))
{
MenuItems = new object[]
MenuItemsSource = new object[]
{
new NavigationViewItem(nameof(CalendarDatePicker), typeof(CalendarDatePickerPage)),
new NavigationViewItem(nameof(System.Windows.Controls.Calendar), typeof(CalendarPage)),
Expand All @@ -91,7 +91,7 @@ public partial class MainWindowViewModel : ObservableObject
},
new NavigationViewItem("Dialogs & flyouts", SymbolRegular.Chat24, typeof(DialogsAndFlyoutsPage))
{
MenuItems = new object[]
MenuItemsSource = new object[]
{
new NavigationViewItem(nameof(Snackbar), typeof(SnackbarPage)),
new NavigationViewItem(nameof(ContentDialog), typeof(ContentDialogPage)),
Expand All @@ -102,7 +102,7 @@ public partial class MainWindowViewModel : ObservableObject
#if DEBUG
new NavigationViewItem("Layout", SymbolRegular.News24, typeof(LayoutPage))
{
MenuItems = new object[]
MenuItemsSource = new object[]
{
new NavigationViewItem("Expander", typeof(ExpanderPage)),
new NavigationViewItem("CardControl", typeof(CardControlPage)),
Expand All @@ -115,7 +115,7 @@ public partial class MainWindowViewModel : ObservableObject
Content = "Media",
Icon = new SymbolIcon { Symbol = SymbolRegular.PlayCircle24 },
TargetPageType = typeof(MediaPage),
MenuItems = new object[]
MenuItemsSource = new object[]
{
new NavigationViewItem("Image", typeof(ImagePage)),
new NavigationViewItem("Canvas", typeof(CanvasPage)),
Expand All @@ -125,7 +125,7 @@ public partial class MainWindowViewModel : ObservableObject
},
new NavigationViewItem("Navigation", SymbolRegular.Navigation24, typeof(NavigationPage))
{
MenuItems = new object[]
MenuItemsSource = new object[]
{
new NavigationViewItem("BreadcrumbBar", typeof(BreadcrumbBarPage)),
new NavigationViewItem("NavigationView", typeof(NavigationViewPage)),
Expand All @@ -140,7 +140,7 @@ public partial class MainWindowViewModel : ObservableObject
typeof(StatusAndInfoPage)
)
{
MenuItems = new object[]
MenuItemsSource = new object[]
{
new NavigationViewItem("InfoBadge", typeof(InfoBadgePage)),
new NavigationViewItem("InfoBar", typeof(InfoBarPage)),
Expand All @@ -151,7 +151,7 @@ public partial class MainWindowViewModel : ObservableObject
},
new NavigationViewItem("Text", SymbolRegular.DrawText24, typeof(TextPage))
{
MenuItems = new object[]
MenuItemsSource = new object[]
{
new NavigationViewItem(nameof(AutoSuggestBox), typeof(AutoSuggestBoxPage)),
new NavigationViewItem(nameof(NumberBox), typeof(NumberBoxPage)),
Expand All @@ -164,7 +164,7 @@ public partial class MainWindowViewModel : ObservableObject
},
new NavigationViewItem("System", SymbolRegular.Desktop24, typeof(OpSystemPage))
{
MenuItems = new object[]
MenuItemsSource = new object[]
{
new NavigationViewItem("Clipboard", typeof(ClipboardPage)),
new NavigationViewItem("FilePicker", typeof(FilePickerPage)),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,12 @@
<ui:NavigationViewItem
Content="Menu Item 1"
Icon="{ui:SymbolIcon Home24}"
TargetPageType="{x:Type samples:SamplePage1}" />
TargetPageType="{x:Type samples:SamplePage1}">
<ui:NavigationViewItem.MenuItems>
<ui:NavigationViewItem Content="Menu SubItem 1" TargetPageType="{x:Type samples:SamplePage3}" />
<ui:NavigationViewItem Content="Menu SubItem 2" TargetPageType="{x:Type samples:SamplePage3}" />
</ui:NavigationViewItem.MenuItems>
</ui:NavigationViewItem>
<ui:NavigationViewItem
Content="Menu Item 2"
Icon="{ui:SymbolIcon AppFolder24}"
Expand Down
2 changes: 1 addition & 1 deletion src/Wpf.Ui.Gallery/Views/Windows/SandboxWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public SandboxWindow(SandboxWindowViewModel viewModel)

MyTestNavigationView.Loaded += (sender, args) =>
{
MyTestNavigationView.MenuItems = new ObservableCollection<object>()
MyTestNavigationView.MenuItemsSource = new ObservableCollection<object>()
{
new NavigationViewItem("Home", SymbolRegular.Home24, typeof(SamplePage1))
};
Expand Down
4 changes: 2 additions & 2 deletions src/Wpf.Ui/Controls/NavigationView/INavigationView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public interface INavigationView
/// <summary>
/// Gets the collection of menu items displayed in the NavigationView.
/// </summary>
IList MenuItems { get; set; }
IList MenuItems { get; }

/// <summary>
/// Gets or sets an object source used to generate the content of the NavigationView menu.
Expand All @@ -46,7 +46,7 @@ public interface INavigationView
/// <summary>
/// Gets the list of objects to be used as navigation items in the footer menu.
/// </summary>
IList FooterMenuItems { get; set; }
IList FooterMenuItems { get; }

/// <summary>
/// Gets or sets the object that represents the navigation items to be used in the footer menu.
Expand Down
2 changes: 1 addition & 1 deletion src/Wpf.Ui/Controls/NavigationView/INavigationViewItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public interface INavigationViewItem
/// <summary>
/// Gets the collection of menu items displayed in the NavigationView.
/// </summary>
IList MenuItems { get; set; }
IList MenuItems { get; }

/// <summary>
/// Gets or sets an object source used to generate the content of the NavigationView menu.
Expand Down
138 changes: 55 additions & 83 deletions src/Wpf.Ui/Controls/NavigationView/NavigationView.Base.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@
// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
// All Rights Reserved.

// Based on Windows UI Library
// Copyright(c) Microsoft Corporation.All rights reserved.

using System.Collections;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
Expand All @@ -15,17 +12,15 @@
// ReSharper disable once CheckNamespace
namespace Wpf.Ui.Controls;

// https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.controls.navigationview?view=winrt-22621
// Based on Windows UI Library https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.controls.navigationview?view=winrt-22621

/// <summary>
/// Represents a container that enables navigation of app content. It has a header, a view for the main content, and a menu pane for navigation commands.
/// </summary>
//[ToolboxItem(true)]
//[System.Drawing.ToolboxBitmap(typeof(NavigationView), "NavigationView.bmp")]
public partial class NavigationView : System.Windows.Controls.Control, INavigationView
{
/// <summary>
/// Static constructor which overrides default property metadata.
/// Initializes static members of the <see cref="NavigationView"/> class and overrides default property metadata.
/// </summary>
static NavigationView()
{
Expand All @@ -43,13 +38,18 @@ public NavigationView()
{
NavigationParent = this;

//It really should be here
MenuItems = new ObservableCollection<object>();
FooterMenuItems = new ObservableCollection<object>();

Loaded += OnLoaded;
Unloaded += OnUnloaded;
SizeChanged += OnSizeChanged;

// Initialize MenuItems collection
var menuItems = new ObservableCollection<object>();
menuItems.CollectionChanged += OnMenuItems_CollectionChanged;
SetValue(MenuItemsPropertyKey, menuItems);

var footerMenuItems = new ObservableCollection<object>();
footerMenuItems.CollectionChanged += OnMenuItems_CollectionChanged;
SetValue(FooterMenuItemsPropertyKey, footerMenuItems);
}

/// <inheritdoc/>
Expand Down Expand Up @@ -94,7 +94,7 @@ protected override void OnInitialized(EventArgs e)
private void OnLoaded(object sender, RoutedEventArgs e)
{
// TODO: Refresh
UpdateVisualState((NavigationView)sender);
//UpdateVisualState((NavigationView)sender);
}

/// <summary>
Expand Down Expand Up @@ -283,80 +283,57 @@ AutoSuggestBoxQuerySubmittedEventArgs args
NavigateToMenuItemFromAutoSuggestBox(FooterMenuItems, element);
}

protected virtual void AddItemsToDictionaries(IList list)
protected virtual void AddItemsToDictionaries(IEnumerable list)
{
for (var i = 0; i < list.Count; i++)
foreach (NavigationViewItem singleNavigationViewItem in list.OfType<NavigationViewItem>())
{
var singleMenuItem = list[i];

if (singleMenuItem is not INavigationViewItem singleNavigationViewItem)
continue;

if (!PageIdOrTargetTagNavigationViewsDictionary.ContainsKey(singleNavigationViewItem.Id))
{
PageIdOrTargetTagNavigationViewsDictionary.Add(
singleNavigationViewItem.Id,
singleNavigationViewItem
);
PageIdOrTargetTagNavigationViewsDictionary.Add(singleNavigationViewItem.Id, singleNavigationViewItem);
}

if (
!PageIdOrTargetTagNavigationViewsDictionary.ContainsKey(
singleNavigationViewItem.TargetPageTag
)
)
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)
)
if (singleNavigationViewItem.TargetPageType != null
&& !PageTypeNavigationViewsDictionary.ContainsKey(singleNavigationViewItem.TargetPageType))
{
PageTypeNavigationViewsDictionary.Add(
singleNavigationViewItem.TargetPageType,
singleNavigationViewItem
);
PageTypeNavigationViewsDictionary.Add(singleNavigationViewItem.TargetPageType, singleNavigationViewItem);
}

singleNavigationViewItem.IsMenuElement = true;

if (singleNavigationViewItem.MenuItems.Count <= 0)
continue;

AddItemsToDictionaries(singleNavigationViewItem.MenuItems);
if (singleNavigationViewItem.HasMenuItems)
{
AddItemsToDictionaries(singleNavigationViewItem.MenuItems);
}
}
}


protected virtual void AddItemsToDictionaries()
{
AddItemsToDictionaries(MenuItems);
AddItemsToDictionaries(FooterMenuItems);
}

protected virtual void AddItemsToAutoSuggestBoxItems(IList list)
protected virtual void AddItemsToAutoSuggestBoxItems(IEnumerable list)
{
for (var i = 0; i < list.Count; i++)
foreach (NavigationViewItem singleNavigationViewItem in list.OfType<NavigationViewItem>())
{
var singleMenuItem = list[i];

if (singleMenuItem is not NavigationViewItem singleNavigationViewItem)
continue;

if (
singleNavigationViewItem is { Content: string content, TargetPageType: { } }
&& !string.IsNullOrWhiteSpace(content)
)
&& !String.IsNullOrWhiteSpace(content))
{
_autoSuggestBoxItems.Add(content);
}

if (singleNavigationViewItem.MenuItems.Count <= 0)
continue;

AddItemsToAutoSuggestBoxItems(singleNavigationViewItem.MenuItems);
if (singleNavigationViewItem.HasMenuItems)
{
AddItemsToAutoSuggestBoxItems(singleNavigationViewItem.MenuItems);
}
}
}

Expand All @@ -366,15 +343,10 @@ protected virtual void AddItemsToAutoSuggestBoxItems()
AddItemsToAutoSuggestBoxItems(FooterMenuItems);
}

protected virtual bool NavigateToMenuItemFromAutoSuggestBox(IList list, string selectedSuggestBoxItem)
protected virtual bool NavigateToMenuItemFromAutoSuggestBox(IEnumerable list, string selectedSuggestBoxItem)
{
for (var i = 0; i < list.Count; i++)
foreach (NavigationViewItem singleNavigationViewItem in list.OfType<NavigationViewItem>())
{
var singleMenuItem = list[i];

if (singleMenuItem is not NavigationViewItem singleNavigationViewItem)
continue;

if (singleNavigationViewItem.Content is string content && content == selectedSuggestBoxItem)
{
NavigateInternal(singleNavigationViewItem);
Expand All @@ -384,26 +356,28 @@ protected virtual bool NavigateToMenuItemFromAutoSuggestBox(IList list, string s
return true;
}

if (singleNavigationViewItem.MenuItems.Count <= 0)
continue;

NavigateToMenuItemFromAutoSuggestBox(singleNavigationViewItem.MenuItems, selectedSuggestBoxItem);
if (NavigateToMenuItemFromAutoSuggestBox(singleNavigationViewItem.MenuItems, selectedSuggestBoxItem))
{
return true;
}
}

return false;
}

protected virtual void UpdateMenuItemsTemplate(IList list)
protected virtual void UpdateMenuItemsTemplate(IEnumerable list)
{
for (var i = 0; i < list.Count; i++)
if (ItemTemplate == null)
{
var singleMenuItem = list[i];

if (singleMenuItem is not NavigationViewItem singleNavigationViewItem)
continue;
return;
}

if (ItemTemplate is not null && singleNavigationViewItem.Template != ItemTemplate)
foreach (var item in list)
{
if (item is NavigationViewItem singleNavigationViewItem)
{
singleNavigationViewItem.Template = ItemTemplate;
}
}
}

Expand Down Expand Up @@ -432,16 +406,14 @@ protected virtual void CloseNavigationViewItemMenus()
currentItem.NavigationViewItemParent?.Activate(this);
}

protected void DeactivateMenuItems(IList list)
protected void DeactivateMenuItems(IEnumerable list)
{
for (var i = 0; i < list.Count; i++)
foreach (var item in list)
{
var singleMenuItem = list[i];

if (singleMenuItem is not NavigationViewItem singleNavigationViewItem)
continue;

singleNavigationViewItem.Deactivate(this);
if (item is NavigationViewItem singleNavigationViewItem)
{
singleNavigationViewItem.Deactivate(this);
}
}
}

Expand Down
Loading
Loading