├── .gitignore ├── LICENSE ├── NuGet └── Xamarin.Forms.NavigationExtensions.nuspec ├── README.md ├── Sources ├── NavigationExtensions.sln ├── NavigationExtensions │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Xamarin.Forms.NavigationExtensions.Portable.csproj │ └── packages.config ├── Samples │ ├── Droid │ │ ├── Assets │ │ │ └── AboutAssets.txt │ │ ├── MainActivity.cs │ │ ├── Properties │ │ │ ├── AndroidManifest.xml │ │ │ └── AssemblyInfo.cs │ │ ├── Resources │ │ │ ├── AboutResources.txt │ │ │ ├── Resource.designer.cs │ │ │ ├── drawable-hdpi │ │ │ │ └── icon.png │ │ │ ├── drawable-xhdpi │ │ │ │ └── icon.png │ │ │ ├── drawable-xxhdpi │ │ │ │ └── icon.png │ │ │ ├── drawable │ │ │ │ └── icon.png │ │ │ ├── layout │ │ │ │ ├── Tabbar.axml │ │ │ │ └── Toolbar.axml │ │ │ └── values │ │ │ │ └── styles.xml │ │ ├── Sample.Droid.csproj │ │ └── packages.config │ ├── Sample │ │ ├── App.cs │ │ ├── Model │ │ │ ├── Entities │ │ │ │ ├── Album.cs │ │ │ │ ├── Photo.cs │ │ │ │ └── User.cs │ │ │ ├── IService.cs │ │ │ ├── Locator.cs │ │ │ └── WebService.cs │ │ ├── Properties │ │ │ └── AssemblyInfo.cs │ │ ├── Sample.csproj │ │ ├── ViewModels │ │ │ ├── AlbumViewModel.cs │ │ │ ├── AlbumsViewModel.cs │ │ │ ├── PhotoViewModel.cs │ │ │ ├── UserViewModel.cs │ │ │ └── UsersViewModel.cs │ │ ├── Views │ │ │ ├── AlbumPage.xaml │ │ │ ├── AlbumPage.xaml.cs │ │ │ ├── AlbumsPage.xaml │ │ │ ├── AlbumsPage.xaml.cs │ │ │ ├── PhotoPage.xaml │ │ │ ├── PhotoPage.xaml.cs │ │ │ ├── UserPage.xaml │ │ │ ├── UserPage.xaml.cs │ │ │ ├── UsersPage.xaml │ │ │ └── UsersPage.xaml.cs │ │ └── packages.config │ ├── Samples.sln │ └── iOS │ │ ├── AppDelegate.cs │ │ ├── Assets.xcassets │ │ ├── AppIcons.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ │ ├── Entitlements.plist │ │ ├── Info.plist │ │ ├── LaunchScreen.storyboard │ │ ├── Main.cs │ │ ├── Sample.iOS.csproj │ │ └── packages.config ├── Xamarin.Forms.NavigationExtensions.Shared │ ├── NavigationExtensions.cs │ ├── NavigationState.cs │ ├── PageState.cs │ ├── Xamarin.Forms.NavigationExtensions.Shared.projitems │ ├── Xamarin.Forms.NavigationExtensions.Shared.shproj │ └── packages.config └── Xamarin.Forms.NavigationExtensions.Standard │ └── Xamarin.Forms.NavigationExtensions.Standard.csproj └── icon.png /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | bld/ 21 | [Bb]in/ 22 | [Oo]bj/ 23 | 24 | # Visual Studio 2015 cache/options directory 25 | .vs/ 26 | # Uncomment if you have tasks that create the project's static files in wwwroot 27 | #wwwroot/ 28 | 29 | # MSTest test Results 30 | [Tt]est[Rr]esult*/ 31 | [Bb]uild[Ll]og.* 32 | 33 | # NUNIT 34 | *.VisualState.xml 35 | TestResult.xml 36 | 37 | # Build Results of an ATL Project 38 | [Dd]ebugPS/ 39 | [Rr]eleasePS/ 40 | dlldata.c 41 | 42 | # DNX 43 | project.lock.json 44 | artifacts/ 45 | 46 | *_i.c 47 | *_p.c 48 | *_i.h 49 | *.ilk 50 | *.meta 51 | *.obj 52 | *.pch 53 | *.pdb 54 | *.pgc 55 | *.pgd 56 | *.rsp 57 | *.sbr 58 | *.tlb 59 | *.tli 60 | *.tlh 61 | *.tmp 62 | *.tmp_proj 63 | *.log 64 | *.vspscc 65 | *.vssscc 66 | .builds 67 | *.pidb 68 | *.svclog 69 | *.scc 70 | 71 | # Chutzpah Test files 72 | _Chutzpah* 73 | 74 | # Visual C++ cache files 75 | ipch/ 76 | *.aps 77 | *.ncb 78 | *.opendb 79 | *.opensdf 80 | *.sdf 81 | *.cachefile 82 | 83 | # Visual Studio profiler 84 | *.psess 85 | *.vsp 86 | *.vspx 87 | *.sap 88 | 89 | # TFS 2012 Local Workspace 90 | $tf/ 91 | 92 | # Guidance Automation Toolkit 93 | *.gpState 94 | 95 | # ReSharper is a .NET coding add-in 96 | _ReSharper*/ 97 | *.[Rr]e[Ss]harper 98 | *.DotSettings.user 99 | 100 | # JustCode is a .NET coding add-in 101 | .JustCode 102 | 103 | # TeamCity is a build add-in 104 | _TeamCity* 105 | 106 | # DotCover is a Code Coverage Tool 107 | *.dotCover 108 | 109 | # NCrunch 110 | _NCrunch_* 111 | .*crunch*.local.xml 112 | nCrunchTemp_* 113 | 114 | # MightyMoose 115 | *.mm.* 116 | AutoTest.Net/ 117 | 118 | # Web workbench (sass) 119 | .sass-cache/ 120 | 121 | # Installshield output folder 122 | [Ee]xpress/ 123 | 124 | # DocProject is a documentation generator add-in 125 | DocProject/buildhelp/ 126 | DocProject/Help/*.HxT 127 | DocProject/Help/*.HxC 128 | DocProject/Help/*.hhc 129 | DocProject/Help/*.hhk 130 | DocProject/Help/*.hhp 131 | DocProject/Help/Html2 132 | DocProject/Help/html 133 | 134 | # Click-Once directory 135 | publish/ 136 | 137 | # Publish Web Output 138 | *.[Pp]ublish.xml 139 | *.azurePubxml 140 | # TODO: Comment the next line if you want to checkin your web deploy settings 141 | # but database connection strings (with potential passwords) will be unencrypted 142 | *.pubxml 143 | *.publishproj 144 | 145 | # NuGet Packages 146 | *.nupkg 147 | # The packages folder can be ignored because of Package Restore 148 | **/packages/* 149 | # except build/, which is used as an MSBuild target. 150 | !**/packages/build/ 151 | # Uncomment if necessary however generally it will be regenerated when needed 152 | #!**/packages/repositories.config 153 | # NuGet v3's project.json files produces more ignoreable files 154 | *.nuget.props 155 | *.nuget.targets 156 | 157 | # Microsoft Azure Build Output 158 | csx/ 159 | *.build.csdef 160 | 161 | # Microsoft Azure Emulator 162 | ecf/ 163 | rcf/ 164 | 165 | # Microsoft Azure ApplicationInsights config file 166 | ApplicationInsights.config 167 | 168 | # Windows Store app package directory 169 | AppPackages/ 170 | BundleArtifacts/ 171 | 172 | # Visual Studio cache files 173 | # files ending in .cache can be ignored 174 | *.[Cc]ache 175 | # but keep track of directories ending in .cache 176 | !*.[Cc]ache/ 177 | 178 | # Others 179 | ClientBin/ 180 | ~$* 181 | *~ 182 | *.dbmdl 183 | *.dbproj.schemaview 184 | *.pfx 185 | *.publishsettings 186 | node_modules/ 187 | orleans.codegen.cs 188 | 189 | # RIA/Silverlight projects 190 | Generated_Code/ 191 | 192 | # Backup & report files from converting an old project file 193 | # to a newer Visual Studio version. Backup files are not needed, 194 | # because we have git ;-) 195 | _UpgradeReport_Files/ 196 | Backup*/ 197 | UpgradeLog*.XML 198 | UpgradeLog*.htm 199 | 200 | # SQL Server files 201 | *.mdf 202 | *.ldf 203 | 204 | # Business Intelligence projects 205 | *.rdl.data 206 | *.bim.layout 207 | *.bim_*.settings 208 | 209 | # Microsoft Fakes 210 | FakesAssemblies/ 211 | 212 | # GhostDoc plugin setting file 213 | *.GhostDoc.xml 214 | 215 | # Node.js Tools for Visual Studio 216 | .ntvs_analysis.dat 217 | 218 | # Visual Studio 6 build log 219 | *.plg 220 | 221 | # Visual Studio 6 workspace options file 222 | *.opt 223 | 224 | # Visual Studio LightSwitch build output 225 | **/*.HTMLClient/GeneratedArtifacts 226 | **/*.DesktopClient/GeneratedArtifacts 227 | **/*.DesktopClient/ModelManifest.xml 228 | **/*.Server/GeneratedArtifacts 229 | **/*.Server/ModelManifest.xml 230 | _Pvt_Extensions 231 | 232 | # Paket dependency manager 233 | .paket/paket.exe 234 | 235 | # FAKE - F# Make 236 | .fake/ 237 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Aloïs Deniel 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /NuGet/Xamarin.Forms.NavigationExtensions.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Xam.Forms.NavigationExtensions 5 | $version$ 6 | Navigation extensions for Xamarin.Forms 7 | Aloïs Deniel 8 | Aloïs Deniel 9 | https://github.com/aloisdeniel/Xamarin.Forms.NavigationExtensions/blob/master/LICENSE 10 | https://github.com/aloisdeniel/Xamarin.Forms.NavigationExtensions 11 | https://raw.githubusercontent.com/aloisdeniel/Xamarin.Forms.NavigationExtensions/master/icon.png 12 | false 13 | Those extensions for Xamarin.Forms basicaly add storage of the navigation history when the application stops. Extensions has been prefered to subclassing for more flexibility. 14 | Those extensions for Xamarin.Forms basicaly add storage of the navigation history when the application stops. Extensions has been prefered to subclassing for more flexibility. 15 | xamarin, pcl, xam.pcl, navigation, winrt, android, xamarin.forms, ios 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Logo](./icon.png) 2 | 3 | # NavigationExtensions for Xamarin.Forms 4 | 5 | Those extensions for **Xamarin.Forms** basicaly add storage of the navigation history when the application stops. Extensions has been prefered to subclassing for more flexibility. 6 | 7 | ## Installation 8 | 9 | The library is available on [NuGet](https://www.nuget.org/packages/Xam.Forms.NavigationExtensions/). 10 | 11 | To install NavigationExtensions, run the following command in the Package Manager Console. 12 | 13 | PM> Install-Package Xam.Forms.NavigationExtensions 14 | 15 | ## Quickstart 16 | 17 | Once you installed the package, extension methods will be automaticaly added to `INavigation` and `Page`. 18 | 19 | To add storage and restoration of navigation stack : 20 | 21 | ```csharp 22 | public class App : Application 23 | { 24 | public App() 25 | { 26 | MainPage = new NavigationPage(new HomePage()); 27 | } 28 | 29 | protected override async void OnStart() 30 | { 31 | // If the app is launched one hour after its last stop, its navigation history 32 | // will be restored. 33 | await this.MainPage.Navigation.RestoreAsync("Main", TimeSpan.FromHours(1)); 34 | } 35 | 36 | protected override void OnSleep() 37 | { 38 | this.MainPage.Navigation.Store("Main"); 39 | } 40 | } 41 | ``` 42 | 43 | To navigate from a page to another by passing arguments : 44 | 45 | ```csharp 46 | this.Navigation.PushAsync(item.Identifier, true); 47 | ``` 48 | 49 | And finaly access navigation argument from your destination page : 50 | 51 | ```csharp 52 | var albumId = (int) this.GetNavigationArgs(); 53 | ``` 54 | 55 | ## Sample 56 | 57 | A complete application sample is available in the source code solution. 58 | 59 | ## Build and publish 60 | 61 | Publishing is done through [Visual Studio Team Services](https://alois-deniel.visualstudio.com/) with a manual trigger. 62 | 63 | ## Roadmap / ideas 64 | 65 | * Add more helpers for selected tab item, scrolling amount, textfield 66 | 67 | ## Copyright and license 68 | 69 | Code and documentation copyright 2016 Aloïs Deniel released under the MIT license. -------------------------------------------------------------------------------- /Sources/NavigationExtensions.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Xamarin.Forms.NavigationExtensions.Portable", "NavigationExtensions\Xamarin.Forms.NavigationExtensions.Portable.csproj", "{F85EB676-1488-41F4-8C09-488621D01A83}" 5 | EndProject 6 | Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Xamarin.Forms.NavigationExtensions.Shared", "Xamarin.Forms.NavigationExtensions.Shared\Xamarin.Forms.NavigationExtensions.Shared.shproj", "{CB546437-26A8-4F76-8607-A55F9A7CE079}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Xamarin.Forms.NavigationExtensions.Standard", "Xamarin.Forms.NavigationExtensions.Standard\Xamarin.Forms.NavigationExtensions.Standard.csproj", "{BC22B2C3-E552-4852-BF07-9CFFC17C852F}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Release|Any CPU = Release|Any CPU 14 | Debug|iPhoneSimulator = Debug|iPhoneSimulator 15 | Release|iPhone = Release|iPhone 16 | Release|iPhoneSimulator = Release|iPhoneSimulator 17 | Debug|iPhone = Debug|iPhone 18 | EndGlobalSection 19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 20 | {F85EB676-1488-41F4-8C09-488621D01A83}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {F85EB676-1488-41F4-8C09-488621D01A83}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {F85EB676-1488-41F4-8C09-488621D01A83}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {F85EB676-1488-41F4-8C09-488621D01A83}.Release|Any CPU.Build.0 = Release|Any CPU 24 | {F85EB676-1488-41F4-8C09-488621D01A83}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU 25 | {F85EB676-1488-41F4-8C09-488621D01A83}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU 26 | {F85EB676-1488-41F4-8C09-488621D01A83}.Release|iPhone.ActiveCfg = Release|Any CPU 27 | {F85EB676-1488-41F4-8C09-488621D01A83}.Release|iPhone.Build.0 = Release|Any CPU 28 | {F85EB676-1488-41F4-8C09-488621D01A83}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU 29 | {F85EB676-1488-41F4-8C09-488621D01A83}.Release|iPhoneSimulator.Build.0 = Release|Any CPU 30 | {F85EB676-1488-41F4-8C09-488621D01A83}.Debug|iPhone.ActiveCfg = Debug|Any CPU 31 | {F85EB676-1488-41F4-8C09-488621D01A83}.Debug|iPhone.Build.0 = Debug|Any CPU 32 | {BC22B2C3-E552-4852-BF07-9CFFC17C852F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 33 | {BC22B2C3-E552-4852-BF07-9CFFC17C852F}.Debug|Any CPU.Build.0 = Debug|Any CPU 34 | {BC22B2C3-E552-4852-BF07-9CFFC17C852F}.Release|Any CPU.ActiveCfg = Release|Any CPU 35 | {BC22B2C3-E552-4852-BF07-9CFFC17C852F}.Release|Any CPU.Build.0 = Release|Any CPU 36 | {BC22B2C3-E552-4852-BF07-9CFFC17C852F}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU 37 | {BC22B2C3-E552-4852-BF07-9CFFC17C852F}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU 38 | {BC22B2C3-E552-4852-BF07-9CFFC17C852F}.Release|iPhone.ActiveCfg = Release|Any CPU 39 | {BC22B2C3-E552-4852-BF07-9CFFC17C852F}.Release|iPhone.Build.0 = Release|Any CPU 40 | {BC22B2C3-E552-4852-BF07-9CFFC17C852F}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU 41 | {BC22B2C3-E552-4852-BF07-9CFFC17C852F}.Release|iPhoneSimulator.Build.0 = Release|Any CPU 42 | {BC22B2C3-E552-4852-BF07-9CFFC17C852F}.Debug|iPhone.ActiveCfg = Debug|Any CPU 43 | {BC22B2C3-E552-4852-BF07-9CFFC17C852F}.Debug|iPhone.Build.0 = Debug|Any CPU 44 | EndGlobalSection 45 | GlobalSection(NestedProjects) = preSolution 46 | EndGlobalSection 47 | EndGlobal 48 | -------------------------------------------------------------------------------- /Sources/NavigationExtensions/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | 4 | // Information about this assembly is defined by the following attributes. 5 | // Change them to the values specific to your project. 6 | 7 | [assembly: AssemblyTitle("Xam.Forms.NavigationExtensions")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("")] 12 | [assembly: AssemblyCopyright("Aloïs Deniel")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". 17 | // The form "{Major}.{Minor}.*" will automatically update the build and revision, 18 | // and "{Major}.{Minor}.{Build}.*" will update just the revision. 19 | 20 | [assembly: AssemblyVersion("1.0.7")] 21 | 22 | // The following attributes are used to specify the signing key for the assembly, 23 | // if desired. See the Mono documentation for more information about signing. 24 | 25 | //[assembly: AssemblyDelaySign(false)] 26 | //[assembly: AssemblyKeyFile("")] 27 | 28 | -------------------------------------------------------------------------------- /Sources/NavigationExtensions/Xamarin.Forms.NavigationExtensions.Portable.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | {F85EB676-1488-41F4-8C09-488621D01A83} 7 | {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 8 | Library 9 | Xamarin.Forms.NavigationExtensions 10 | Xam.Forms.NavigationExtensions 11 | v4.5 12 | Profile78 13 | 14 | 15 | true 16 | full 17 | false 18 | bin\Debug 19 | DEBUG; 20 | prompt 21 | 4 22 | false 23 | 24 | 25 | true 26 | bin\Release 27 | prompt 28 | 4 29 | false 30 | 31 | 32 | 33 | 34 | 35 | 36 | ..\packages\Xamarin.Forms.2.4.0.282\lib\portable-win+net45+wp80+win81+wpa81\Xamarin.Forms.Core.dll 37 | 38 | 39 | ..\packages\Xamarin.Forms.2.4.0.282\lib\portable-win+net45+wp80+win81+wpa81\Xamarin.Forms.Platform.dll 40 | 41 | 42 | ..\packages\Xamarin.Forms.2.4.0.282\lib\portable-win+net45+wp80+win81+wpa81\Xamarin.Forms.Xaml.dll 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /Sources/NavigationExtensions/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /Sources/Samples/Droid/Assets/AboutAssets.txt: -------------------------------------------------------------------------------- 1 | Any raw assets you want to be deployed with your application can be placed in 2 | this directory (and child directories) and given a Build Action of "AndroidAsset". 3 | 4 | These files will be deployed with your package and will be accessible using Android's 5 | AssetManager, like this: 6 | 7 | public class ReadAsset : Activity 8 | { 9 | protected override void OnCreate (Bundle bundle) 10 | { 11 | base.OnCreate (bundle); 12 | 13 | InputStream input = Assets.Open ("my_asset.txt"); 14 | } 15 | } 16 | 17 | Additionally, some Android functions will automatically load asset files: 18 | 19 | Typeface tf = Typeface.CreateFromAsset (Context.Assets, "fonts/samplefont.ttf"); 20 | -------------------------------------------------------------------------------- /Sources/Samples/Droid/MainActivity.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | using Android.App; 4 | using Android.Content; 5 | using Android.Content.PM; 6 | using Android.Runtime; 7 | using Android.Views; 8 | using Android.Widget; 9 | using Android.OS; 10 | 11 | namespace Sample.Droid 12 | { 13 | [Activity(Label = "Sample.Droid", Icon = "@drawable/icon", Theme = "@style/MyTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)] 14 | public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity 15 | { 16 | protected override void OnCreate(Bundle bundle) 17 | { 18 | TabLayoutResource = Resource.Layout.Tabbar; 19 | ToolbarResource = Resource.Layout.Toolbar; 20 | 21 | base.OnCreate(bundle); 22 | 23 | global::Xamarin.Forms.Forms.Init(this, bundle); 24 | 25 | LoadApplication(new App()); 26 | } 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /Sources/Samples/Droid/Properties/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Sources/Samples/Droid/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using Android.App; 4 | 5 | // Information about this assembly is defined by the following attributes. 6 | // Change them to the values specific to your project. 7 | 8 | [assembly: AssemblyTitle("Sample.Droid")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("")] 13 | [assembly: AssemblyCopyright("alois")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". 18 | // The form "{Major}.{Minor}.*" will automatically update the build and revision, 19 | // and "{Major}.{Minor}.{Build}.*" will update just the revision. 20 | 21 | [assembly: AssemblyVersion("1.0.0")] 22 | 23 | // The following attributes are used to specify the signing key for the assembly, 24 | // if desired. See the Mono documentation for more information about signing. 25 | 26 | //[assembly: AssemblyDelaySign(false)] 27 | //[assembly: AssemblyKeyFile("")] 28 | 29 | -------------------------------------------------------------------------------- /Sources/Samples/Droid/Resources/AboutResources.txt: -------------------------------------------------------------------------------- 1 | Images, layout descriptions, binary blobs and string dictionaries can be included 2 | in your application as resource files. Various Android APIs are designed to 3 | operate on the resource IDs instead of dealing with images, strings or binary blobs 4 | directly. 5 | 6 | For example, a sample Android app that contains a user interface layout (main.axml), 7 | an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png) 8 | would keep its resources in the "Resources" directory of the application: 9 | 10 | Resources/ 11 | drawable/ 12 | icon.png 13 | 14 | layout/ 15 | main.axml 16 | 17 | values/ 18 | strings.xml 19 | 20 | In order to get the build system to recognize Android resources, set the build action to 21 | "AndroidResource". The native Android APIs do not operate directly with filenames, but 22 | instead operate on resource IDs. When you compile an Android application that uses resources, 23 | the build system will package the resources for distribution and generate a class called "R" 24 | (this is an Android convention) that contains the tokens for each one of the resources 25 | included. For example, for the above Resources layout, this is what the R class would expose: 26 | 27 | public class R { 28 | public class drawable { 29 | public const int icon = 0x123; 30 | } 31 | 32 | public class layout { 33 | public const int main = 0x456; 34 | } 35 | 36 | public class strings { 37 | public const int first_string = 0xabc; 38 | public const int second_string = 0xbcd; 39 | } 40 | } 41 | 42 | You would then use R.drawable.icon to reference the drawable/icon.png file, or R.layout.main 43 | to reference the layout/main.axml file, or R.strings.first_string to reference the first 44 | string in the dictionary file values/strings.xml. 45 | -------------------------------------------------------------------------------- /Sources/Samples/Droid/Resources/Resource.designer.cs: -------------------------------------------------------------------------------- 1 | namespace Sample.Droid 2 | { 3 | 4 | 5 | public partial class Resource 6 | { 7 | 8 | public partial class Attribute 9 | { 10 | 11 | private Attribute() 12 | { 13 | } 14 | } 15 | 16 | public partial class Drawable 17 | { 18 | 19 | // aapt resource value: 0x7f020000 20 | public const int icon = 2130837504; 21 | 22 | private Drawable() 23 | { 24 | } 25 | } 26 | 27 | public partial class Layout 28 | { 29 | 30 | // aapt resource value: 0x7f030000 31 | public const int Main = 2130903040; 32 | 33 | private Layout() 34 | { 35 | } 36 | } 37 | 38 | public partial class String 39 | { 40 | 41 | // aapt resource value: 0x7f040000 42 | public const int hello = 2130968576; 43 | 44 | // aapt resource value: 0x7f040001 45 | public const int app_name = 2130968577; 46 | 47 | private String() 48 | { 49 | } 50 | } 51 | 52 | public partial class Id 53 | { 54 | 55 | // aapt resource value: 0x7f050000 56 | public const int myButton = 2131034112; 57 | 58 | private Id() 59 | { 60 | } 61 | } 62 | } 63 | } 64 | 65 | -------------------------------------------------------------------------------- /Sources/Samples/Droid/Resources/drawable-hdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dotnet-ad/Xam.Forms.NavigationExtensions/78429b03f0649e1b9d80ab8540459cfea26e6e2c/Sources/Samples/Droid/Resources/drawable-hdpi/icon.png -------------------------------------------------------------------------------- /Sources/Samples/Droid/Resources/drawable-xhdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dotnet-ad/Xam.Forms.NavigationExtensions/78429b03f0649e1b9d80ab8540459cfea26e6e2c/Sources/Samples/Droid/Resources/drawable-xhdpi/icon.png -------------------------------------------------------------------------------- /Sources/Samples/Droid/Resources/drawable-xxhdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dotnet-ad/Xam.Forms.NavigationExtensions/78429b03f0649e1b9d80ab8540459cfea26e6e2c/Sources/Samples/Droid/Resources/drawable-xxhdpi/icon.png -------------------------------------------------------------------------------- /Sources/Samples/Droid/Resources/drawable/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dotnet-ad/Xam.Forms.NavigationExtensions/78429b03f0649e1b9d80ab8540459cfea26e6e2c/Sources/Samples/Droid/Resources/drawable/icon.png -------------------------------------------------------------------------------- /Sources/Samples/Droid/Resources/layout/Tabbar.axml: -------------------------------------------------------------------------------- 1 |  2 | 3 | -------------------------------------------------------------------------------- /Sources/Samples/Droid/Resources/layout/Toolbar.axml: -------------------------------------------------------------------------------- 1 |  2 | 3 | -------------------------------------------------------------------------------- /Sources/Samples/Droid/Resources/values/styles.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 5 | 6 | 24 | 27 | 28 | -------------------------------------------------------------------------------- /Sources/Samples/Droid/Sample.Droid.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | {9CF2AC9F-600D-4488-8C62-1413BF6F7581} 7 | {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 8 | Library 9 | Sample.Droid 10 | Sample.Droid 11 | v6.0 12 | True 13 | Resources\Resource.designer.cs 14 | Resource 15 | Properties\AndroidManifest.xml 16 | Resources 17 | Assets 18 | true 19 | 20 | 21 | true 22 | full 23 | false 24 | bin\Debug 25 | DEBUG; 26 | prompt 27 | 4 28 | false 29 | None 30 | 31 | 32 | true 33 | bin\Release 34 | prompt 35 | 4 36 | false 37 | false 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | ..\..\packages\Xamarin.Android.Support.v4.23.3.0\lib\MonoAndroid403\Xamarin.Android.Support.v4.dll 46 | 47 | 48 | ..\..\packages\Xamarin.Android.Support.Vector.Drawable.23.3.0\lib\MonoAndroid403\Xamarin.Android.Support.Vector.Drawable.dll 49 | 50 | 51 | ..\..\packages\Xamarin.Android.Support.Animated.Vector.Drawable.23.3.0\lib\MonoAndroid403\Xamarin.Android.Support.Animated.Vector.Drawable.dll 52 | 53 | 54 | ..\..\packages\Xamarin.Android.Support.v7.AppCompat.23.3.0\lib\MonoAndroid403\Xamarin.Android.Support.v7.AppCompat.dll 55 | 56 | 57 | ..\..\packages\Xamarin.Android.Support.v7.RecyclerView.23.3.0\lib\MonoAndroid403\Xamarin.Android.Support.v7.RecyclerView.dll 58 | 59 | 60 | ..\..\packages\Xamarin.Android.Support.Design.23.3.0\lib\MonoAndroid43\Xamarin.Android.Support.Design.dll 61 | 62 | 63 | ..\..\packages\Xamarin.Android.Support.v7.CardView.23.3.0\lib\MonoAndroid403\Xamarin.Android.Support.v7.CardView.dll 64 | 65 | 66 | ..\..\packages\Xamarin.Android.Support.v7.MediaRouter.23.3.0\lib\MonoAndroid403\Xamarin.Android.Support.v7.MediaRouter.dll 67 | 68 | 69 | ..\..\packages\Xamarin.Forms.2.2.0.31\lib\MonoAndroid10\Xamarin.Forms.Platform.Android.dll 70 | 71 | 72 | ..\..\packages\Xamarin.Forms.2.2.0.31\lib\MonoAndroid10\FormsViewGroup.dll 73 | 74 | 75 | ..\..\packages\Xamarin.Forms.2.2.0.31\lib\MonoAndroid10\Xamarin.Forms.Core.dll 76 | 77 | 78 | ..\..\packages\Xamarin.Forms.2.2.0.31\lib\MonoAndroid10\Xamarin.Forms.Xaml.dll 79 | 80 | 81 | ..\..\packages\Xamarin.Forms.2.2.0.31\lib\MonoAndroid10\Xamarin.Forms.Platform.dll 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | {7ED12A87-2155-4804-B951-51CBEF135578} 107 | Sample 108 | 109 | 110 | {F85EB676-1488-41F4-8C09-488621D01A83} 111 | Xamarin.Forms.NavigationExtensions 112 | 113 | 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /Sources/Samples/Droid/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Sources/Samples/Sample/App.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | using Xamarin.Forms; 4 | using Sample.Navigation; 5 | 6 | namespace Sample 7 | { 8 | public class App : Application 9 | { 10 | public App() 11 | { 12 | Locator.Service = new WebService(); 13 | 14 | var tabbedPage = new TabbedPage(); 15 | 16 | tabbedPage.Children.Add(new NavigationPage(new AlbumsPage()) { Title="Albums" }); 17 | tabbedPage.Children.Add(new NavigationPage(new UsersPage()) { Title="Users" }); 18 | 19 | MainPage = tabbedPage; 20 | } 21 | 22 | public readonly TimeSpan RestorationTimeSpan = TimeSpan.FromHours(1); 23 | 24 | protected override async void OnStart() 25 | { 26 | var tabbedPage = this.MainPage as TabbedPage; 27 | await tabbedPage.Children.RestoreAsync("Main", RestorationTimeSpan); 28 | } 29 | 30 | protected override void OnSleep() 31 | { 32 | var tabbedPage = this.MainPage as TabbedPage; 33 | tabbedPage.Children.Store("Main"); 34 | } 35 | 36 | protected override void OnResume() 37 | { 38 | // Handle when your app resumes 39 | } 40 | } 41 | } 42 | 43 | -------------------------------------------------------------------------------- /Sources/Samples/Sample/Model/Entities/Album.cs: -------------------------------------------------------------------------------- 1 | namespace Sample.Navigation 2 | { 3 | using Newtonsoft.Json; 4 | 5 | public class Album 6 | { 7 | [JsonProperty("id")] 8 | public int Identifier { get; set; } 9 | 10 | [JsonProperty("title")] 11 | public string Title { get; set; } 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /Sources/Samples/Sample/Model/Entities/Photo.cs: -------------------------------------------------------------------------------- 1 | namespace Sample.Navigation 2 | { 3 | using Newtonsoft.Json; 4 | 5 | public class Photo 6 | { 7 | [JsonProperty("id")] 8 | public int Identifier { get; set; } 9 | 10 | [JsonProperty("title")] 11 | public string Title { get; set; } 12 | 13 | [JsonProperty("url")] 14 | public string Url { get; set; } 15 | 16 | [JsonProperty("thumbnailUrl")] 17 | public string ThumbnailUrl { get; set; } 18 | } 19 | } 20 | 21 | -------------------------------------------------------------------------------- /Sources/Samples/Sample/Model/Entities/User.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Newtonsoft.Json; 3 | 4 | namespace Sample 5 | { 6 | public class User 7 | { 8 | [JsonProperty("id")] 9 | public int Identifier { get; set; } 10 | 11 | [JsonProperty("name")] 12 | public string Name { get; set; } 13 | 14 | [JsonProperty("username")] 15 | public string Username { get; set; } 16 | 17 | [JsonProperty("email")] 18 | public string Email { get; set; } 19 | 20 | [JsonProperty("website")] 21 | public string Website { get; set; } 22 | 23 | [JsonProperty("phone")] 24 | public string Phone { get; set; } 25 | } 26 | } 27 | 28 | -------------------------------------------------------------------------------- /Sources/Samples/Sample/Model/IService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading.Tasks; 4 | 5 | namespace Sample.Navigation 6 | { 7 | public interface IService 8 | { 9 | Task> GetAlbums(); 10 | 11 | Task> GetPhotos(int albumId); 12 | 13 | Task GetPhoto(int photoId); 14 | 15 | Task> GetUsers(); 16 | 17 | Task GetUser(int userId); 18 | } 19 | } 20 | 21 | -------------------------------------------------------------------------------- /Sources/Samples/Sample/Model/Locator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace Sample.Navigation 3 | { 4 | public static class Locator 5 | { 6 | public static IService Service { get; set; } 7 | } 8 | } 9 | 10 | -------------------------------------------------------------------------------- /Sources/Samples/Sample/Model/WebService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Net.Http; 4 | using System.Threading.Tasks; 5 | using Newtonsoft.Json; 6 | 7 | namespace Sample.Navigation 8 | { 9 | public class WebService : IService 10 | { 11 | public WebService() 12 | { 13 | this.Client = new HttpClient(); 14 | } 15 | 16 | private HttpClient Client { get; set; } 17 | 18 | public const string EndPoint = "http://jsonplaceholder.typicode.com"; 19 | 20 | public const string AlbumsPath = "albums"; 21 | 22 | public const string AlbumPhotosPath = "photos?albumId={0}"; 23 | 24 | public const string PhotoPath = "photos/{0}"; 25 | 26 | public const string UsersPath = "users"; 27 | 28 | public const string UserPath = "users/{0}"; 29 | 30 | public Task> GetAlbums() 31 | { 32 | return this.GetJson>(AlbumsPath); 33 | } 34 | 35 | public Task> GetPhotos(int albumId) 36 | { 37 | return this.GetJson>(string.Format(AlbumPhotosPath,albumId)); 38 | } 39 | 40 | public Task GetPhoto(int photoId) 41 | { 42 | return this.GetJson(string.Format(PhotoPath, photoId)); 43 | } 44 | 45 | public Task> GetUsers() 46 | { 47 | return this.GetJson>(UsersPath); 48 | } 49 | 50 | public Task GetUser(int userId) 51 | { 52 | return this.GetJson(string.Format(UserPath, userId)); 53 | } 54 | 55 | private async Task GetJson(string path) 56 | { 57 | var url = string.Format("{0}/{1}", EndPoint, path); 58 | var req = await this.Client.GetAsync(url); 59 | req.EnsureSuccessStatusCode(); 60 | var content = await req.Content.ReadAsStringAsync(); 61 | return JsonConvert.DeserializeObject(content); 62 | } 63 | } 64 | } 65 | 66 | -------------------------------------------------------------------------------- /Sources/Samples/Sample/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | 4 | // Information about this assembly is defined by the following attributes. 5 | // Change them to the values specific to your project. 6 | 7 | [assembly: AssemblyTitle("Sample")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("")] 12 | [assembly: AssemblyCopyright("alois")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". 17 | // The form "{Major}.{Minor}.*" will automatically update the build and revision, 18 | // and "{Major}.{Minor}.{Build}.*" will update just the revision. 19 | 20 | [assembly: AssemblyVersion("1.0.*")] 21 | 22 | // The following attributes are used to specify the signing key for the assembly, 23 | // if desired. See the Mono documentation for more information about signing. 24 | 25 | //[assembly: AssemblyDelaySign(false)] 26 | //[assembly: AssemblyKeyFile("")] 27 | 28 | -------------------------------------------------------------------------------- /Sources/Samples/Sample/Sample.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | {7ED12A87-2155-4804-B951-51CBEF135578} 7 | {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 8 | true 9 | Library 10 | Sample 11 | Sample 12 | v4.5 13 | Profile78 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug 20 | DEBUG; 21 | prompt 22 | 4 23 | false 24 | false 25 | 26 | 27 | true 28 | bin\Release 29 | prompt 30 | 4 31 | false 32 | false 33 | 34 | 35 | 36 | 37 | 38 | AlbumPage.xaml 39 | 40 | 41 | AlbumsPage.xaml 42 | 43 | 44 | PhotoPage.xaml 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | UsersPage.xaml 57 | 58 | 59 | UserPage.xaml 60 | 61 | 62 | 63 | 64 | 65 | 66 | ..\..\packages\Xamarin.Forms.2.2.0.31\lib\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+MonoTouch10+Xamarin.iOS10\Xamarin.Forms.Core.dll 67 | 68 | 69 | ..\..\packages\Xamarin.Forms.2.2.0.31\lib\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+MonoTouch10+Xamarin.iOS10\Xamarin.Forms.Xaml.dll 70 | 71 | 72 | ..\..\packages\Xamarin.Forms.2.2.0.31\lib\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+MonoTouch10+Xamarin.iOS10\Xamarin.Forms.Platform.dll 73 | 74 | 75 | ..\..\packages\Microsoft.Net.Http.2.2.29\lib\portable-net40+sl4+win8+wp71+wpa81\System.Net.Http.dll 76 | 77 | 78 | ..\..\packages\Microsoft.Net.Http.2.2.29\lib\portable-net40+sl4+win8+wp71+wpa81\System.Net.Http.Primitives.dll 79 | 80 | 81 | ..\..\packages\Microsoft.Net.Http.2.2.29\lib\portable-net40+sl4+win8+wp71+wpa81\System.Net.Http.Extensions.dll 82 | 83 | 84 | ..\..\packages\Newtonsoft.Json.8.0.3\lib\portable-net45+wp80+win8+wpa81+dnxcore50\Newtonsoft.Json.dll 85 | 86 | 87 | ..\..\packages\CommonServiceLocator.1.3\lib\portable-net4+sl5+netcore45+wpa81+wp8\Microsoft.Practices.ServiceLocation.dll 88 | 89 | 90 | ..\..\packages\MvvmLightLibs.5.3.0.0\lib\portable-net45+wp8+wpa81+netcore45+monoandroid1+xamarin.ios10\GalaSoft.MvvmLight.dll 91 | 92 | 93 | ..\..\packages\MvvmLightLibs.5.3.0.0\lib\portable-net45+wp8+wpa81+netcore45+monoandroid1+xamarin.ios10\GalaSoft.MvvmLight.Extras.dll 94 | 95 | 96 | ..\..\NavigationExtensions\bin\Release\Xam.Forms.NavigationExtensions.dll 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | MSBuild:UpdateDesignTimeXaml 105 | 106 | 107 | MSBuild:UpdateDesignTimeXaml 108 | 109 | 110 | MSBuild:UpdateDesignTimeXaml 111 | 112 | 113 | MSBuild:UpdateDesignTimeXaml 114 | 115 | 116 | MSBuild:UpdateDesignTimeXaml 117 | 118 | 119 | 120 | 121 | {F85EB676-1488-41F4-8C09-488621D01A83} 122 | Xamarin.Forms.NavigationExtensions 123 | 124 | 125 | 126 | 127 | -------------------------------------------------------------------------------- /Sources/Samples/Sample/ViewModels/AlbumViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using GalaSoft.MvvmLight; 6 | 7 | namespace Sample.Navigation 8 | { 9 | public class AlbumViewModel : ViewModelBase 10 | { 11 | public AlbumViewModel(IService service) 12 | { 13 | this.service = service; 14 | this.Photos = new List(); 15 | } 16 | 17 | private int albumId; 18 | 19 | private readonly IService service; 20 | 21 | private IEnumerable photos; 22 | 23 | public IEnumerable Photos 24 | { 25 | get { return photos; } 26 | set { this.Set(ref photos, value); } 27 | } 28 | 29 | public async Task Update(int albumId) 30 | { 31 | if (albumId != this.albumId || !this.Photos.Any()) 32 | { 33 | this.albumId = albumId; 34 | this.Photos = await this.service.GetPhotos(albumId); 35 | } 36 | } 37 | } 38 | } 39 | 40 | -------------------------------------------------------------------------------- /Sources/Samples/Sample/ViewModels/AlbumsViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using GalaSoft.MvvmLight; 6 | 7 | namespace Sample.Navigation 8 | { 9 | public class AlbumsViewModel : ViewModelBase 10 | { 11 | public AlbumsViewModel(IService service) 12 | { 13 | this.service = service; 14 | this.Albums = new List(); 15 | } 16 | 17 | private readonly IService service; 18 | 19 | private IEnumerable albums; 20 | 21 | public IEnumerable Albums 22 | { 23 | get { return albums; } 24 | set { this.Set(ref albums, value); } 25 | } 26 | 27 | public async Task Update() 28 | { 29 | if (!this.Albums.Any()) 30 | { 31 | this.Albums = await this.service.GetAlbums(); 32 | } 33 | } 34 | } 35 | } 36 | 37 | -------------------------------------------------------------------------------- /Sources/Samples/Sample/ViewModels/PhotoViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using GalaSoft.MvvmLight; 4 | 5 | namespace Sample.Navigation 6 | { 7 | public class PhotoViewModel : ViewModelBase 8 | { 9 | public PhotoViewModel(IService service) 10 | { 11 | this.service = service; 12 | } 13 | 14 | private int photoId = -1; 15 | 16 | private readonly IService service; 17 | 18 | private string url; 19 | 20 | public string Url 21 | { 22 | get { return url; } 23 | set { this.Set(ref url, value); } 24 | } 25 | 26 | public async Task Update(int photoId) 27 | { 28 | if (photoId != this.photoId) 29 | { 30 | this.photoId = photoId; 31 | this.Url = (await this.service.GetPhoto(photoId))?.Url; 32 | } 33 | } 34 | } 35 | } 36 | 37 | -------------------------------------------------------------------------------- /Sources/Samples/Sample/ViewModels/UserViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using GalaSoft.MvvmLight; 4 | using Sample.Navigation; 5 | 6 | namespace Sample 7 | { 8 | public class UserViewModel : ViewModelBase 9 | { 10 | public UserViewModel(IService service) 11 | { 12 | this.service = service; 13 | } 14 | 15 | private int userId = -1; 16 | 17 | private readonly IService service; 18 | 19 | private User user; 20 | 21 | public User User 22 | { 23 | get { return user; } 24 | set 25 | { 26 | if (this.Set(ref user, value)) 27 | { 28 | this.RaisePropertyChanged(() => this.Name); 29 | this.RaisePropertyChanged(() => this.Username); 30 | this.RaisePropertyChanged(() => this.Phone); 31 | this.RaisePropertyChanged(() => this.Website); 32 | this.RaisePropertyChanged(() => this.Email); 33 | } 34 | } 35 | } 36 | 37 | public string Name 38 | { 39 | get { return this.user?.Name; } 40 | } 41 | 42 | public string Username 43 | { 44 | get { return this.user?.Username; } 45 | } 46 | 47 | public string Phone 48 | { 49 | get { return this.user?.Phone; } 50 | } 51 | 52 | public string Email 53 | { 54 | get { return this.user?.Email; } 55 | } 56 | 57 | public string Website 58 | { 59 | get { return this.user?.Website; } 60 | } 61 | 62 | public async Task Update(int userId) 63 | { 64 | if (userId != this.userId) 65 | { 66 | this.userId = userId; 67 | this.User = await this.service.GetUser(userId); 68 | } 69 | } 70 | } 71 | } 72 | 73 | -------------------------------------------------------------------------------- /Sources/Samples/Sample/ViewModels/UsersViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using GalaSoft.MvvmLight; 6 | using Sample.Navigation; 7 | 8 | namespace Sample 9 | { 10 | public class UsersViewModel : ViewModelBase 11 | { 12 | public UsersViewModel(IService service) 13 | { 14 | this.service = service; 15 | this.Users = new List(); 16 | } 17 | 18 | private readonly IService service; 19 | 20 | private IEnumerable users; 21 | 22 | public IEnumerable Users 23 | { 24 | get { return users; } 25 | set { this.Set(ref users, value); } 26 | } 27 | 28 | public async Task Update() 29 | { 30 | if (!this.Users.Any()) 31 | { 32 | this.Users = await this.service.GetUsers(); 33 | } 34 | } 35 | } 36 | } 37 | 38 | -------------------------------------------------------------------------------- /Sources/Samples/Sample/Views/AlbumPage.xaml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Sources/Samples/Sample/Views/AlbumPage.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Xamarin.Forms; 4 | 5 | namespace Sample.Navigation 6 | { 7 | public partial class AlbumPage : ContentPage 8 | { 9 | public AlbumPage() 10 | { 11 | this.BindingContext = new AlbumViewModel(Locator.Service); 12 | 13 | InitializeComponent(); 14 | } 15 | 16 | protected override async void OnAppearing() 17 | { 18 | base.OnAppearing(); 19 | 20 | var albumId = (int) this.GetNavigationArgs(); 21 | 22 | this.Title = "Loading ..."; 23 | 24 | try 25 | { 26 | var vm = this.BindingContext as AlbumViewModel; 27 | await vm.Update(albumId); 28 | this.Title = albumId.ToString(); 29 | } 30 | catch (Exception ex) 31 | { 32 | this.Title = "Error"; 33 | } 34 | } 35 | 36 | private void OnItemTapped(object sender, Xamarin.Forms.ItemTappedEventArgs e) 37 | { 38 | var item = e.Item as Photo; 39 | this.Navigation.PushAsync(item.Identifier, true); 40 | } 41 | } 42 | } 43 | 44 | -------------------------------------------------------------------------------- /Sources/Samples/Sample/Views/AlbumsPage.xaml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Sources/Samples/Sample/Views/AlbumsPage.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Xamarin.Forms; 4 | 5 | namespace Sample.Navigation 6 | { 7 | public partial class AlbumsPage : ContentPage 8 | { 9 | public AlbumsPage() 10 | { 11 | this.BindingContext = new AlbumsViewModel(Locator.Service); 12 | 13 | InitializeComponent(); 14 | } 15 | 16 | protected override async void OnAppearing() 17 | { 18 | base.OnAppearing(); 19 | 20 | this.Title = "Loading ..."; 21 | 22 | try 23 | { 24 | var vm = this.BindingContext as AlbumsViewModel; 25 | await vm.Update(); 26 | this.Title = "Albums"; 27 | } 28 | catch (Exception ex) 29 | { 30 | this.Title = "Error"; 31 | } 32 | } 33 | 34 | private void OnItemTapped(object sender, Xamarin.Forms.ItemTappedEventArgs e) 35 | { 36 | var item = e.Item as Album; 37 | this.Navigation.PushAsync(item.Identifier, true); 38 | } 39 | } 40 | } 41 | 42 | -------------------------------------------------------------------------------- /Sources/Samples/Sample/Views/PhotoPage.xaml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Sources/Samples/Sample/Views/PhotoPage.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Xamarin.Forms; 4 | 5 | namespace Sample.Navigation 6 | { 7 | public partial class PhotoPage : ContentPage 8 | { 9 | public PhotoPage() 10 | { 11 | this.BindingContext = new PhotoViewModel(Locator.Service); 12 | 13 | InitializeComponent(); 14 | } 15 | 16 | protected override async void OnAppearing() 17 | { 18 | base.OnAppearing(); 19 | 20 | var photoId = (int)this.GetNavigationArgs(); 21 | 22 | this.Title = "Loading ..."; 23 | 24 | try 25 | { 26 | var vm = this.BindingContext as PhotoViewModel; 27 | await vm.Update(photoId); 28 | this.Title = photoId.ToString(); 29 | } 30 | catch (Exception ex) 31 | { 32 | this.Title = "Error"; 33 | } 34 | } 35 | } 36 | } 37 | 38 | -------------------------------------------------------------------------------- /Sources/Samples/Sample/Views/UserPage.xaml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 10 | 11 | -------------------------------------------------------------------------------- /Sources/Samples/Sample/Views/UserPage.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Sample.Navigation; 4 | using Xamarin.Forms; 5 | 6 | namespace Sample 7 | { 8 | public partial class UserPage : ContentPage 9 | { 10 | public UserPage() 11 | { 12 | this.BindingContext = new UserViewModel(Locator.Service); 13 | 14 | InitializeComponent(); 15 | } 16 | 17 | protected override async void OnAppearing() 18 | { 19 | base.OnAppearing(); 20 | 21 | var userId = (int)this.GetNavigationArgs(); 22 | 23 | this.Title = "Loading ..."; 24 | 25 | try 26 | { 27 | var vm = this.BindingContext as UserViewModel; 28 | await vm.Update(userId); 29 | this.Title = userId.ToString(); 30 | } 31 | catch (Exception ex) 32 | { 33 | this.Title = "Error"; 34 | } 35 | } 36 | } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /Sources/Samples/Sample/Views/UsersPage.xaml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Sources/Samples/Sample/Views/UsersPage.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Sample.Navigation; 4 | using Xamarin.Forms; 5 | 6 | namespace Sample 7 | { 8 | public partial class UsersPage : ContentPage 9 | { 10 | public UsersPage() 11 | { 12 | this.BindingContext = new UsersViewModel(Locator.Service); 13 | 14 | InitializeComponent(); 15 | } 16 | 17 | protected override async void OnAppearing() 18 | { 19 | base.OnAppearing(); 20 | 21 | this.Title = "Loading ..."; 22 | 23 | try 24 | { 25 | var vm = this.BindingContext as UsersViewModel; 26 | await vm.Update(); 27 | this.Title = "Users"; 28 | } 29 | catch (Exception ex) 30 | { 31 | this.Title = "Error"; 32 | } 33 | } 34 | 35 | private void OnItemTapped(object sender, Xamarin.Forms.ItemTappedEventArgs e) 36 | { 37 | var item = e.Item as User; 38 | this.Navigation.PushAsync(item.Identifier, true); 39 | } 40 | } 41 | } 42 | 43 | -------------------------------------------------------------------------------- /Sources/Samples/Sample/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Sources/Samples/Samples.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sample", "Sample\Sample.csproj", "{7ED12A87-2155-4804-B951-51CBEF135578}" 5 | EndProject 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sample.iOS", "iOS\Sample.iOS.csproj", "{5DB3C45B-54DA-4ECD-BF8B-18EFCCC989B0}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sample.Droid", "Droid\Sample.Droid.csproj", "{9CF2AC9F-600D-4488-8C62-1413BF6F7581}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Xamarin.Forms.NavigationExtensions", "..\NavigationExtensions\Xamarin.Forms.NavigationExtensions.csproj", "{F85EB676-1488-41F4-8C09-488621D01A83}" 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Debug|Any CPU = Debug|Any CPU 15 | Release|Any CPU = Release|Any CPU 16 | Debug|iPhoneSimulator = Debug|iPhoneSimulator 17 | Release|iPhone = Release|iPhone 18 | Release|iPhoneSimulator = Release|iPhoneSimulator 19 | Debug|iPhone = Debug|iPhone 20 | EndGlobalSection 21 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 22 | {7ED12A87-2155-4804-B951-51CBEF135578}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 23 | {7ED12A87-2155-4804-B951-51CBEF135578}.Debug|Any CPU.Build.0 = Debug|Any CPU 24 | {7ED12A87-2155-4804-B951-51CBEF135578}.Release|Any CPU.ActiveCfg = Release|Any CPU 25 | {7ED12A87-2155-4804-B951-51CBEF135578}.Release|Any CPU.Build.0 = Release|Any CPU 26 | {7ED12A87-2155-4804-B951-51CBEF135578}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU 27 | {7ED12A87-2155-4804-B951-51CBEF135578}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU 28 | {7ED12A87-2155-4804-B951-51CBEF135578}.Release|iPhone.ActiveCfg = Release|Any CPU 29 | {7ED12A87-2155-4804-B951-51CBEF135578}.Release|iPhone.Build.0 = Release|Any CPU 30 | {7ED12A87-2155-4804-B951-51CBEF135578}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU 31 | {7ED12A87-2155-4804-B951-51CBEF135578}.Release|iPhoneSimulator.Build.0 = Release|Any CPU 32 | {7ED12A87-2155-4804-B951-51CBEF135578}.Debug|iPhone.ActiveCfg = Debug|Any CPU 33 | {7ED12A87-2155-4804-B951-51CBEF135578}.Debug|iPhone.Build.0 = Debug|Any CPU 34 | {5DB3C45B-54DA-4ECD-BF8B-18EFCCC989B0}.Debug|Any CPU.ActiveCfg = Debug|iPhoneSimulator 35 | {5DB3C45B-54DA-4ECD-BF8B-18EFCCC989B0}.Debug|Any CPU.Build.0 = Debug|iPhoneSimulator 36 | {5DB3C45B-54DA-4ECD-BF8B-18EFCCC989B0}.Release|Any CPU.ActiveCfg = Debug|iPhoneSimulator 37 | {5DB3C45B-54DA-4ECD-BF8B-18EFCCC989B0}.Release|Any CPU.Build.0 = Debug|iPhoneSimulator 38 | {5DB3C45B-54DA-4ECD-BF8B-18EFCCC989B0}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator 39 | {5DB3C45B-54DA-4ECD-BF8B-18EFCCC989B0}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator 40 | {5DB3C45B-54DA-4ECD-BF8B-18EFCCC989B0}.Release|iPhone.ActiveCfg = Release|iPhone 41 | {5DB3C45B-54DA-4ECD-BF8B-18EFCCC989B0}.Release|iPhone.Build.0 = Release|iPhone 42 | {5DB3C45B-54DA-4ECD-BF8B-18EFCCC989B0}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator 43 | {5DB3C45B-54DA-4ECD-BF8B-18EFCCC989B0}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator 44 | {5DB3C45B-54DA-4ECD-BF8B-18EFCCC989B0}.Debug|iPhone.ActiveCfg = Debug|iPhone 45 | {5DB3C45B-54DA-4ECD-BF8B-18EFCCC989B0}.Debug|iPhone.Build.0 = Debug|iPhone 46 | {9CF2AC9F-600D-4488-8C62-1413BF6F7581}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 47 | {9CF2AC9F-600D-4488-8C62-1413BF6F7581}.Debug|Any CPU.Build.0 = Debug|Any CPU 48 | {9CF2AC9F-600D-4488-8C62-1413BF6F7581}.Release|Any CPU.ActiveCfg = Release|Any CPU 49 | {9CF2AC9F-600D-4488-8C62-1413BF6F7581}.Release|Any CPU.Build.0 = Release|Any CPU 50 | {9CF2AC9F-600D-4488-8C62-1413BF6F7581}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU 51 | {9CF2AC9F-600D-4488-8C62-1413BF6F7581}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU 52 | {9CF2AC9F-600D-4488-8C62-1413BF6F7581}.Release|iPhone.ActiveCfg = Release|Any CPU 53 | {9CF2AC9F-600D-4488-8C62-1413BF6F7581}.Release|iPhone.Build.0 = Release|Any CPU 54 | {9CF2AC9F-600D-4488-8C62-1413BF6F7581}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU 55 | {9CF2AC9F-600D-4488-8C62-1413BF6F7581}.Release|iPhoneSimulator.Build.0 = Release|Any CPU 56 | {9CF2AC9F-600D-4488-8C62-1413BF6F7581}.Debug|iPhone.ActiveCfg = Debug|Any CPU 57 | {9CF2AC9F-600D-4488-8C62-1413BF6F7581}.Debug|iPhone.Build.0 = Debug|Any CPU 58 | {F85EB676-1488-41F4-8C09-488621D01A83}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 59 | {F85EB676-1488-41F4-8C09-488621D01A83}.Debug|Any CPU.Build.0 = Debug|Any CPU 60 | {F85EB676-1488-41F4-8C09-488621D01A83}.Release|Any CPU.ActiveCfg = Release|Any CPU 61 | {F85EB676-1488-41F4-8C09-488621D01A83}.Release|Any CPU.Build.0 = Release|Any CPU 62 | {F85EB676-1488-41F4-8C09-488621D01A83}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU 63 | {F85EB676-1488-41F4-8C09-488621D01A83}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU 64 | {F85EB676-1488-41F4-8C09-488621D01A83}.Release|iPhone.ActiveCfg = Release|Any CPU 65 | {F85EB676-1488-41F4-8C09-488621D01A83}.Release|iPhone.Build.0 = Release|Any CPU 66 | {F85EB676-1488-41F4-8C09-488621D01A83}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU 67 | {F85EB676-1488-41F4-8C09-488621D01A83}.Release|iPhoneSimulator.Build.0 = Release|Any CPU 68 | {F85EB676-1488-41F4-8C09-488621D01A83}.Debug|iPhone.ActiveCfg = Debug|Any CPU 69 | {F85EB676-1488-41F4-8C09-488621D01A83}.Debug|iPhone.Build.0 = Debug|Any CPU 70 | EndGlobalSection 71 | EndGlobal 72 | -------------------------------------------------------------------------------- /Sources/Samples/iOS/AppDelegate.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | using Foundation; 6 | using UIKit; 7 | 8 | namespace Sample.iOS 9 | { 10 | [Register("AppDelegate")] 11 | public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate 12 | { 13 | public override bool FinishedLaunching(UIApplication app, NSDictionary options) 14 | { 15 | global::Xamarin.Forms.Forms.Init(); 16 | 17 | LoadApplication(new App()); 18 | 19 | return base.FinishedLaunching(app, options); 20 | } 21 | } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /Sources/Samples/iOS/Assets.xcassets/AppIcons.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images": [ 3 | { 4 | "idiom": "iphone", 5 | "size": "29x29", 6 | "scale": "1x" 7 | }, 8 | { 9 | "idiom": "iphone", 10 | "size": "29x29", 11 | "scale": "2x" 12 | }, 13 | { 14 | "idiom": "iphone", 15 | "size": "29x29", 16 | "scale": "3x" 17 | }, 18 | { 19 | "idiom": "iphone", 20 | "size": "40x40", 21 | "scale": "2x" 22 | }, 23 | { 24 | "idiom": "iphone", 25 | "size": "40x40", 26 | "scale": "3x" 27 | }, 28 | { 29 | "idiom": "iphone", 30 | "size": "57x57", 31 | "scale": "1x" 32 | }, 33 | { 34 | "idiom": "iphone", 35 | "size": "57x57", 36 | "scale": "2x" 37 | }, 38 | { 39 | "idiom": "iphone", 40 | "size": "60x60", 41 | "scale": "2x" 42 | }, 43 | { 44 | "idiom": "iphone", 45 | "size": "60x60", 46 | "scale": "3x" 47 | }, 48 | { 49 | "idiom": "ipad", 50 | "size": "29x29", 51 | "scale": "1x" 52 | }, 53 | { 54 | "idiom": "ipad", 55 | "size": "29x29", 56 | "scale": "2x" 57 | }, 58 | { 59 | "idiom": "ipad", 60 | "size": "40x40", 61 | "scale": "1x" 62 | }, 63 | { 64 | "idiom": "ipad", 65 | "size": "40x40", 66 | "scale": "2x" 67 | }, 68 | { 69 | "idiom": "ipad", 70 | "size": "50x50", 71 | "scale": "1x" 72 | }, 73 | { 74 | "idiom": "ipad", 75 | "size": "50x50", 76 | "scale": "2x" 77 | }, 78 | { 79 | "idiom": "ipad", 80 | "size": "72x72", 81 | "scale": "1x" 82 | }, 83 | { 84 | "idiom": "ipad", 85 | "size": "72x72", 86 | "scale": "2x" 87 | }, 88 | { 89 | "idiom": "ipad", 90 | "size": "76x76", 91 | "scale": "1x" 92 | }, 93 | { 94 | "idiom": "ipad", 95 | "size": "76x76", 96 | "scale": "2x" 97 | }, 98 | { 99 | "size": "24x24", 100 | "idiom": "watch", 101 | "scale": "2x", 102 | "role": "notificationCenter", 103 | "subtype": "38mm" 104 | }, 105 | { 106 | "size": "27.5x27.5", 107 | "idiom": "watch", 108 | "scale": "2x", 109 | "role": "notificationCenter", 110 | "subtype": "42mm" 111 | }, 112 | { 113 | "size": "29x29", 114 | "idiom": "watch", 115 | "role": "companionSettings", 116 | "scale": "2x" 117 | }, 118 | { 119 | "size": "29x29", 120 | "idiom": "watch", 121 | "role": "companionSettings", 122 | "scale": "3x" 123 | }, 124 | { 125 | "size": "40x40", 126 | "idiom": "watch", 127 | "scale": "2x", 128 | "role": "appLauncher", 129 | "subtype": "38mm" 130 | }, 131 | { 132 | "size": "44x44", 133 | "idiom": "watch", 134 | "scale": "2x", 135 | "role": "longLook", 136 | "subtype": "42mm" 137 | }, 138 | { 139 | "size": "86x86", 140 | "idiom": "watch", 141 | "scale": "2x", 142 | "role": "quickLook", 143 | "subtype": "38mm" 144 | }, 145 | { 146 | "size": "98x98", 147 | "idiom": "watch", 148 | "scale": "2x", 149 | "role": "quickLook", 150 | "subtype": "42mm" 151 | } 152 | ], 153 | "info": { 154 | "version": 1, 155 | "author": "xcode" 156 | } 157 | } -------------------------------------------------------------------------------- /Sources/Samples/iOS/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Sources/Samples/iOS/Entitlements.plist: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Sources/Samples/iOS/Info.plist: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | CFBundleDisplayName 6 | Sample 7 | CFBundleName 8 | Sample 9 | CFBundleIdentifier 10 | com.aloisdeniel.sample.navigation.sample 11 | CFBundleShortVersionString 12 | 1.0 13 | CFBundleVersion 14 | 1.0 15 | LSRequiresIPhoneOS 16 | 17 | MinimumOSVersion 18 | 8.0 19 | UIDeviceFamily 20 | 21 | 1 22 | 2 23 | 24 | UILaunchStoryboardName 25 | LaunchScreen 26 | UIRequiredDeviceCapabilities 27 | 28 | armv7 29 | 30 | UISupportedInterfaceOrientations 31 | 32 | UIInterfaceOrientationPortrait 33 | UIInterfaceOrientationLandscapeLeft 34 | UIInterfaceOrientationLandscapeRight 35 | 36 | UISupportedInterfaceOrientations~ipad 37 | 38 | UIInterfaceOrientationPortrait 39 | UIInterfaceOrientationPortraitUpsideDown 40 | UIInterfaceOrientationLandscapeLeft 41 | UIInterfaceOrientationLandscapeRight 42 | 43 | XSAppIconAssets 44 | Assets.xcassets/AppIcons.appiconset 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /Sources/Samples/iOS/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Sources/Samples/iOS/Main.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | using Foundation; 6 | using UIKit; 7 | 8 | namespace Sample.iOS 9 | { 10 | public class Application 11 | { 12 | // This is the main entry point of the application. 13 | static void Main(string[] args) 14 | { 15 | // if you want to use a different Application Delegate class from "AppDelegate" 16 | // you can specify it here. 17 | UIApplication.Main(args, null, "AppDelegate"); 18 | } 19 | } 20 | } 21 | 22 | -------------------------------------------------------------------------------- /Sources/Samples/iOS/Sample.iOS.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | iPhoneSimulator 6 | {5DB3C45B-54DA-4ECD-BF8B-18EFCCC989B0} 7 | {FEACFBD2-3405-455C-9665-78FE426C6842};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 8 | Exe 9 | Sample.iOS 10 | Sample.iOS 11 | Resources 12 | 13 | 14 | true 15 | full 16 | false 17 | bin\iPhoneSimulator\Debug 18 | DEBUG;ENABLE_TEST_CLOUD; 19 | prompt 20 | 4 21 | false 22 | iPhone Developer 23 | true 24 | true 25 | true 26 | true 27 | None 28 | i386 29 | false 30 | 31 | 32 | true 33 | bin\iPhone\Release 34 | 35 | prompt 36 | 4 37 | false 38 | iPhone Developer 39 | true 40 | true 41 | true 42 | Entitlements.plist 43 | ARMv7, ARM64 44 | 45 | 46 | true 47 | bin\iPhoneSimulator\Release 48 | 49 | prompt 50 | 4 51 | false 52 | iPhone Developer 53 | true 54 | true 55 | None 56 | i386 57 | 58 | 59 | true 60 | full 61 | false 62 | bin\iPhone\Debug 63 | DEBUG;ENABLE_TEST_CLOUD; 64 | prompt 65 | 4 66 | false 67 | iPhone Developer 68 | true 69 | true 70 | true 71 | true 72 | true 73 | true 74 | Entitlements.plist 75 | ARMv7, ARM64 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | ..\..\packages\Xamarin.Forms.2.2.0.31\lib\Xamarin.iOS10\Xamarin.Forms.Platform.iOS.dll 84 | 85 | 86 | ..\..\packages\Xamarin.Forms.2.2.0.31\lib\Xamarin.iOS10\Xamarin.Forms.Core.dll 87 | 88 | 89 | ..\..\packages\Xamarin.Forms.2.2.0.31\lib\Xamarin.iOS10\Xamarin.Forms.Xaml.dll 90 | 91 | 92 | ..\..\packages\Xamarin.Forms.2.2.0.31\lib\Xamarin.iOS10\Xamarin.Forms.Platform.dll 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | {7ED12A87-2155-4804-B951-51CBEF135578} 117 | Sample 118 | 119 | 120 | {F85EB676-1488-41F4-8C09-488621D01A83} 121 | Xamarin.Forms.NavigationExtensions 122 | 123 | 124 | 125 | 126 | -------------------------------------------------------------------------------- /Sources/Samples/iOS/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /Sources/Xamarin.Forms.NavigationExtensions.Shared/NavigationExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace Xamarin.Forms 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Runtime.CompilerServices; 6 | using System.Threading.Tasks; 7 | using System.Linq; 8 | using Xamarin.Forms.NavigationExt; 9 | 10 | 11 | /// 12 | /// Extensions for saving and restoring navigation states with arguments. 13 | /// 14 | public static class NavigationExtensions 15 | { 16 | #region Arguments access 17 | 18 | /// 19 | /// All the navigation arguments associated to pages. 20 | /// 21 | private static ConditionalWeakTable arguments = new ConditionalWeakTable(); 22 | 23 | /// 24 | /// Gets the navigation arguments for a page. 25 | /// 26 | /// The navigation arguments. 27 | /// Page. 28 | public static object GetNavigationArgs(this Page page) 29 | { 30 | object argument = null; 31 | arguments.TryGetValue(page, out argument); 32 | 33 | return argument; 34 | } 35 | 36 | /// 37 | /// Stores the navigation arguments for a page. 38 | /// 39 | /// The navigation arguments. 40 | /// Page. 41 | /// Arguments. 42 | public static void SetNavigationArgs(this Page page, object args) 43 | { 44 | if(args != null) 45 | { 46 | object existing = null; 47 | if (arguments.TryGetValue(page, out existing)) 48 | { 49 | arguments.Remove(page); 50 | } 51 | 52 | arguments.Add(page, args); 53 | } 54 | } 55 | 56 | #endregion 57 | 58 | #region State restoration 59 | 60 | private const string StoreKeyPrefix = "Navigation."; 61 | 62 | /// 63 | /// Restores all stacks from saved state in local storage. 64 | /// 65 | /// The async. 66 | /// Navigation. 67 | /// The base identifier of the stack. 68 | /// The maximum time for navigation restoration. 69 | public static async Task RestoreAsync(this INavigation navigation, string name, TimeSpan maximumRestoreSpan) 70 | { 71 | var key = $"{StoreKeyPrefix}{name}"; 72 | 73 | if (Application.Current.Properties.ContainsKey(key)) 74 | { 75 | var states = Application.Current.Properties[key] as NavigationStates; 76 | 77 | if (DateTime.Now - states.Date < maximumRestoreSpan) 78 | { 79 | var navigationPages = states.Navigation.Select(RestorePage).ToList(); 80 | var modalPages = states.Modal.Select(RestorePage).ToList(); 81 | 82 | if (navigationPages.Count > 1) 83 | { 84 | var initialPages = navigation.NavigationStack.ToList(); 85 | 86 | // 1. Restoring navigation stack 87 | var lastNavigationPage = navigationPages.LastOrDefault(); 88 | navigationPages.RemoveAt(navigationPages.Count - 1); 89 | await navigation.PushAsync(lastNavigationPage, false); 90 | foreach (var page in navigationPages) 91 | { 92 | navigation.InsertPageBefore(page, lastNavigationPage); 93 | } 94 | 95 | // 2. Removing already present pages before restore 96 | foreach (var page in initialPages) 97 | { 98 | navigation.RemovePage(page); 99 | } 100 | } 101 | 102 | if (modalPages.Count > 0) 103 | { 104 | //3. Restoring modal stack 105 | foreach (var page in modalPages) 106 | { 107 | await navigation.PushModalAsync(page, false); 108 | // HACK: lack of InsertPageBefore for modal stack 109 | if (Device.OS == TargetPlatform.iOS) 110 | { 111 | await Task.Delay(100); 112 | } 113 | } 114 | } 115 | } 116 | } 117 | } 118 | 119 | /// 120 | /// Stores all the navigations stacks with the given name into local storage. 121 | /// 122 | /// The navigation service. 123 | /// The name that will represents this navigation. 124 | /// The base identifier of the stack. 125 | public static void Store(this INavigation navigation, string name) 126 | { 127 | var states = new NavigationStates() 128 | { 129 | Date = DateTime.Now, 130 | Navigation = ConvertPages(navigation.NavigationStack), 131 | Modal = ConvertPages(navigation.ModalStack), 132 | }; 133 | 134 | Application.Current.Properties[$"{StoreKeyPrefix}{name}"] = states; 135 | } 136 | 137 | /// 138 | /// Restores the page by instanciating the page and argument from stored state. 139 | /// 140 | /// The page. 141 | /// State. 142 | private static Page RestorePage(PageState state) 143 | { 144 | var page = Activator.CreateInstance(state.PageType) as Page; 145 | var argument = state.Argument; 146 | page.SetNavigationArgs(argument); 147 | return page; 148 | } 149 | 150 | private static IEnumerable ConvertPages(IEnumerable pages) 151 | { 152 | return pages.Select((p) => new PageState() 153 | { 154 | PageType = p.GetType(), 155 | Argument = p.GetNavigationArgs(), 156 | }); 157 | } 158 | 159 | #endregion 160 | 161 | #region Navigation 162 | 163 | /// 164 | /// Navigates to the given page with an argument that will be available from this page, but also stored with the navigation state. 165 | /// 166 | /// The async. 167 | /// The navigation service. 168 | /// The destination page. 169 | /// The navigation arguments. 170 | /// Indicates whether the navigation should be animated. 171 | public static Task PushAsync(this INavigation navigation, Page page, object args, bool animated) 172 | { 173 | page.SetNavigationArgs(args); 174 | return navigation.PushAsync(page, animated); 175 | } 176 | 177 | /// 178 | /// Navigates modaly to the given page with an argument that will be available from this page, but also stored with the navigation state. 179 | /// 180 | /// The async. 181 | /// The navigation service. 182 | /// The destination page. 183 | /// The navigation arguments. 184 | /// Indicates whether the navigation should be animated. 185 | public static Task PushModalAsync(this INavigation navigation, Page page, object args, bool animated) 186 | { 187 | page.SetNavigationArgs(args); 188 | return navigation.PushModalAsync(page, animated); 189 | } 190 | 191 | /// 192 | /// Instanciates a page from its type(must have an empty constructor) and navigates to this page with an argument that will be available from this page, but also stored with the navigation state. 193 | /// 194 | /// The async. 195 | /// The navigation service. 196 | /// The destination page type. 197 | /// The navigation arguments. 198 | /// Indicates whether the navigation should be animated. 199 | public static Task PushAsync(this INavigation navigation, Type pageType, object args = null, bool animated = true) 200 | { 201 | var page = Activator.CreateInstance(pageType) as Page; 202 | return navigation.PushAsync(page, args, animated); 203 | } 204 | 205 | /// 206 | /// Instanciates a page from its type(must have an empty constructor) and navigates modaly to this page with an argument that will be available from this page, but also stored with the navigation state. 207 | /// 208 | /// The async. 209 | /// The navigation service. 210 | /// The destination page type. 211 | /// The navigation arguments. 212 | /// Indicates whether the navigation should be animated. 213 | public static Task PushModalAsync(this INavigation navigation, Type pageType, object args = null, bool animated = true) 214 | { 215 | var page = Activator.CreateInstance(pageType) as Page; 216 | return navigation.PushAsync(page, args, animated); 217 | } 218 | 219 | /// 220 | /// Instanciates a page from its type(must have an empty constructor) and navigates to this page with an argument that will be available from this page, but also stored with the navigation state. 221 | /// 222 | /// The async. 223 | /// The navigation service. 224 | /// The navigation arguments. 225 | /// Indicates whether the navigation should be animated. 226 | /// The destination page type. 227 | public static Task PushAsync(this INavigation navigation, object args = null, bool animated = true) where T : Page 228 | { 229 | return navigation.PushAsync(typeof(T),args,animated); 230 | } 231 | 232 | /// 233 | /// Instanciates a page from its type(must have an empty constructor) and navigates modaly to this page with an argument that will be available from this page, but also stored with the navigation state. 234 | /// 235 | /// The async. 236 | /// The navigation service. 237 | /// The navigation arguments. 238 | /// Indicates whether the navigation should be animated. 239 | /// The destination page type. 240 | public static Task PushModalAsync(this INavigation navigation, object args = null, bool animated = true) where T : Page 241 | { 242 | return navigation.PushAsync(typeof(T), args, animated); 243 | } 244 | 245 | #endregion 246 | 247 | #region Collection helpers 248 | 249 | /// 250 | /// Restores navigation state for each of the pages. 251 | /// 252 | /// The async. 253 | /// The pages. 254 | /// The base identifier of the stacks. 255 | /// The maximum time for navigation restoration. 256 | public static async Task RestoreAsync(this IList pages, string name, TimeSpan maximumRestoreSpan) 257 | { 258 | for (int i = 0; i < pages.Count(); i++) 259 | { 260 | var page = pages.ElementAt(i); 261 | await page.Navigation.RestoreAsync($"{name}.Tab[{i}]", maximumRestoreSpan); 262 | } 263 | } 264 | 265 | /// 266 | /// Stores navigation state for each of the pages. 267 | /// 268 | /// The pages. 269 | /// The base identifier of the stacks. 270 | public static void Store(this IList pages, string name) 271 | { 272 | for (int i = 0; i < pages.Count(); i++) 273 | { 274 | var page = pages.ElementAt(i); 275 | page.Navigation.Store($"{name}.Tab[{i}]"); 276 | } 277 | } 278 | 279 | #endregion 280 | } 281 | } -------------------------------------------------------------------------------- /Sources/Xamarin.Forms.NavigationExtensions.Shared/NavigationState.cs: -------------------------------------------------------------------------------- 1 | namespace Xamarin.Forms.NavigationExt 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | 6 | /// 7 | /// Represents a navigation state. 8 | /// 9 | public class NavigationStates 10 | { 11 | /// 12 | /// Gets or sets the store date. 13 | /// 14 | /// The date. 15 | public DateTime Date { get; set; } 16 | 17 | /// 18 | /// Gets or sets the all the stored navigation states (page and args). 19 | /// 20 | /// The navigation stack. 21 | public IEnumerable Navigation { get; set; } 22 | 23 | /// 24 | /// Gets or sets the all the stored modal navigation states (page and args). 25 | /// 26 | /// The modal stack. 27 | public IEnumerable Modal { get; set; } 28 | } 29 | } 30 | 31 | -------------------------------------------------------------------------------- /Sources/Xamarin.Forms.NavigationExtensions.Shared/PageState.cs: -------------------------------------------------------------------------------- 1 | namespace Xamarin.Forms.NavigationExt 2 | { 3 | using System; 4 | 5 | /// 6 | /// Represents a navigation state. 7 | /// 8 | public class PageState 9 | { 10 | /// 11 | /// Gets or sets the type of the page. 12 | /// 13 | /// The type of the page. 14 | public Type PageType { get; set; } 15 | 16 | /// 17 | /// Gets or sets the navigation argument. 18 | /// 19 | /// The argument. 20 | public object Argument { get; set; } 21 | } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /Sources/Xamarin.Forms.NavigationExtensions.Shared/Xamarin.Forms.NavigationExtensions.Shared.projitems: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 5 | true 6 | {CB546437-26A8-4F76-8607-A55F9A7CE079} 7 | 8 | 9 | Xamarin.Forms.NavigationExtensions.Shared 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /Sources/Xamarin.Forms.NavigationExtensions.Shared/Xamarin.Forms.NavigationExtensions.Shared.shproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {CB546437-26A8-4F76-8607-A55F9A7CE079} 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Sources/Xamarin.Forms.NavigationExtensions.Shared/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /Sources/Xamarin.Forms.NavigationExtensions.Standard/Xamarin.Forms.NavigationExtensions.Standard.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard1.3 5 | Xam.Forms.NavigationExtensions 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dotnet-ad/Xam.Forms.NavigationExtensions/78429b03f0649e1b9d80ab8540459cfea26e6e2c/icon.png --------------------------------------------------------------------------------