Skip to content

Commit

Permalink
Merge pull request #1829 from PrismLibrary/modal
Browse files Browse the repository at this point in the history
Enhanced Modal Logic & Exception Handling
  • Loading branch information
dansiegel committed Jun 9, 2019
2 parents b885ff5 + 2cfed95 commit 941897f
Show file tree
Hide file tree
Showing 15 changed files with 320 additions and 160 deletions.
Expand Up @@ -39,13 +39,9 @@ public App()
/// <param name="e">Details about the launch request and process.</param>
protected override void OnLaunched(LaunchActivatedEventArgs e)
{


Frame rootFrame = Window.Current.Content as Frame;

// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (rootFrame == null)
if (!(Window.Current.Content is Frame rootFrame))
{
// Create a Frame to act as the navigation context and navigate to the first page
rootFrame = new Frame();
Expand Down
Expand Up @@ -27,14 +27,5 @@
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Update="Views\DemoDialog.xaml">
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Views\DialogDemoPage.xaml">
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Views\UserAlert.xaml">
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
</ItemGroup>
</Project>
Expand Up @@ -29,7 +29,6 @@ public string Message
set => SetProperty(ref _message, value);
}


public bool CanNavigate
{
get { return _canNavigate; }
Expand Down
8 changes: 7 additions & 1 deletion Sandbox/Xamarin/HelloWorld/ModuleA/Views/ViewA.xaml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
xmlns:prism="http://prismlibrary.com"
prism:ViewModelLocator.AutowireViewModel="True"
x:Class="ModuleA.Views.ViewA"
Padding="{OnPlatform iOS='0,20,0,0'}"
Expand All @@ -23,6 +23,12 @@
<Label Text="{Binding Message}" />
<Label Text="{Binding IsActive, StringFormat='IsActive: {0}'}" />
<Button Command="{Binding NavigateCommand}" Text="Navigate" />
<Button Text="View B"
Command="{prism:NavigateTo ViewB}" />
<Button Text="Select Tab C"
Command="{prism:SelectTab ViewC}" />
<Button Text="Go Back"
Command="{prism:GoBack}" />
</StackLayout>

</ContentPage>
14 changes: 8 additions & 6 deletions Sandbox/Xamarin/HelloWorld/ModuleA/Views/ViewB.xaml
Expand Up @@ -2,22 +2,24 @@
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:ModuleA.Views"
xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
xmlns:prism="http://prismlibrary.com"
prism:ViewModelLocator.AutowireViewModel="True"
x:Class="ModuleA.Views.ViewB"
x:Name="viewB"
Padding="{OnPlatform iOS='0,20,0,0'}"
Title="View B">
<ContentPage.Padding>
<OnPlatform x:TypeArguments="Thickness">
<On Platform="iOS" Value="0,20,0,0" />
</OnPlatform>
</ContentPage.Padding>

<!--<local:PartialViewB prism:ViewModelLocator.AutowirePartialView="{x:Reference viewB}" />-->
<StackLayout>
<Label Text="{Binding Title}" VerticalOptions="Center" HorizontalOptions="Center" />
<Label Text="{Binding IsActive}" />
<Button Command="{Binding NavigateCommand}" Text="Navigate" />
<Button Text="View C"
Command="{prism:NavigateTo ViewC}" />
<Button Text="Select Tab C"
Command="{prism:SelectTab ViewC}" />
<Button Text="Go Back"
Command="{prism:GoBack}" />
</StackLayout>

</ContentPage>
20 changes: 11 additions & 9 deletions Sandbox/Xamarin/HelloWorld/ModuleA/Views/ViewC.xaml
@@ -1,17 +1,19 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
xmlns:prism="http://prismlibrary.com"
prism:ViewModelLocator.AutowireViewModel="True"
x:Class="ModuleA.Views.ViewC"
Padding="{OnPlatform iOS='0,20,0,0'}"
Title="View C">
<ContentPage.Padding>
<OnPlatform x:TypeArguments="Thickness">
<On Platform="iOS" Value="0,20,0,0" />
</OnPlatform>
</ContentPage.Padding>
<StackLayout>
<StackLayout>
<Label Text="{Binding Title}" VerticalOptions="Center" HorizontalOptions="Center" />
<Button Command="{Binding NavigateCommand}" Text="Navigate" />
</StackLayout>
<Button Command="{Binding NavigateCommand}" Text="Navigate" />
<Button Text="View B"
Command="{prism:NavigateTo ViewB}" />
<Button Text="Select Tab A"
Command="{prism:SelectTab ViewA}" />
<Button Text="Go Back"
Command="{prism:GoBack}" />
</StackLayout>
</ContentPage>
17 changes: 15 additions & 2 deletions Source/Prism/Common/ParametersBase.cs
Expand Up @@ -58,8 +58,21 @@ protected ParametersBase(string query)
}
}

