Skip to content

Commit 2d064a2

Browse files
authored
Merge pull request #33 from MADE-Apps/page-mvvm
PR for #31 - MvvmLight support for navigation
2 parents ee027e1 + 60d2fa3 commit 2d064a2

22 files changed

Lines changed: 478 additions & 46 deletions
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFrameworks>netstandard2.0;xamarin.ios10;monoandroid81;uap10.0.16299</TargetFrameworks>
5+
</PropertyGroup>
6+
7+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
8+
<DocumentationFile>bin\Debug\netstandard2.0\MADE.App.Views.Navigation.MvvmLight.xml</DocumentationFile>
9+
</PropertyGroup>
10+
11+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
12+
<DocumentationFile>bin\Release\netstandard2.0\MADE.App.Views.Navigation.MvvmLight.xml</DocumentationFile>
13+
</PropertyGroup>
14+
15+
<ItemGroup>
16+
<Compile Remove="api\**" />
17+
<Compile Remove="articles\**" />
18+
<Compile Remove="_site\**" />
19+
<EmbeddedResource Remove="api\**" />
20+
<EmbeddedResource Remove="articles\**" />
21+
<EmbeddedResource Remove="_site\**" />
22+
<None Remove="api\**" />
23+
<None Remove="articles\**" />
24+
<None Remove="_site\**" />
25+
</ItemGroup>
26+
27+
<PropertyGroup>
28+
<LogFile>Docfx-$(TargetFramework).log</LogFile>
29+
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
30+
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
31+
<Version>1.0.0.0</Version>
32+
<Authors>MADE Apps</Authors>
33+
<Company>MADE Apps</Company>
34+
<Product>MADE App View Navigation MvvmLight Library</Product>
35+
<Description>Making App Development Easier with a collection of easy to use components for building MVVM friendly page to page navigation for .NET projects using MvvmLight across Windows, Android, and iOS.</Description>
36+
<Copyright>Copyright (C) MADE Apps. All rights reserved.</Copyright>
37+
<PackageLicenseUrl>https://github.com/MADE-Apps/MADE-App-Components/blob/master/LICENSE</PackageLicenseUrl>
38+
<PackageProjectUrl>https://github.com/MADE-Apps/MADE-App-Components</PackageProjectUrl>
39+
<RepositoryUrl>https://github.com/MADE-Apps/MADE-App-Components</RepositoryUrl>
40+
<RepositoryType>git</RepositoryType>
41+
<PackageIconUrl>https://pbs.twimg.com/profile_images/927154020422160385/6HSRU36P_400x400.jpg</PackageIconUrl>
42+
<PackageTags>MADE App Development MvvmLight Mvvm View Navigation Service Frame Windows Android iOS Xamarin</PackageTags>
43+
<RootNamespace>MADE.App.Views.Navigation</RootNamespace>
44+
</PropertyGroup>
45+
46+
<ItemGroup>
47+
<None Remove=".gitignore" />
48+
<None Remove="docfx.json" />
49+
<None Remove="index.md" />
50+
<None Remove="log.txt" />
51+
<None Remove="toc.yml" />
52+
<None Remove="Docfx-*.log" />
53+
</ItemGroup>
54+
55+
<ItemGroup>
56+
<PackageReference Include="CommonServiceLocator" Version="2.0.3" />
57+
<PackageReference Include="docfx.console" Version="2.36.0" PrivateAssets="All" />
58+
<PackageReference Include="MSBuild.Sdk.Extras" Version="1.5.4" PrivateAssets="All" />
59+
<PackageReference Include="MvvmLightLibs" Version="5.4.1" />
60+
</ItemGroup>
61+
62+
<ItemGroup Condition=" '$(TargetFramework)' == 'monoandroid81' ">
63+
<PackageReference Include="Xamarin.Android.Support.Fragment" Version="27.0.2" />
64+
<PackageReference Include="Xamarin.Android.Support.v7.AppCompat" Version="27.0.2" />
65+
</ItemGroup>
66+
67+
<ItemGroup Condition=" '$(TargetFramework)' == 'uap10.0.16299' ">
68+
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform" Version="6.1.4" />
69+
</ItemGroup>
70+
71+
<ItemGroup>
72+
<ProjectReference Include="..\MADE.App.Views.Navigation\MADE.App.Views.Navigation.csproj" />
73+
</ItemGroup>
74+
75+
<Import Project="$(MSBuildSDKExtrasTargets)" Condition="Exists('$(MSBuildSDKExtrasTargets)')" />
76+
</Project>
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
#if WINDOWS_UWP || __ANDROID__
2+
namespace MADE.App.Views.Navigation.Pages
3+
{
4+
using MADE.App.Views.Navigation.ViewModels;
5+
6+
/// <summary>
7+
/// Defines an MVVM friendly page that is compatible with MvvmLight and the application NavigationFrame.
8+
/// </summary>
9+
public class MvvmPage : Page
10+
{
11+
/// <summary>
12+
/// Called when the page has loaded.
13+
/// </summary>
14+
public override void OnPageLoaded()
15+
{
16+
base.OnPageLoaded();
17+
18+
if (this.DataContext is PageViewModel vm)
19+
{
20+
vm.OnPageLoaded();
21+
}
22+
}
23+
24+
/// <summary>
25+
/// Called when the page has been navigated from.
26+
/// </summary>
27+
/// <param name="e">
28+
/// The navigation event argument for the navigation.
29+
/// </param>
30+
public override void OnNavigatedFrom(NavigationEventArgs e)
31+
{
32+
base.OnNavigatedFrom(e);
33+
34+
if (this.DataContext is PageViewModel vm)
35+
{
36+
vm.OnNavigatedFrom(e);
37+
}
38+
}
39+
40+
/// <summary>
41+
/// Called when the page has been navigated to.
42+
/// </summary>
43+
/// <param name="e">
44+
/// The navigation event argument for the navigation.
45+
/// </param>
46+
public override void OnNavigatedTo(NavigationEventArgs e)
47+
{
48+
base.OnNavigatedTo(e);
49+
50+
if (this.DataContext is PageViewModel vm)
51+
{
52+
vm.OnNavigatedTo(e);
53+
}
54+
}
55+
56+
/// <summary>
57+
/// Called when the page is being navigated from.
58+
/// </summary>
59+
/// <param name="e">
60+
/// The navigation event argument for the navigation supporting the cancellation of the navigation.
61+
/// </param>
62+
public override void OnNavigatingFrom(NavigatingCancelEventArgs e)
63+
{
64+
base.OnNavigatingFrom(e);
65+
66+
if (this.DataContext is PageViewModel vm)
67+
{
68+
vm.OnNavigatingFrom(e);
69+
}
70+
}
71+
}
72+
}
73+
#endif
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
// --------------------------------------------------------------------------------------------------------------------
2+
// <copyright file="PageViewModel.cs" company="MADE Apps">
3+
// Copyright (c) MADE Apps.
4+
// </copyright>
5+
// <summary>
6+
// Defines a view-model for a MADE page.
7+
// </summary>
8+
// --------------------------------------------------------------------------------------------------------------------
9+
10+
namespace MADE.App.Views.Navigation.ViewModels
11+
{
12+
using CommonServiceLocator;
13+
14+
using GalaSoft.MvvmLight;
15+
using GalaSoft.MvvmLight.Ioc;
16+
using GalaSoft.MvvmLight.Messaging;
17+
18+
/// <summary>
19+
/// Defines a view-model for a MADE page.
20+
/// </summary>
21+
public class PageViewModel : ViewModelBase
22+
{
23+
/// <summary>
24+
/// Initializes a new instance of the <see cref="PageViewModel"/> class.
25+
/// </summary>
26+
public PageViewModel()
27+
: this(ServiceLocator.Current.GetInstance<IMessenger>())
28+
{
29+
30+
}
31+
32+
/// <summary>
33+
/// Initializes a new instance of the <see cref="PageViewModel"/> class.
34+
/// </summary>
35+
/// <param name="messenger">
36+
/// The MVVM message aggregator.
37+
/// </param>
38+
[PreferredConstructor]
39+
public PageViewModel(IMessenger messenger)
40+
{
41+
this.MessengerInstance = messenger;
42+
}
43+
44+
/// <summary>
45+
/// Called when the page has loaded.
46+
/// </summary>
47+
public virtual void OnPageLoaded()
48+
{
49+
}
50+
51+
/// <summary>
52+
/// Called when the page has been navigated from.
53+
/// </summary>
54+
/// <param name="e">
55+
/// The navigation event argument for the navigation.
56+
/// </param>
57+
public virtual void OnNavigatedFrom(NavigationEventArgs e)
58+
{
59+
}
60+
61+
/// <summary>
62+
/// Called when the page has been navigated to.
63+
/// </summary>
64+
/// <param name="e">
65+
/// The navigation event argument for the navigation.
66+
/// </param>
67+
public virtual void OnNavigatedTo(NavigationEventArgs e)
68+
{
69+
}
70+
71+
/// <summary>
72+
/// Called when the page is being navigated from.
73+
/// </summary>
74+
/// <param name="e">
75+
/// The navigation event argument for the navigation supporting the cancellation of the navigation.
76+
/// </param>
77+
public virtual void OnNavigatingFrom(NavigatingCancelEventArgs e)
78+
{
79+
}
80+
}
81+
}

