using System; using System.Collections.ObjectModel; using System.Collections.Generic; using System.Linq; using Aurora.Design.Components.NavigationMenu; using Aurora.Design.Views.MainView; using Xamarin.Forms; using Xamarin.Forms.Xaml; using Aurora.Models.Media; using Aurora.Design.Components.MediaPlayer; namespace Aurora.Design.Views.Main { /// /// Delegate for updating player metadata /// /// public delegate void SetPlayerMetadataDelegate(BaseMedia media); [XamlCompilation(XamlCompilationOptions.Compile)] public partial class MainView : MasterDetailPage, IDisposable { private Dictionary _viewModels; private BaseViewModel _lastViewModel; public MainView() { InitializeComponent(); BindingContext = new MainViewModel(); _viewModels = new Dictionary(); MasterPage.ListView.ItemSelected += OnNavItemSelected; Appearing += OnAppearing; } public void Dispose() { Appearing -= OnAppearing; } /// /// Event handler for side bar items being selected /// /// /// private void OnNavItemSelected(object sender, SelectedItemChangedEventArgs e) { var item = e.SelectedItem as NavigationItem; if (item == null) return; 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(); //Unasign deactivating vm UnassignPlayerControls(_lastViewModel); //Assign viewModel _lastViewModel = vm; view.BindingContext = vm; //Assign player controls to viewmodel AssignPlayerControls(vm); ContentPresenter viewContent = (ContentPresenter)ContentPage.Content.FindByName("ViewContent"); viewContent.Content = view; MasterPage.ListView.SelectedItem = null; } /// /// Event handler for page appearing. /// /// The object that fired the event. /// The event arguments private void OnAppearing(object sender, EventArgs args) { //Set initial view from first item in list ObservableCollection screenList = (ObservableCollection)MasterPage.ListView.ItemsSource; //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; AssignPlayerControls(vm); vm.OnActive(); ContentPresenter viewContent = (ContentPresenter)ContentPage.Content.FindByName("ViewContent"); viewContent.Content = view; MasterPage.ListView.SelectedItem = screenList.FirstOrDefault(); } /// /// Unassign setplayer delegate to prevent vms from changing player info when inactive /// /// private void UnassignPlayerControls(BaseViewModel vm) { vm.SetPlayerMetadata = null; } /// /// Assign main views music player controls to a view model /// /// BaseViewModel to assign controls to private void AssignPlayerControls(BaseViewModel vm) { Player player = (Player)ContentPage.FindByName("Player"); player.PlayButtonCommand = new Command(vm.OnPlayExecute, vm.CanPlayExecute); player.NextButtonCommand = new Command(vm.OnNextExecute, vm.CanNextExecute); player.PreviousButtonCommand = new Command(vm.OnPreviousExecute, vm.CanPreviousExecute); //Assign SetPlayer delegate vm.SetPlayerMetadata = SetPlayerDelegate; } private void SetPlayerDelegate(BaseMedia media) { Player player = (Player)ContentPage.FindByName("Player"); if (media.Metadata is AudioMetadata) { AudioMetadata meta = (AudioMetadata)media.Metadata; player.ArtistName = meta.Artist; player.SongTitle = meta.Title; } } } }