NavigationViewMenu 不考虑其 MenuItemsSource

NavigationViewMenu not considering its MenuItemsSource

示例: link

我正在开发一个应用程序,允许人们保存笔记,并创建可以存储笔记的类别。

类别列在列表和 ObservableCollection 中,因为我在尝试序列化 NavigationViewItems 列表时遇到了问题。 所以我做了以下 class:

[DataContract]
class Category
{
    [DataMember]
    public String Title { get; set; }

    [DataMember]
    public int IconIndex { get; set; }

    [DataMember]
    public String Id { get; set; }
}

在我的 App.xaml.cs 中我有:

internal static ObservableCollection<NavigationViewItem> Categories = new ObservableCollection<NavigationViewItem>();
internal static List<Category> CategoriesItems = new List<Category>();

类别(ObservableCollection)用作我的 NavigationView 的 MenuItemsSource :

nav.MenuItemsSource = App.Categories;

在另一个文件中,我有一个名为 OpenCategories 的函数,在应用程序打开时调用:

public async static void OpenCategories(StorageFile file)
{
    MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(await FileIO.ReadTextAsync(file)));
    DataContractJsonSerializer ser = new DataContractJsonSerializer(App.CategoriesItems.GetType());
    App.CategoriesItems = ser.ReadObject(ms) as List<Category>;
    ms.Close();

    UIServices.RefreshCategoriesUI();
}

这里是 UIServices.RefreshCategoriesUI() :

public static void RefreshCategoriesUI()
{
    App.Categories = new System.Collections.ObjectModel.ObservableCollection<NavigationViewItem>();
    foreach(Category cat in App.CategoriesItems)
    {
        App.Categories.Add(new NavigationViewItem
        {
            Content = cat.Title,
            Icon = new SymbolIcon((Symbol)Enum.GetValues(typeof(Symbol)).GetValue(cat.IconIndex))
        });
    }
}

=> 我的问题是,即使 App.Categories 包含 NavigationViewItems,我的 NavigationViewMenu 始终为空。为什么不更新了?

编辑: 这是我所做的更改。

Categories 已从 App.xaml.cs 移动到 MainPage.xaml 并已转换为 DependencyProperty

internal DependencyProperty CategoriesProperty = DependencyProperty.Register("CategoriesProperty", typeof(ObservableCollection<NavigationViewItem>), typeof(App), new PropertyMetadata(default(ObservableCollection<NavigationViewItem>)));

RefreshCategoriesUI 不再使用。相反,我将 CategoriesItems 变成了 ObservableCollection 属性 并订阅了 CollectionChanged 事件:

private void CategoriesItems_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
    var page = (MainPage)((Frame)Window.Current.Content).Content;
    page.Categories = new ObservableCollection<NavigationViewItem>();
    foreach (Category cat in CategoriesItems)
        page.Categories.Add(new NavigationViewItem
        {
            Content = cat.Title,
            Icon = new SymbolIcon((Symbol)Enum.GetValues(typeof(Symbol)).GetValue(cat.IconIndex))
        });
}

最后 OpenCategories 现在以这种方式工作:

public async static void OpenCategories(StorageFile file)
{
    MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(await FileIO.ReadTextAsync(file)));
    DataContractJsonSerializer ser = new DataContractJsonSerializer(App.CategoriesItems.GetType());
    ObservableCollection<Category> categories = ser.ReadObject(ms) as ObservableCollection<Category>;
    foreach (Category cat in categories)
        App.CategoriesItems.Add(cat);
    ms.Close();
}

哦,这似乎很明显,但随着类别的移动,我将 NavigationView 的 MenuItemSource 从 App.Categories 更改为类别。

还是不行。当我在运行时检查时,类别包含我通过我的应用程序创建的所有类别。

此外,这真的很奇怪,因为当我第一次检查 Categories 是否包含某些内容时(写这个 post),在我的断点之后,所有类别都像它应该每次都在 NavigationView 中弹出,但是当我再次尝试时,它没有用。

对于您的示例,在 App.xaml.cs 文件 CategoriesItems_CollectionChanged 方法中,每次触发 CollectionChanged 事件时,您都会创建一个新的 ObservableCollection<NavigationViewItem> 对象,然后将项目添加到其中,但您还应该再次将 NavigationView.MenuItemsSource 设置为 ObservableCollection

您可以尝试改变您的CategoriesItems_CollectionChanged方法,如下所示。

private void CategoriesItems_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
    // Gets the MainPage
    var page = (MainPage)((Frame)Window.Current.Content).Content;
    page.Categories = new ObservableCollection<NavigationViewItem>();

    // Creates all the NavigationViewItems, based on CategoriesItems
    foreach (Category cat in CategoriesItems)
        page.Categories.Add(new NavigationViewItem
        {
            Content = cat.Title,
            Icon = new SymbolIcon((Symbol)Enum.GetValues(typeof(Symbol)).GetValue(cat.IconIndex))
        });

    //Here is the code to set the NavigationView's MenuItemsSource.

    NavigationView nav= (NavigationView)page.FindName("nav");
    nav.MenuItemsSource = page.Categories;
}