I created a new UWP project with a NavigationView
(winui 2.4) in MainPage.xaml.
I proceeded by binding a hierarchical ObservableCollection
to populate the NavigationView
menu items (1 parent, 4 children)
Launching the application, the hierarchical structure renders as expected, and seem to be working fine.
My next objective would be to collapse every expanded menu item clicking on a button. To do so, the docs suggest using NavigationView.Collapse(NavigationViewItem)
: my intention would be to iterate through NavigationView.MenuItems
and collapse them.
The issue is that it seems NavigationView.MenuItems
returns empty and I cannot figure out why.
I included a Button that prints NavigationView.MenuItems.Count()
, which returns 0.
On the other hand, hard-coding the hierarchical menu items and repeating said procedure seem to work fine.
MainPage.xaml
<Grid>
<muxc:NavigationView x:Name="MainNavigation" MenuItemsSource="{x:Bind categories, Mode=OneWay}">
<muxc:NavigationView.MenuItemTemplate>
<DataTemplate x:DataType="data:Category" >
<muxc:NavigationViewItem Content="{x:Bind Name}" MenuItemsSource="{x:Bind Children}" />
</DataTemplate>
</muxc:NavigationView.MenuItemTemplate>
<Button Content="Do Something" Click="Button_Click" />
</muxc:NavigationView>
</Grid>
MainPage.xaml.cs
public sealed partial class MainPage : Page
{
ObservableCollection<Category> categories = new ObservableCollection<Category>();
public MainPage()
{
this.InitializeComponent();
categories = PopulateHierarchy();
}
private ObservableCollection<Category> PopulateHierarchy()
{
ObservableCollection<Category> list = new ObservableCollection<Category>();
ObservableCollection<Category> children = new ObservableCollection<Category>();
children.Add(new Category { Name = "Child 1" });
children.Add(new Category { Name = "Child 2" });
children.Add(new Category { Name = "Child 3" });
children.Add(new Category { Name = "Child 4" });
list.Add(new Category { Name = "Test1", Children=children });
return list;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
int itemsCount = MainNavigation.MenuItems.Count();
Debug.WriteLine(itemsCount);
}
}
Category.cs
public class Category
{
public string Name { get; set; }
public ObservableCollection<Category> Children { get; set; }
}
Edit: it seems like this is a known bug, I found a closed issue on GitHub but the problem persists.
UWP: NavigationView.MenuItems results empty if populated programmatically
I can reproduce your problem that MenuItems.Count is zero. As your provide link said, you could also get the items with MenuItemsSource
property.
The parameter of Collapse
method is NavigationViewItem
, and we could not pass MenuItems element (data source type) into it directly. We need use the data source to find the matched NavigationViewItem
, the ContainerFromMenuItem
method is right choice for getting NavigationViewItem with data source. And then MenuItems
is not necessary for this scenario. Because categories
has been decaled previously. we could use it directly. So the code could be written like below.
private void Button_Click(object sender, RoutedEventArgs e)
{
var container = MainNavigation.ContainerFromMenuItem(categories.First()) as Microsoft.UI.Xaml.Controls.NavigationViewItem;
MainNavigation.Collapse(container);
}