public object this[string key] =>
_entries.FirstOrDefault(x => string.Compare(x.Key, key, StringComparison.Ordinal) == 0);
public object this[string key]
{
get
{
foreach(var entry in _entries)
{
if(string.Compare(entry.Key, key, StringComparison.Ordinal) == 0)
{
return entry.Value;
}
}

return null;
}
}

public int Count => _entries.Count;

Expand Down
Expand Up @@ -132,16 +132,14 @@ public async Task Navigate_UnregisteredView_ThrowException()

Assert.False(result.Success);
Assert.NotNull(result.Exception);
#if Autofac
Assert.IsType<ComponentNotRegisteredException>(result.Exception);
#elif DryIoc
Assert.IsType<ContainerException>(result.Exception);
#elif Ninject
Assert.IsType<ActivationException>(result.Exception);
Assert.IsType<NavigationException>(result.Exception);
Assert.Equal(NavigationException.NoPageIsRegistered, result.Exception.Message);
#if DryIoc
Assert.IsType<ContainerException>(result.Exception.InnerException);
#elif Unity
Assert.IsType<NullReferenceException>(result.Exception);
Assert.IsType<NullReferenceException>(result.Exception.InnerException);
#endif
Assert.Contains("missing", result.Exception.ToString(), StringComparison.OrdinalIgnoreCase);
Assert.Contains("missing", result.Exception.InnerException.ToString(), StringComparison.OrdinalIgnoreCase);
}

[Theory]
Expand Down
14 changes: 10 additions & 4 deletions Source/Xamarin/Prism.Forms/Common/PageUtilities.cs
Expand Up @@ -293,20 +293,26 @@ internal static bool HasDirectNavigationPageParent(Page page)
return page?.Parent != null && page?.Parent is NavigationPage;
}

internal static bool HasNavigationPageParent(Page page)
internal static bool HasNavigationPageParent(Page page) =>
HasNavigationPageParent(page, out var _);

internal static bool HasNavigationPageParent(Page page, out NavigationPage navigationPage)
{
if (page?.Parent != null)
{
if (page.Parent is NavigationPage)
if (page.Parent is NavigationPage navParent)
{
navigationPage = navParent;
return true;
}
else if (page.Parent is TabbedPage || page.Parent is CarouselPage)
else if ((page.Parent is TabbedPage || page.Parent is CarouselPage) && page.Parent?.Parent is NavigationPage navigationParent)
{
return page.Parent.Parent != null && page.Parent.Parent is NavigationPage;
navigationPage = navigationParent;
return true;
}
}

navigationPage = null;
return false;
}

Expand Down
32 changes: 32 additions & 0 deletions Source/Xamarin/Prism.Forms/Navigation/NavigationException.cs
@@ -0,0 +1,32 @@
using System;
using Xamarin.Forms;

namespace Prism.Navigation
{
public class NavigationException : Exception
{
public const string CannotPopApplicationMainPage = "Cannot Pop Application MainPage";
public const string CannotGoBackFromRoot = "Cannot GoBack from NavigationPage Root.";
public const string GoBackToRootRequiresNavigationPage = "GoBackToRootAsync can only be called when the calling Page is within a NavigationPage.";
public const string RelativeNavigationRequiresNavigationPage = "Removing views using the relative '../' syntax while navigating is only supported within a NavigationPage";
public const string IConfirmNavigationReturnedFalse = "IConfirmNavigation returned false";
public const string NoPageIsRegistered = "No Page has been registered with the provided key";
public const string ErrorCreatingPage = "An error occurred while resolving the page. This is most likely the result of invalid XAML or other type initialization exception";
public const string UnknownException = "An unknown error occurred. You may need to specify whether to Use Modal Navigation or not.";

public NavigationException()
{
}

public NavigationException(string message, Page page) : this(message, page, null)
{
}

public NavigationException(string message, Page page, Exception innerException) : base(message, innerException)
{
Page = page;
}

public Page Page { get; }
}
}

0 comments on commit 941897f

Please sign in to comment.