NavigationPageMvvmNavigation.cs 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. using System;
  2. using System.Threading.Tasks;
  3. using Avalonia.Controls;
  4. using MiniMvvm;
  5. namespace ControlCatalog.Pages
  6. {
  7. internal interface ISampleNavigationService
  8. {
  9. event EventHandler<NavigationStateChangedEventArgs>? StateChanged;
  10. Task NavigateToAsync(ViewModelBase viewModel);
  11. Task GoBackAsync();
  12. Task PopToRootAsync();
  13. }
  14. internal interface ISamplePageFactory
  15. {
  16. ContentPage CreatePage(ViewModelBase viewModel);
  17. }
  18. internal sealed class NavigationStateChangedEventArgs : EventArgs
  19. {
  20. public NavigationStateChangedEventArgs(string currentPageHeader, int navigationDepth, string lastAction)
  21. {
  22. CurrentPageHeader = currentPageHeader;
  23. NavigationDepth = navigationDepth;
  24. LastAction = lastAction;
  25. }
  26. public string CurrentPageHeader { get; }
  27. public int NavigationDepth { get; }
  28. public string LastAction { get; }
  29. }
  30. internal sealed class SampleNavigationService : ISampleNavigationService
  31. {
  32. private readonly NavigationPage _navigationPage;
  33. private readonly ISamplePageFactory _pageFactory;
  34. public SampleNavigationService(NavigationPage navigationPage, ISamplePageFactory pageFactory)
  35. {
  36. _navigationPage = navigationPage;
  37. _pageFactory = pageFactory;
  38. _navigationPage.Pushed += (_, e) => PublishState($"Pushed {e.Page?.Header}");
  39. _navigationPage.Popped += (_, e) => PublishState($"Popped {e.Page?.Header}");
  40. _navigationPage.PoppedToRoot += (_, _) => PublishState("Popped to root");
  41. }
  42. public event EventHandler<NavigationStateChangedEventArgs>? StateChanged;
  43. public async Task NavigateToAsync(ViewModelBase viewModel)
  44. {
  45. var page = _pageFactory.CreatePage(viewModel);
  46. await _navigationPage.PushAsync(page);
  47. }
  48. public async Task GoBackAsync()
  49. {
  50. if (_navigationPage.NavigationStack.Count <= 1)
  51. {
  52. PublishState("Already at the root page");
  53. return;
  54. }
  55. await _navigationPage.PopAsync();
  56. }
  57. public async Task PopToRootAsync()
  58. {
  59. if (_navigationPage.NavigationStack.Count <= 1)
  60. {
  61. PublishState("Already at the root page");
  62. return;
  63. }
  64. await _navigationPage.PopToRootAsync();
  65. }
  66. private void PublishState(string lastAction)
  67. {
  68. var header = _navigationPage.CurrentPage?.Header?.ToString() ?? "None";
  69. StateChanged?.Invoke(this, new NavigationStateChangedEventArgs(
  70. header,
  71. _navigationPage.NavigationStack.Count,
  72. lastAction));
  73. }
  74. }
  75. }