Skip to content

Commit

Permalink
Merge pull request PrismLibrary#611 from PrismLibrary/v6.2-Preview
Browse files Browse the repository at this point in the history
improved async/await logic to fix PrismLibrary#609
  • Loading branch information
brianlagunas committed Jun 1, 2016
2 parents 7173757 + 9adb3f8 commit 35dddb3
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 42 deletions.
18 changes: 14 additions & 4 deletions Sandbox/Xamarin/HelloWorld/ModuleA/ViewModels/ViewAViewModel.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Prism.Commands;
using System;
using Prism.Commands;
using Prism.Mvvm;
using Prism.Navigation;

Expand All @@ -15,18 +16,27 @@ public string Title
set { SetProperty(ref _title, value); }
}

private bool _canNavigate = true;
public bool CanNavigate
{
get { return _canNavigate; }
set { SetProperty(ref _canNavigate, value); }
}

public DelegateCommand NavigateCommand { get; set; }

public ViewAViewModel(INavigationService navigationService)
{
_navigationService = navigationService;

NavigateCommand = new DelegateCommand(Navigate);
NavigateCommand = new DelegateCommand(Navigate).ObservesCanExecute((vm) => CanNavigate);
}

void Navigate()
async void Navigate()
{
_navigationService.NavigateAsync("ViewB");
CanNavigate = false;
await _navigationService.NavigateAsync("ViewB");
CanNavigate = true;
}

public void OnNavigatedFrom(NavigationParameters parameters)
Expand Down
16 changes: 12 additions & 4 deletions Sandbox/Xamarin/HelloWorld/ModuleA/ViewModels/ViewBViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,26 @@ public string Title
set { SetProperty(ref _title, value); }
}

private bool _canNavigate = true;
public bool CanNavigate
{
get { return _canNavigate; }
set { SetProperty(ref _canNavigate, value); }
}

public DelegateCommand NavigateCommand { get; set; }

public ViewBViewModel(INavigationService navigationService)
{
_navigationService = navigationService;

NavigateCommand = new DelegateCommand(Navigate);
NavigateCommand = new DelegateCommand(Navigate).ObservesCanExecute((vm) => CanNavigate);
}

void Navigate()
async void Navigate()
{
_navigationService.GoBackAsync();
CanNavigate = false;
await _navigationService.GoBackAsync();
CanNavigate = true;
}

