0

Sample : link

I'm developing an application that allows people to save notes, and create categories in which you can store your notes.

Categories are listed in a List, and an ObservableCollection, because I had a problem, trying to serialize a List of NavigationViewItems. So I made the following class:

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

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

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

And in my App.xaml.cs I have:

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

Categories (the ObservableCollection) is used as my NavigationView's MenuItemsSource :

nav.MenuItemsSource = App.Categories;

In an other file, I have a function called OpenCategories, called at the opening of the application:

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();
}

And here's 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))
        });
    }
}

=> My issue is that even though App.Categories contains NavigationViewItems, my NavigationViewMenu is always empty. Why isn't it updating ?

Edit : Here are the changes I made.

Categories has been moved from App.xaml.cs to MainPage.xaml and has been transformed into a DependencyProperty

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

RefreshCategoriesUI is not used anymore. Instead, I turned CategoriesItems into a ObservableCollection property and subscribed to the CollectionChanged event:

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))
        });
}

And finally OpenCategories is now working this way:

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();
}

Oh and it seems obvious but I changed the MenuItemSource of my NavigationView from App.Categories to Categories, as Categories moved.

It's still not working. And when I check during runtime, Categories contains all the categories I created through my app.

Moreover, it's really weird because when I first checked if Categories contained something (to write this post), after my breakpoint, all the categories popped up in the NavigationView as it's supposed to do everytime, but when I tried again it didn't work.

4

1 回答 1

0

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

您可以尝试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;
}
于 2018-01-08T14:23:31.023 回答