Moved to a more simple navigation strategy, instead of MessagingCenter-based navigation.
This commit is contained in:
Родитель
373a095e1b
Коммит
7c3306e2df
|
@ -11,7 +11,7 @@ namespace Customers
|
|||
|
||||
SubscribeToDisplayAlertMessages();
|
||||
|
||||
SubscribeToNavigationMessages();
|
||||
// SubscribeToNavigationMessages();
|
||||
|
||||
if (Device.OS == TargetPlatform.iOS)
|
||||
navPage.BarTextColor = Color.White;
|
||||
|
@ -53,15 +53,15 @@ namespace Customers
|
|||
/// <summary>
|
||||
/// Subscribes to messages for navigation.
|
||||
/// </summary>
|
||||
static void SubscribeToNavigationMessages()
|
||||
{
|
||||
MessagingService.Current.Subscribe(MessageKeys.PopAsync, async (service) =>
|
||||
{
|
||||
var task = Application.Current?.MainPage?.Navigation?.PopAsync();
|
||||
if (task != null)
|
||||
await task;
|
||||
});
|
||||
}
|
||||
// static void SubscribeToNavigationMessages()
|
||||
// {
|
||||
// MessagingService.Current.Subscribe(MessageKeys.PopAsync, async (service) =>
|
||||
// {
|
||||
// var task = Application.Current?.MainPage?.Navigation?.PopAsync();
|
||||
// if (task != null)
|
||||
// await task;
|
||||
// });
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,9 +6,6 @@ namespace Customers
|
|||
{
|
||||
public const string DisplayAlert = "DisplayAlert";
|
||||
public const string DisplayQuestion = "DisplayQuestion";
|
||||
public const string NavigateToDetailPage = "NavigateToDetail";
|
||||
public const string NavigateToEditPage = "NavigateToEdit";
|
||||
public const string PopAsync = "PopAsync";
|
||||
public const string SaveCustomer = "SaveCustomer";
|
||||
public const string DeleteCustomer = "DeleteCustomer";
|
||||
public const string CustomerLocationUpdated = "CustomerLocationUpdated";
|
||||
|
|
|
@ -57,6 +57,7 @@
|
|||
<Compile Include="Data\ILocalization.cs" />
|
||||
<Compile Include="Extensions\IntExtensions.cs" />
|
||||
<Compile Include="Constants\MessageKeys.cs" />
|
||||
<Compile Include="ViewModels\NavigationAwareBaseViewModel.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
|
||||
<Import Project="..\packages\Xamarin.Forms.2.0.0.6490\build\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+MonoTouch10+Xamarin.iOS10\Xamarin.Forms.targets" Condition="Exists('..\packages\Xamarin.Forms.2.0.0.6490\build\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+MonoTouch10+Xamarin.iOS10\Xamarin.Forms.targets')" />
|
||||
|
|
|
@ -23,24 +23,12 @@ namespace Customers
|
|||
{
|
||||
base.OnAppearing();
|
||||
|
||||
// subscribe to NavigateToEditPage messages
|
||||
MessagingService.Current.Subscribe<CustomerDetailViewModel>(MessageKeys.NavigateToEditPage, async (service, viewmodel) =>
|
||||
await Navigation.PushAsync(new CustomerEditPage() { BindingContext = ViewModel }));
|
||||
|
||||
// Typically, is preferable to call into the viewmodel for OnAppearing() logic to be performed,
|
||||
// but we're not doing that in this case because we need to interact with the Xamarin.Forms.Map property on this Page.
|
||||
// In the future, the Map type and it's properties may get more binding support, so that the map setup can be omitted from code-behind.
|
||||
await SetupMap();
|
||||
}
|
||||
|
||||
protected override void OnDisappearing()
|
||||
{
|
||||
base.OnDisappearing();
|
||||
|
||||
// unsubscribe from NavigateToEditPage messages
|
||||
MessagingService.Current.Unsubscribe<CustomerDetailViewModel>(MessageKeys.NavigateToEditPage);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets up the map.
|
||||
/// </summary>
|
||||
|
|
|
@ -18,6 +18,11 @@ namespace Customers
|
|||
Title = null; // because iOS already displays the previous page's title with the back button, we don't want to display it twice.
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensures the state field has 2 characters at most.
|
||||
/// </summary>
|
||||
/// <param name="sender">The sender.</param>
|
||||
/// <param name="e">The PropertyChangedEventArgs</param>
|
||||
void StateEntry_PropertyChanged (object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.PropertyName == "Text")
|
||||
|
@ -35,6 +40,11 @@ namespace Customers
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensures the zip code field has 5 characters at most.
|
||||
/// </summary>
|
||||
/// <param name="sender">The sender.</param>
|
||||
/// <param name="e">The PropertyChangedEventArgs</param>
|
||||
void PostalCode_PropertyChanged (object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.PropertyName == "Text")
|
||||
|
|
|
@ -22,18 +22,26 @@ namespace Customers
|
|||
fab.Clicked = AndroidAddButtonClicked;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The action to take when a list item is tapped.
|
||||
/// </summary>
|
||||
/// <param name="sender"> The sender.</param>
|
||||
/// <param name="e">The ItemTappedEventArgs</param>
|
||||
void ItemTapped (object sender, ItemTappedEventArgs e)
|
||||
{
|
||||
// send message to navigate to detail page
|
||||
MessagingService.Current.SendMessage<CustomerDetailViewModel>(MessageKeys.NavigateToDetailPage, new CustomerDetailViewModel((Customer)e.Item));
|
||||
Navigation.PushAsync(new CustomerDetailPage() { BindingContext = new CustomerDetailViewModel((Customer)e.Item) });
|
||||
|
||||
((ListView)sender).SelectedItem = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The action to take when the + button is clicked on Android.
|
||||
/// </summary>
|
||||
/// <param name="sender">The sender.</param>
|
||||
/// <param name="e">The EventArgs</param>
|
||||
void AndroidAddButtonClicked (object sender, EventArgs e)
|
||||
{
|
||||
// send message to navigate to edit page (new customer)
|
||||
MessagingService.Current.SendMessage(MessageKeys.NavigateToEditPage);
|
||||
Navigation.PushAsync(new CustomerEditPage() { BindingContext = new CustomerDetailViewModel(new Customer()) });
|
||||
}
|
||||
|
||||
protected override void OnAppearing()
|
||||
|
@ -41,32 +49,6 @@ namespace Customers
|
|||
base.OnAppearing();
|
||||
|
||||
ViewModel.LoadCustomersCommand.Execute(null);
|
||||
|
||||
// subscribe to messages to navigate to detail page
|
||||
MessagingService.Current.Subscribe<CustomerDetailViewModel>(MessageKeys.NavigateToDetailPage, async (service, viewmodel) =>
|
||||
await Navigation.PushAsync(new CustomerDetailPage() { BindingContext = viewmodel }));
|
||||
|
||||
// subscribe to messages to navigate to edit page (new customer)
|
||||
MessagingService.Current.Subscribe(MessageKeys.NavigateToEditPage, async (service) =>
|
||||
await Navigation.PushAsync(new CustomerEditPage() { BindingContext = new CustomerDetailViewModel(new Customer()) }));
|
||||
|
||||
// subscribe to messages to navigate to edit page (existing customer)
|
||||
MessagingService.Current.Subscribe<CustomerDetailViewModel>(MessageKeys.NavigateToEditPage, async (service, viewmodel) =>
|
||||
await Navigation.PushAsync(new CustomerEditPage() { BindingContext = viewmodel }));
|
||||
}
|
||||
|
||||
protected override void OnDisappearing()
|
||||
{
|
||||
base.OnDisappearing();
|
||||
|
||||
// unsubscribe from messages to navigate to detail page
|
||||
MessagingService.Current.Unsubscribe<CustomerDetailViewModel>(MessageKeys.NavigateToDetailPage);
|
||||
|
||||
// unsubscribe from messages to navigate to edit page (new customer)
|
||||
MessagingService.Current.Unsubscribe(MessageKeys.NavigateToEditPage);
|
||||
|
||||
// unsubscribe from messages to navigate to edit page (existing customer)
|
||||
MessagingService.Current.Unsubscribe<CustomerDetailViewModel>(MessageKeys.NavigateToEditPage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ using FormsToolkit;
|
|||
|
||||
namespace Customers
|
||||
{
|
||||
public class CustomerDetailViewModel : BaseViewModel
|
||||
public class CustomerDetailViewModel : NavigationAwareBaseViewModel
|
||||
{
|
||||
bool _IsNewCustomer;
|
||||
|
||||
|
@ -78,11 +78,11 @@ namespace Customers
|
|||
get
|
||||
{
|
||||
return _SaveCustomerCommand ??
|
||||
(_SaveCustomerCommand = new Command(ExecuteSaveCustomerCommand));
|
||||
(_SaveCustomerCommand = new Command(() => ExecuteSaveCustomerCommand()));
|
||||
}
|
||||
}
|
||||
|
||||
void ExecuteSaveCustomerCommand()
|
||||
async Task ExecuteSaveCustomerCommand()
|
||||
{
|
||||
if (String.IsNullOrWhiteSpace(Customer.LastName) || String.IsNullOrWhiteSpace(Customer.FirstName))
|
||||
{
|
||||
|
@ -104,11 +104,9 @@ namespace Customers
|
|||
}
|
||||
else
|
||||
{
|
||||
// send a message that we want the given customer to be saved
|
||||
MessagingService.Current.SendMessage<Customer>(MessageKeys.SaveCustomer, this.Customer);
|
||||
|
||||
// perform a pop in order to navigate back to the customer list
|
||||
MessagingService.Current.SendMessage(MessageKeys.PopAsync);
|
||||
await PopAsync();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -143,13 +141,13 @@ namespace Customers
|
|||
get
|
||||
{
|
||||
return _EditCustomerCommand ??
|
||||
(_EditCustomerCommand = new Command(ExecuteEditCustomerCommand));
|
||||
(_EditCustomerCommand = new Command(async () => await ExecuteEditCustomerCommand()));
|
||||
}
|
||||
}
|
||||
|
||||
void ExecuteEditCustomerCommand()
|
||||
async Task ExecuteEditCustomerCommand()
|
||||
{
|
||||
MessagingService.Current.SendMessage<CustomerDetailViewModel>(MessageKeys.NavigateToEditPage, this);
|
||||
await PushAsync(new CustomerEditPage() { BindingContext = this });
|
||||
}
|
||||
|
||||
|
||||
|
@ -163,7 +161,7 @@ namespace Customers
|
|||
get
|
||||
{
|
||||
return _DeleteCustomerCommand ??
|
||||
(_DeleteCustomerCommand = new Command(ExecuteDeleteCustomerCommand));
|
||||
(_DeleteCustomerCommand = new Command(ExecuteDeleteCustomerCommand));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -175,16 +173,16 @@ namespace Customers
|
|||
Question = null,
|
||||
Positive = "Delete",
|
||||
Negative = "Cancel",
|
||||
OnCompleted = new Action<bool>(result =>
|
||||
OnCompleted = new Action<bool>(async result =>
|
||||
{
|
||||
if (result)
|
||||
{
|
||||
await PopAsync(false);
|
||||
|
||||
await PopAsync();
|
||||
|
||||
// send a message that we want the given customer to be deleted
|
||||
MessagingService.Current.SendMessage<Customer>(MessageKeys.DeleteCustomer, this.Customer);
|
||||
|
||||
MessagingService.Current.SendMessage(MessageKeys.PopAsync);
|
||||
|
||||
MessagingService.Current.SendMessage(MessageKeys.PopAsync);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
|
|
@ -9,7 +9,7 @@ using FormsToolkit;
|
|||
|
||||
namespace Customers
|
||||
{
|
||||
public class CustomerListViewModel : BaseViewModel
|
||||
public class CustomerListViewModel : NavigationAwareBaseViewModel
|
||||
{
|
||||
public CustomerListViewModel()
|
||||
{
|
||||
|
@ -98,14 +98,13 @@ namespace Customers
|
|||
get
|
||||
{
|
||||
return _NewCustomerCommand ??
|
||||
(_NewCustomerCommand = new Command(ExecuteNewCustomerCommand));
|
||||
(_NewCustomerCommand = new Command(async () => await ExecuteNewCustomerCommand()));
|
||||
}
|
||||
}
|
||||
|
||||
void ExecuteNewCustomerCommand()
|
||||
async Task ExecuteNewCustomerCommand()
|
||||
{
|
||||
// send message to navigate to edit page (new customer)
|
||||
MessagingService.Current.SendMessage(MessageKeys.NavigateToEditPage, new CustomerDetailViewModel(new Customer()));
|
||||
await PushAsync(new CustomerEditPage() { BindingContext = new CustomerDetailViewModel(new Customer()) });
|
||||
}
|
||||
|
||||
Command _DialNumberCommand;
|
||||
|
|
|
@ -0,0 +1,113 @@
|
|||
using System;
|
||||
using MvvmHelpers;
|
||||
using Xamarin.Forms;
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Customers
|
||||
{
|
||||
/// <summary>
|
||||
/// Implements the INavigation interface on top of BaseViewModel.
|
||||
/// </summary>
|
||||
public abstract class NavigationAwareBaseViewModel : BaseViewModel, INavigation
|
||||
{
|
||||
readonly INavigation _Navigation;
|
||||
|
||||
protected NavigationAwareBaseViewModel()
|
||||
{
|
||||
// If Navigation is available on Application.Current.MainPage, get it.
|
||||
_Navigation = Application.Current?.MainPage?.Navigation;
|
||||
}
|
||||
|
||||
#region INavigation implementation
|
||||
|
||||
public void RemovePage(Page page)
|
||||
{
|
||||
_Navigation?.RemovePage(page);
|
||||
}
|
||||
|
||||
public void InsertPageBefore(Page page, Page before)
|
||||
{
|
||||
_Navigation?.InsertPageBefore(page, before);
|
||||
}
|
||||
|
||||
public async Task PushAsync(Page page)
|
||||
{
|
||||
var task = _Navigation?.PushAsync(page);
|
||||
if (task != null)
|
||||
await task;
|
||||
}
|
||||
|
||||
public async Task<Page> PopAsync()
|
||||
{
|
||||
var task = _Navigation?.PopAsync();
|
||||
return task != null ? await task : await Task.FromResult(null as Page);
|
||||
}
|
||||
|
||||
public async Task PopToRootAsync()
|
||||
{
|
||||
var task = _Navigation?.PopToRootAsync();
|
||||
if (task != null)
|
||||
await task;
|
||||
}
|
||||
|
||||
public async Task PushModalAsync(Page page)
|
||||
{
|
||||
var task = _Navigation?.PushModalAsync(page);
|
||||
if (task != null)
|
||||
await task;
|
||||
}
|
||||
|
||||
public async Task<Page> PopModalAsync()
|
||||
{
|
||||
var task = _Navigation?.PopModalAsync();
|
||||
return (task != null) ? await task : await Task.FromResult(null as Page);
|
||||
}
|
||||
|
||||
public async Task PushAsync(Page page, bool animated)
|
||||
{
|
||||
var task = _Navigation?.PushAsync(page, animated);
|
||||
if (task != null)
|
||||
await task;
|
||||
}
|
||||
|
||||
public async Task<Page> PopAsync(bool animated)
|
||||
{
|
||||
var task = _Navigation?.PopAsync(animated);
|
||||
return (task != null) ? await task : await Task.FromResult(null as Page);
|
||||
}
|
||||
|
||||
public async Task PopToRootAsync(bool animated)
|
||||
{
|
||||
var task = _Navigation?.PopToRootAsync(animated);
|
||||
if (task != null)
|
||||
await task;
|
||||
}
|
||||
|
||||
public async Task PushModalAsync(Page page, bool animated)
|
||||
{
|
||||
var task = _Navigation?.PushModalAsync(page, animated);
|
||||
if (task != null)
|
||||
await task;
|
||||
}
|
||||
|
||||
public async Task<Page> PopModalAsync(bool animated)
|
||||
{
|
||||
var task = _Navigation?.PopModalAsync(animated);
|
||||
return (task != null) ? await task : await Task.FromResult(null as Page);
|
||||
}
|
||||
|
||||
public IReadOnlyList<Page> NavigationStack
|
||||
{
|
||||
get { return _Navigation?.NavigationStack; }
|
||||
}
|
||||
|
||||
public IReadOnlyList<Page> ModalStack
|
||||
{
|
||||
get { return _Navigation?.ModalStack; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
Загрузка…
Ссылка в новой задаче