0
votes

Im currently trying to learn WPF and the MVVM pattern, but am confused when it comes to changing the main windows view from inside a User Control.

What I currently have

I have a single window application which when started displays a login view which is a UserControl and is set as a ContentControl in my main window.

ApplicationView.xaml

    <Window x:Class="MyApplication.Views.ApplicationView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:ignore="http://www.galasoft.ch/ignore"
        xmlns:local="clr-namespace:MyApplication.Views"
        xmlns:viewModels="clr-namespace:MyApplication.ViewModels"
        mc:Ignorable="d ignore"
        DataContext="{Binding Application, Source={StaticResource Locator}}">    
   <Window.Resources>
       <DataTemplate DataType="{x:Type viewModels:LoginViewModel }">
            <local:LoginView />
        </DataTemplate>
       <DataTemplate DataType="{x:Type viewModels:MainViewViewModel }">
           <local:MainView />
       </DataTemplate>
   </Window.Resources>
    <Grid>
        <ContentControl Content="{Binding CurrentPageViewModel}"></ContentControl>
    </Grid>
</Window>

ApplicationViewModel.cs

namespace MyApplication.ViewModels
{
    public class ApplicationViewModel : ViewModelBase
    {
        #region Fields

        private ICommand _changePageCommand;
        private IPageViewModel _currentPageViewModel;
        private List<IPageViewModel> _pageViewModels;

        #endregion

        public ApplicationViewModel()
        {
            //Add available pages
            PageViewModels.Add(new LoginViewModel());
            PageViewModels.Add(new MainViewViewModel());

            //Set starting page
            CurrentPageViewModel = PageViewModels[0];

        }

        #region Properties / Commands

        public ICommand ChangePageCommand
        {
            get
            {
                if (_changePageCommand == null)
                {
                    _changePageCommand = new RelayCommand<object>(
                        p => ChangeViewModel((IPageViewModel)p),
                        p => p is IPageViewModel);
                }

                return _changePageCommand;
            }
        }

        public List<IPageViewModel> PageViewModels
        {
            get
            {
                if (_pageViewModels == null)                
                    _pageViewModels = new List<IPageViewModel>();

                return _pageViewModels;
            }
        }

        public IPageViewModel CurrentPageViewModel
        {
            get
            {
                return _currentPageViewModel;
            }
            set
            {
                if (_currentPageViewModel != value)
                {
                    _currentPageViewModel = value;
                    this.VerifyPropertyName("CurrentPageViewModel");
                    this.RaisePropertyChanged();
                }
            }
        }

        #endregion


        #region Methods
        private void ChangeViewModel(IPageViewModel viewModel)
        {
            if (!PageViewModels.Contains(viewModel))
                PageViewModels.Add(viewModel);

            CurrentPageViewModel = PageViewModels
                .FirstOrDefault(vm => vm == viewModel);
        }
        #endregion
    }
}

What I want to achieve

I want to change the applications window view from the LoginView to the MainView once a login button inside the login UserControl is clicked. I'm struggling to get my head around how this would be possible and how to achieve this. Any help would be greatly appreciated, Thanks.

2
Have you checked the following link (stackoverflow.com/questions/13136816/…)Kevin Wallis

2 Answers

0
votes

In Application View.xaml :

<ContentControl Content="{Binding CurrentPageViewModel, Mode=TwoWay}"></ContentControl>

In loginview.xaml, bind the login button click to a command inside LoginViewModel as LoginButtonClickedCommand

Listen to the command in ApplicationViewModel

LoginViewModelInstance.LoginButtonClickedCommand = new RelayCommand(OnLoginButtonClicked, param => true);

Handle the command handler and change the CurrentPageViewModel inside ApplicationViewModel

private void OnLoginButtonClicked(object obj)
{
    CurrentPageViewModel = new ContentPageViewModel();
}

This should do the trick for you.

0
votes

You just need to execute the Command in the ApplicationViewModel from your UserControl. Consider you have a Button on your UserControl that need to switch view in main window on clicking, you can trigger it as follows

<Button Command="{Binding DataContext.ChangePageCommand, RelativeSource=
          {RelativeSource AncestorType={x:Type ApplicationViewModel}}, Mode=OneWay}" />

If you need full working example, you can refer WPF MVVM navigate views

Hope this helps.