问题
My setup is basically as follows:
NavigationView
'sMenuItemsSource
is bound toviewModel.NavItems
.NavItems
is a computed property ofviewModel
.
The view model class implements
INotifyPropertyChanged
for binding purposeBooks
of view model is loaded asynchronously.
What works
The NavigationViewItem
s show up after the page is reached.
The Problem
I need to set a specified NavigationViewItem
as the SelectedItem of the NavigationView
. But there's no NavigationViewItem
(from viewModel
) to use inside OnNavigatedTo(NavigationEventArgs e), because at that point viewModel.NavItems
is not ready yet.
So is there a pattern for selecting a NavigationViewItem
in this async situation?
XAML
<NavigationView x:Name="navView"
MenuItemsSource="{x:Bind viewModel.NavItems, Mode=OneWay}"
SelectionChanged="NavView_SelectionChanged" >
…
the view model
internal class MainPageViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
// The data service
private MainDataService mainDataService = new MainDataService();
private List<Book> books = new List<Book>();
public List<Book> Books
{
get
{
return this.books;
}
set
{
this.books = value;
this.OnPropertyChanged();
this.OnPropertyChanged("NavItems");
}
}
public IEnumerable<NavigationViewItemBase> NavItems
{
get
{
return Books.SelectMany(
b => (new List<NavigationViewItemBase> { new NavigationViewItemHeader {
Content = b.Title,
Tag = b.Title
} })
.Concat(
b.Sections.Select(s => new NavigationViewItem
{
Content = s.Title,
Icon = new FontIcon { Glyph = "\uE8B7", FontFamily = new FontFamily("Segoe MDL2 Assets") }
})
)
);
}
}
// @param selectedBookIndex: the index of the book whose first section
// should be selected.
public async Task UpdateBooks(int selectedBookIndex)
{
await mainDataService.PrepareData();
this.Books = mainDataService.Books;
}
…
}
回答1:
So is there a pattern for selecting a NavigationViewItem in this async situation?
For async situation, you need use ObservableCollection but not List
. And it represents a dynamic data collection that provides notifications when items get added, removed, or when the whole list is refreshed.
But there's no NavigationViewItem (from viewModel) to use inside OnNavigatedTo(NavigationEventArgs e), because at that point viewModel.NavItems is not ready yet.
Before the data is not ready, you could keep the Frame
navigation to the default page that used as placehoder within NavigationView
Loaded event.
For more you could refer Data binding in depth.
来源:https://stackoverflow.com/questions/51020208/how-to-programmatically-select-a-bound-navigationviewitem-of-navigationview