MADE.App.Views.Navigation/NavigationFrame.Android.cs

Lines changed: 22 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ namespace MADE.App.Views.Navigation
88
using Android.Support.V4.App;
99
using Android.Support.V7.App;
1010

11+
using MADE.App.Views.Navigation.Pages;
12+
1113
/// <summary>
1214
/// Defines a frame for navigating and displaying page content.
1315
/// </summary>
@@ -82,25 +84,21 @@ public void GoBack()
8284
return;
8385
}
8486

85-
if (!this.CanNavigateAway())
87+
NavigationEventArgs previousPageEvent = this.GetNavigationEvent(this.BackStackDepth - 1);
88+
if (previousPageEvent == null)
8689
{
90+
// ToDo, if there is no page event, we are at the end of the stack. Should exit app.
8791
return;
8892
}
8993

90-
NavigationEventArgs currentPageEvent = this.GetNavigationEvent(this.BackStackDepth);
91-
if (currentPageEvent != null)
92-
{
93-
currentPageEvent.NavigationMode = NavigationMode.Back;
94-
}
94+
previousPageEvent.NavigationMode = NavigationMode.Back;
9595

96-
NavigationEventArgs previousPageEvent = this.GetNavigationEvent(this.BackStackDepth - 1);
97-
if (previousPageEvent != null)
96+
if (!this.CanNavigateAway(previousPageEvent))
9897
{
99-
previousPageEvent.NavigationMode = NavigationMode.Back;
98+
return;
10099
}
101100

