Viewmodels are now maintained throughout the app lifecycle

This commit is contained in:
watsonb8 2019-07-15 15:03:59 -04:00
parent 00b39b1d84
commit a3937e78da
9 changed files with 70 additions and 15 deletions

View File

@ -17,5 +17,7 @@ namespace Aurora.Design.Components.NavigationMenu
public string Group { get; set; } public string Group { get; set; }
public Type TargetType { get; set; } public Type TargetType { get; set; }
public Type TargetViewModelType { get; set; }
} }
} }

View File

@ -1,7 +1,7 @@
using System; using System;
namespace Aurora.Design.Views.Artists namespace Aurora.Design.Views.Artists
{ {
public class ArtistsViewModel public class ArtistsViewModel : BaseViewModel
{ {
public ArtistsViewModel() public ArtistsViewModel()
{ {

View File

@ -1,6 +1,7 @@
using System; using System;
using System.ComponentModel; using System.ComponentModel;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Threading.Tasks;
namespace Aurora.Design.Views namespace Aurora.Design.Views
{ {
@ -10,6 +11,13 @@ namespace Aurora.Design.Views
{ {
} }
#region Lifecycle
public virtual void OnActive() { }
public virtual void OnInactive() { }
#endregion
#region INotifyPropertyChanged Implementation #region INotifyPropertyChanged Implementation
public bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null) public bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
{ {

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using Aurora.Design.Components.NavigationMenu; using Aurora.Design.Components.NavigationMenu;
using Aurora.Design.Views.MainView; using Aurora.Design.Views.MainView;
@ -11,10 +12,14 @@ namespace Aurora.Design.Views.Main
[XamlCompilation(XamlCompilationOptions.Compile)] [XamlCompilation(XamlCompilationOptions.Compile)]
public partial class MainView : MasterDetailPage public partial class MainView : MasterDetailPage
{ {
private Dictionary<int, BaseViewModel> _viewModels;
private BaseViewModel _lastViewModel;
public MainView() public MainView()
{ {
InitializeComponent(); InitializeComponent();
BindingContext = new MainViewModel(); BindingContext = new MainViewModel();
_viewModels = new Dictionary<int, BaseViewModel>();
MasterPage.ListView.ItemSelected += ListView_ItemSelected; MasterPage.ListView.ItemSelected += ListView_ItemSelected;
Appearing += OnAppearing; Appearing += OnAppearing;
@ -32,6 +37,33 @@ namespace Aurora.Design.Views.Main
var view = (View)Activator.CreateInstance(item.TargetType); var view = (View)Activator.CreateInstance(item.TargetType);
//Check if we have an instantiated viewModel
BaseViewModel vm = new BaseViewModel();
if (_viewModels.ContainsKey(item.Id))
{
_viewModels.TryGetValue(item.Id, out vm);
}
else
{
if (item.TargetViewModelType.BaseType != typeof(BaseViewModel))
{
throw new InvalidOperationException("TargetViewModel field must be of type BaseViewModel");
}
//Instantiate new view model
vm = (BaseViewModel)Activator.CreateInstance(item.TargetViewModelType);
_viewModels.Add(item.Id, vm);
}
//Activate viewmodel
vm.OnActive();
//Deactivate last viewModel
_lastViewModel.OnInactive();
//Assign viewModel
_lastViewModel = vm;
view.BindingContext = vm;
ContentPresenter viewContent = (ContentPresenter)ContentPage.Content.FindByName("ViewContent"); ContentPresenter viewContent = (ContentPresenter)ContentPage.Content.FindByName("ViewContent");
viewContent.Content = view; viewContent.Content = view;
@ -47,7 +79,26 @@ namespace Aurora.Design.Views.Main
{ {
//Set initial view from first item in list //Set initial view from first item in list
ObservableCollection<NavigationGroupItem> screenList = (ObservableCollection<NavigationGroupItem>)MasterPage.ListView.ItemsSource; ObservableCollection<NavigationGroupItem> screenList = (ObservableCollection<NavigationGroupItem>)MasterPage.ListView.ItemsSource;
var view = (View)Activator.CreateInstance(screenList.FirstOrDefault().FirstOrDefault().TargetType);
//Assign viewModel
NavigationItem firstNavItem = screenList.FirstOrDefault().FirstOrDefault();
var view = (View)Activator.CreateInstance(firstNavItem.TargetType);
BaseViewModel vm = new BaseViewModel();
if (_viewModels.ContainsKey(firstNavItem.Id))
{
_viewModels.TryGetValue(firstNavItem.Id, out vm);
}
else
{
//Instantiate new view model
vm = (BaseViewModel)Activator.CreateInstance(firstNavItem.TargetViewModelType);
_viewModels.Add(firstNavItem.Id, vm);
}
view.BindingContext = vm;
_lastViewModel = vm;
vm.OnActive();
ContentPresenter viewContent = (ContentPresenter)ContentPage.Content.FindByName("ViewContent"); ContentPresenter viewContent = (ContentPresenter)ContentPage.Content.FindByName("ViewContent");
viewContent.Content = view; viewContent.Content = view;

View File

@ -32,12 +32,12 @@ namespace Aurora.Design.Views.MainView
{ {
_pages = new ObservableCollection<NavigationItem>(new[] _pages = new ObservableCollection<NavigationItem>(new[]
{ {
new NavigationItem { Id = 4, Title = "Party", Group="Social", TargetType = typeof(PartyView)}, new NavigationItem { Id = 0, Title = "Songs", Group="Library", TargetType = typeof(SongsView), TargetViewModelType = typeof(SongsViewModel) },
new NavigationItem { Id = 5, Title = "Profile", Group="Social", TargetType = typeof(ProfileView)}, new NavigationItem { Id = 1, Title = "Artists", Group="Library", TargetType = typeof(ArtistsView), TargetViewModelType = typeof(ArtistsViewModel)},
new NavigationItem { Id = 0, Title = "Songs", Group="Library", TargetType = typeof(SongsView) }, new NavigationItem { Id = 2, Title = "Albums", Group="Library", TargetType = typeof(AlbumsView), TargetViewModelType = typeof(AlbumsViewModel)},
new NavigationItem { Id = 1, Title = "Artists", Group="Library", TargetType = typeof(ArtistsView)}, new NavigationItem { Id = 3, Title = "Stations", Group="Library", TargetType = typeof(StationsView), TargetViewModelType = typeof(StationsViewModel)},
new NavigationItem { Id = 2, Title = "Albums", Group="Library", TargetType = typeof(AlbumsView)}, new NavigationItem { Id = 4, Title = "Party", Group="Social", TargetType = typeof(PartyView), TargetViewModelType = typeof(PartyViewModel)},
new NavigationItem { Id = 3, Title = "Stations", Group="Library", TargetType = typeof(StationsView)}, new NavigationItem { Id = 5, Title = "Profile", Group="Social", TargetType = typeof(ProfileView), TargetViewModelType = typeof(ProfileViewModel)},
}); });
} }

View File

@ -8,7 +8,6 @@ namespace Aurora.Design.Views.Party
public PartyView() public PartyView()
{ {
InitializeComponent(); InitializeComponent();
BindingContext = new PartyViewModel();
} }
} }
} }

View File

@ -9,7 +9,6 @@ namespace Aurora.Design.Views.Profile
public ProfileView() public ProfileView()
{ {
InitializeComponent(); InitializeComponent();
BindingContext = new ProfileViewModel();
} }
} }
} }

View File

@ -5,10 +5,6 @@
xmlns:songs="clr-namespace:Aurora.Design.Views.Songs" xmlns:songs="clr-namespace:Aurora.Design.Views.Songs"
xmlns:dg="clr-namespace:Xamarin.Forms.DataGrid;assembly=Xamarin.Forms.DataGrid" xmlns:dg="clr-namespace:Xamarin.Forms.DataGrid;assembly=Xamarin.Forms.DataGrid"
x:Class="Aurora.Design.Views.Songs.SongsView"> x:Class="Aurora.Design.Views.Songs.SongsView">
<ContentPage.BindingContext>
<songs:SongsViewModel
x:Name="songsViewModel"/>
</ContentPage.BindingContext>
<ContentPage.Content> <ContentPage.Content>
<dg:DataGrid <dg:DataGrid
ItemsSource="{Binding SongsList}" ItemsSource="{Binding SongsList}"

View File

@ -1,7 +1,7 @@
using System; using System;
namespace Aurora.Design.Views.Stations namespace Aurora.Design.Views.Stations
{ {
public class StationsViewModel public class StationsViewModel : BaseViewModel
{ {
public StationsViewModel() public StationsViewModel()
{ {