marko devcic

  • github:
    deva666
  • email:
    madevcic {at} gmail.com

Beginner MVVM Navigation Part 2

Posted on 19 March 2014

We're going to extend our sample books and authors catalog app from the part 1 and add another possible implementation of the HostViewModel type. This time we're building the HostViewModel so it holds on to its child view models for the entire lifetime. If your child view models are light weight and you can afford to have them live for the entire life time of the hosting view model then this is the way to go.

Again, here's the complete code for our HostViewModel .

  internal abstract class HostViewModel : ViewModelBase
    {
        private ViewModelBase _selectedChild;

        public ViewModelBase SelectedChild
        {
            get { return _selectedChild; }
            set { SetPropertyValue(ref _selectedChild, value); }
        }

        public List<ViewModelBase> Children { get; protected set; }
    }

And the MainViewModel implementing it.

     internal sealed class MainViewModel : HostViewModel
    {
        private readonly Timer _timer;

        public override string Title { get { return "Main"; } }

        public string Version
        {
            get { return this.GetType().Assembly.GetName().Version.ToString(); }
        }

        private string _time;
        public string Time
        {
            get { return _time; }
            set { SetPropertyValue(ref _time, value); }
        }

        private ICommand _goToBooksCommand;
        public ICommand GoToBooksCommand
        {
            get { return _goToBooksCommand ?? (_goToBooksCommand = new DelegateCommand(GoToBooks)); }
        }

        private ICommand _goToAuthorsCommand;
        public ICommand GoToAuthorsCommand
        {
            get { return _goToAuthorsCommand ?? (_goToAuthorsCommand = new DelegateCommand(GoToAuthors)); }
        }

        private ICommand _goToSettingsCommand;
        public ICommand GoToSettingsCommand
        {
            get { return _goToSettingsCommand ?? (_goToSettingsCommand = new DelegateCommand(GoToSettings)); }
        }

        public MainViewModel()
        {
            this.Children = new List<ViewModelBase>();
            GoToBooks();
            _timer = new Timer((s) => Time = DateTime.Now.ToLongTimeString(), this, 500, 500);
        }

        private void GoToBooks()
        {
            var booksVM = this.Children.FirstOrDefault(vm => vm.GetType() == typeof(BooksViewModel));
            if (booksVM == null)
            {
                booksVM = new BooksViewModel();
                Children.Add(booksVM);
            }
            this.SelectedChild = booksVM;
        }

        private void GoToAuthors()
        {
            var authorsVM = this.Children.FirstOrDefault(vm => vm.GetType() == typeof(AuthorsViewModel));
            if (authorsVM == null)
            {
                authorsVM = new AuthorsViewModel();
                Children.Add(authorsVM);
            }
            this.SelectedChild = authorsVM;
        }

        private void GoToSettings()
        {
            var settingsVM = this.Children.FirstOrDefault(vm => vm.GetType() == typeof(SettingsViewModel));
            if (settingsVM == null)
            {
                settingsVM = new SettingsViewModel();
                Children.Add(settingsVM);
            }
            this.SelectedChild = settingsVM;
        }

        protected override void OnDispose()
        {
            foreach (var vm in this.Children)
            {
                ((ViewModelBase)vm).Dispose();
            }
            _timer.Dispose();
            base.OnDispose();
        }
    }

This time we're holding all the child view models inside a List, so keep in mind they are going to live for the entire lifetime of the view model that's hosting them.