102101
this.HandleNavigation(
103-
currentPageEvent,
104102
previousPageEvent,
105103
() =>
106104
{
@@ -137,11 +135,6 @@ public bool Navigate(Type sourcePageType)
137135
/// </returns>
138136
public bool Navigate(Type sourcePageType, object parameter)
139137
{
140-
if (!this.CanNavigateAway())
141-
{
142-
return false;
143-
}
144-
145138
if (!(Activator.CreateInstance(sourcePageType) is Page page))
146139
{
147140
return false;
@@ -154,6 +147,11 @@ public bool Navigate(Type sourcePageType, object parameter)
154147
SourcePageType = sourcePageType
155148
};
156149

150+
if (!this.CanNavigateAway(navArgs))
151+
{
152+
return false;
153+
}
154+
157155
this.HandleNavigation(
158156
navArgs,
159157
() =>
@@ -193,26 +191,18 @@ protected override void OnCreate(Bundle savedInstanceState)
193191
}
194192

195193
private void HandleNavigation(NavigationEventArgs navArgs, Action navigationAction)
196-
{
197-
this.HandleNavigation(navArgs, navArgs, navigationAction);
198-
}
199-
200-
private void HandleNavigation(
201-
NavigationEventArgs previousNavArgs,
202-
NavigationEventArgs newNavArgs,
203-
Action navigationAction)
204194
{
205195
IPage previousPage = this.currentPage;
206-
previousPage?.OnNavigatedFrom(previousNavArgs);
196+
previousPage?.OnNavigatedFrom(navArgs);
207197

208198
navigationAction?.Invoke();
209199

210200
this.currentPage = this.SupportFragmentManager.GetCurrentFragment() as Page;
211201
if (this.currentPage != null)
212202
{
213-
this.currentPage.OnNavigatedTo(newNavArgs);
214-
this.CurrentSourcePageParameter = newNavArgs.Parameter;
215-
this.PageNavigated?.Invoke(this, newNavArgs);
203+
this.currentPage.OnNavigatedTo(navArgs);
204+
this.CurrentSourcePageParameter = navArgs.Parameter;
205+
this.PageNavigated?.Invoke(this, navArgs);
216206
}
217207
}
218208

@@ -239,7 +229,7 @@ private void RemoveNavigationEvent(int key)
239229
}
240230
}
241231

242-
private bool CanNavigateAway()
232+
private bool CanNavigateAway(NavigationEventArgs args)
243233
{
244234
IPage previousPage = this.currentPage;
245235

@@ -248,9 +238,10 @@ private bool CanNavigateAway()
248238
NavigatingCancelEventArgs navArgs =
249239
new NavigatingCancelEventArgs(() => shouldCancel = true)
250240
{
251-
SourcePageType = previousPage?.GetType(),
252-
NavigationMode = NavigationMode.Back
253-
};
241+
SourcePageType = args.SourcePageType,
242+
NavigationMode = args.NavigationMode,
243+
Parameter = args.Parameter
244+
};
254245

255246
previousPage?.OnNavigatingFrom(navArgs);
256247

MADE.App.Views.Navigation/IAndroidPage.cs renamed to MADE.App.Views.Navigation/Pages/IAndroidPage.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#if __ANDROID__
2-
namespace MADE.App.Views.Navigation
2+
namespace MADE.App.Views.Navigation.Pages
33
{
44
using Android.Views;
55

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
// </summary>
88
// --------------------------------------------------------------------------------------------------------------------
99

10-
namespace MADE.App.Views.Navigation
10+
namespace MADE.App.Views.Navigation.Pages
1111
{
1212
/// <summary>
1313
/// Defines an interface for an application page.

MADE.App.Views.Navigation/Page.Android.cs renamed to MADE.App.Views.Navigation/Pages/Page.Android.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#if __ANDROID__
2-
namespace MADE.App.Views.Navigation
2+
namespace MADE.App.Views.Navigation.Pages
33
{
44
using Android.OS;
55
using Android.Support.V4.App;

MADE.App.Views.Navigation/Page.Windows.cs renamed to MADE.App.Views.Navigation/Pages/Page.Windows.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#if WINDOWS_UWP
2-
namespace MADE.App.Views.Navigation
2+
namespace MADE.App.Views.Navigation.Pages
33
{
44
using Windows.ApplicationModel;
55

0 commit comments

Comments
 (0)