I'm developing a Windows Phone Universal App using MVVM Light (I'm new to MVVM pattern). My problem is to make it work like that:
- Application is launched (or the user navigates to different view),
- then we see the basic UI,
- and then we wait for the data to be loaded, while the application stays responsive.
So far I have tested many different approaches like:
- implementing
NotifyTaskCompletion<T>
- implementing async command
- call an async void from viewmodel constructor
- loading data in command called by "page loaded" event
and in each case my application was showing splash screen (or was blocking before navigating to another page) unless the data was loaded. The methods return data properly, views display it well.
So my question is, what is the proper way to load data asynchronously in Universal App? I will be grateful for your help.
This is how my code looks like for now:
MainViewModel.cs
public MainViewModel()
{
this._navigationService = ServiceLocator.Current.GetInstance<INavigationService>();
_newsService = ServiceLocator.Current.GetInstance<INewsService>();
LoadMainPageCommand =
new RelayCommand(async() => await LoadMainPageData());
}
public RelayCommand LoadMainPageCommand { get; set; }
private async Task LoadMainPageData()
{
// to make it work a bit longer
for (int i = Int32.MaxValue; i > 20000; i--) ;
NewsCategories= await _newsService.GetNewsCategoriesAsync();
RaisePropertyChanged("NewsCategories");
}
HubPage.xaml
<Page
x:Class="xxx.HubPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:xxx"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:i="using:Microsoft.Xaml.Interactivity"
xmlns:core="using:Microsoft.Xaml.Interactions.Core"
xmlns:data="using:xxx.Data"
mc:Ignorable="d">
<i:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="Loaded">
<core:InvokeCommandAction Command="{Binding LoadMainPageCommand}"/>
</core:EventTriggerBehavior>
</i:Interaction.Behaviors>
...
INewsService.cs
public interface INewsService
{
Task<ObservableCollection<NewsCategory>> GetNewsCategoriesAsync();
}