public void OnNavigatedFrom(NavigationParameters parameters)
Expand Down
53 changes: 19 additions & 34 deletions Source/Xamarin/Prism.Forms/Navigation/PageNavigationService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,10 @@ public virtual async Task<bool> GoBackAsync(NavigationParameters parameters = nu
/// <param name="parameters">The navigation parameters</param>
/// <param name="useModalNavigation">If <c>true</c> uses PopModalAsync, if <c>false</c> uses PopAsync</param>
/// <param name="animated">If <c>true</c> the transition is animated, if <c>false</c> there is no animation on transition.</param>
public virtual async Task NavigateAsync<TViewModel>(NavigationParameters parameters = null, bool? useModalNavigation = null, bool animated = true)
public virtual Task NavigateAsync<TViewModel>(NavigationParameters parameters = null, bool? useModalNavigation = null, bool animated = true)
where TViewModel : BindableBase
{
await NavigateAsync(typeof(TViewModel).FullName, parameters, useModalNavigation, animated);
return NavigateAsync(typeof(TViewModel).FullName, parameters, useModalNavigation, animated);
}

/// <summary>
Expand All @@ -88,9 +88,9 @@ public virtual async Task NavigateAsync<TViewModel>(NavigationParameters paramet
/// <param name="parameters">The navigation parameters</param>
/// <param name="useModalNavigation">If <c>true</c> uses PopModalAsync, if <c>false</c> uses PopAsync</param>
/// <param name="animated">If <c>true</c> the transition is animated, if <c>false</c> there is no animation on transition.</param>
public virtual async Task NavigateAsync(string name, NavigationParameters parameters = null, bool? useModalNavigation = null, bool animated = true)
public virtual Task NavigateAsync(string name, NavigationParameters parameters = null, bool? useModalNavigation = null, bool animated = true)
{
await NavigateAsync(new Uri(name, UriKind.RelativeOrAbsolute), parameters, useModalNavigation, animated);
return NavigateAsync(new Uri(name, UriKind.RelativeOrAbsolute), parameters, useModalNavigation, animated);
}

/// <summary>
Expand All @@ -104,14 +104,14 @@ public virtual async Task NavigateAsync(string name, NavigationParameters parame
/// <example>
/// Navigate(new Uri("MainPage?id=3&name=brian", UriKind.RelativeSource), parameters);
/// </example>
public virtual async Task NavigateAsync(Uri uri, NavigationParameters parameters = null, bool? useModalNavigation = null, bool animated = true)
public virtual Task NavigateAsync(Uri uri, NavigationParameters parameters = null, bool? useModalNavigation = null, bool animated = true)
{
var navigationSegments = UriParsingHelper.GetUriSegments(uri);

if (uri.IsAbsoluteUri)
await ProcessNavigationForAbsoulteUri(navigationSegments, parameters, useModalNavigation, animated);
return ProcessNavigationForAbsoulteUri(navigationSegments, parameters, useModalNavigation, animated);
else
await ProcessNavigation(GetCurrentPage(), navigationSegments, parameters, useModalNavigation, animated);
return ProcessNavigation(GetCurrentPage(), navigationSegments, parameters, useModalNavigation, animated);
}

async Task ProcessNavigation(Page currentPage, Queue<string> segments, NavigationParameters parameters, bool? useModalNavigation, bool animated)
Expand Down Expand Up @@ -227,7 +227,7 @@ async Task ProcessNavigationForTabbedPage(TabbedPage currentPage, string nextSeg
continue;

await ProcessNavigation(child, segments, parameters, useModalNavigation, animated);
await DoNavigateAction(null, nextSegment, child, parameters, () =>
await DoNavigateAction(null, nextSegment, child, parameters, onNavigationActionCompleted: () =>
{
currentPage.CurrentPage = child;
});
Expand All @@ -251,7 +251,7 @@ async Task ProcessNavigationForCarouselPage(CarouselPage currentPage, string nex
continue;

await ProcessNavigation(child, segments, parameters, useModalNavigation, animated);
await DoNavigateAction(null, nextSegment, child, parameters, () =>
await DoNavigateAction(null, nextSegment, child, parameters, onNavigationActionCompleted: () =>
{
currentPage.CurrentPage = child;
});
Expand Down Expand Up @@ -287,10 +287,10 @@ await DoNavigateAction(currentPage, nextSegment, nextPage, parameters, async ()
{
var newDetail = CreatePageFromSegment(nextSegment);
await ProcessNavigation(newDetail, segments, parameters, newDetail is NavigationPage ? false : true, animated);
await DoNavigateAction(null, nextSegment, newDetail, parameters, () =>
await DoNavigateAction(null, nextSegment, newDetail, parameters, onNavigationActionCompleted: () =>
{
currentPage.Detail = newDetail;
currentPage.IsPresented = isPresented;
currentPage.Detail = newDetail;
});
return;
}
Expand All @@ -299,7 +299,7 @@ await DoNavigateAction(null, nextSegment, newDetail, parameters, () =>
if (detail.GetType() == nextSegmentType)
{
await ProcessNavigation(detail, segments, parameters, useModalNavigation, animated);
await DoNavigateAction(null, nextSegment, detail, parameters, () =>
await DoNavigateAction(null, nextSegment, detail, parameters, onNavigationActionCompleted:() =>
{
currentPage.IsPresented = isPresented;
});
Expand All @@ -309,10 +309,10 @@ await DoNavigateAction(null, nextSegment, detail, parameters, () =>
{
var newDetail = CreatePageFromSegment(nextSegment);
await ProcessNavigation(newDetail, segments, parameters, newDetail is NavigationPage ? false : true, animated);
await DoNavigateAction(detail, nextSegment, newDetail, parameters, () =>
await DoNavigateAction(detail, nextSegment, newDetail, parameters, onNavigationActionCompleted: () =>
{
currentPage.Detail = newDetail;
currentPage.IsPresented = isPresented;
currentPage.Detail = newDetail;
});
return;
}
Expand All @@ -331,7 +331,7 @@ bool GetMasterDetailPageIsPresented(MasterDetailPage page)
return false;
}

static async Task DoNavigateAction(Page fromPage, string toSegment, Page toPage, NavigationParameters parameters, Action navigationAction = null)
static async Task DoNavigateAction(Page fromPage, string toSegment, Page toPage, NavigationParameters parameters, Func<Task> navigationAction = null, Action onNavigationActionCompleted = null)
{
var segmentPrameters = GetSegmentParameters(toSegment, parameters);

Expand All @@ -342,7 +342,9 @@ static async Task DoNavigateAction(Page fromPage, string toSegment, Page toPage,
OnNavigatedFrom(fromPage, segmentPrameters);

if (navigationAction != null)
navigationAction();
await navigationAction();

onNavigationActionCompleted?.Invoke();

OnNavigatedTo(toPage, segmentPrameters);
}
Expand Down Expand Up @@ -510,27 +512,10 @@ static void OnNavigatedFrom(object page, NavigationParameters parameters)
InvokeOnNavigationAwareElement(page, v => v.OnNavigatedFrom(parameters));
}

static void OnNavigatedTo(object page, NavigationParameters parameters, bool includeChild = false)
static void OnNavigatedTo(object page, NavigationParameters parameters)
{
if (page != null)
InvokeOnNavigationAwareElement(page, v => v.OnNavigatedTo(parameters));

if (includeChild)
{
Page childPage = null;

if (page is NavigationPage)
childPage = ((NavigationPage)page).CurrentPage;
else if (page is TabbedPage)
childPage = ((TabbedPage)page).CurrentPage;
if (page is CarouselPage)
childPage = ((CarouselPage)page).CurrentPage;
else if (page is MasterDetailPage)
childPage = ((MasterDetailPage)page).Detail;

if (childPage != null)
InvokeOnNavigationAwareElement(childPage, c => c.OnNavigatedTo(parameters));
}
}

static void InvokeOnNavigationAwareElement(object item, Action<INavigationAware> invocation)
Expand Down

0 comments on commit 35dddb3

Please sign in to comment.