Tai Nguyen
Tai Nguyen

Reputation: 956

Windows Phone Mvvm Light Navigate between Views

I'm new on Windows phone. I want to create an application but actually i have a problem with the Binding command.

I want on click , to change the view

In my homepage i have 2 buttons : Login / Register in my MainPage.xaml on the View Folder

<phone:PhoneApplicationPage>

    <Grid>
        <Grid.Background>
            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                <GradientStop Color="Black" Offset="0"/>
                <GradientStop Color="#FF563AA0" Offset="1"/>
            </LinearGradientBrush>
        </Grid.Background>

        <ContentControl Content="{Binding CurrentViewModel}" />

        <Button 
            Command="{Binding ConnexionViewCommand}"
            x:Name="Connexion_button" 
            HorizontalAlignment="Left" 
            Margin="90,308,0,0"
            Content="Login" 
            VerticalAlignment="Top" 
            Width="282"/>
        <Button 
            Command="{Binding InscriptionViewCommand}"
            x:Name="Create_account" 
            HorizontalAlignment="Left" 
            Margin="90,446,0,0"
            Content="Create Account" 
            VerticalAlignment="Top" 
            Width="282"/>
    </Grid>

</phone:PhoneApplicationPage>

I have 3 files in my folder View : ConnexionView.xaml and InscriptionView.xaml , and the MainPage.xaml

5 files in my folder ViewModel : ConnexionViewModel.cs , InscriptionViewModel.cs, MainPageViewModel.cs, MainViewModel.cs and ViewModelLocator.cs

I try to Follow this example but i don't understand a lot.

http://www.codeproject.com/Articles/323187/MVVMLight-Using-Two-Views

i add this code in my MainViewModel.cs but i don't know what i have to do now.

namespace TeysserApp.ViewModel
{
    public class MainViewModel : ViewModelBase
    {
        private ViewModelBase _currentViewModel;

        readonly static ConnexionViewModel _ConnexionViewModel = new ConnexionViewModel();
        readonly static InscriptionViewModel _InscriptionViewModel = new InscriptionViewModel();
        readonly static MainPageViewModel _MainPageViewModel = new MainPageViewModel();


        public ViewModelBase CurrentViewModel
        {
            get
            {
                return _currentViewModel;
            }
            set
            {
                if (_currentViewModel == value)
                    return;
                _currentViewModel = value;
                RaisePropertyChanged("CurrentViewModel");
            }
        }
        public ICommand ConnexionViewCommand { get; private set; }
        public ICommand InscriptionViewCommand { get; private set; }

        public MainViewModel()
        {
            CurrentViewModel = MainViewModel._MainPageViewModel;
            ConnexionViewCommand = new RelayCommand(() => ExecuteCommandViewCommand());
            InscriptionViewCommand = new RelayCommand(() => ExecuteInscriptionViewCommand());
        }
        private void ExecuteConnexionViewCommand()
        {
            CurrentViewModel = MainViewModel._ConnexionViewModel;
        }

        private void ExecuteSecondViewCommand()
        {
            CurrentViewModel = MainViewModel._InscriptionViewModel;
        }

    }
}

Here my ViewModelLocator.cs

namespace TestApp.ViewModel
{
    /// <summary>
    /// This class contains static references to all the view models in the
    /// application and provides an entry point for the bindings.
    /// <para>
    /// See http://www.galasoft.ch/mvvm
    /// </para>
    /// </summary>
    public class ViewModelLocator
    {
        static ViewModelLocator()
        {
            ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);

            if (ViewModelBase.IsInDesignModeStatic)
            {
                // SimpleIoc.Default.Register<IDataService, Design.DesignDataService>();
            }
            else
            {
                // SimpleIoc.Default.Register<IDataService, DataService>();
            }

            SimpleIoc.Default.Register<MainViewModel>();
            SimpleIoc.Default.Register<ConnexionViewModel>();
            SimpleIoc.Default.Register<InscriptionViewModel>();
        }

        /// <summary>
        /// Gets the Main property.
        /// </summary>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance",
            "CA1822:MarkMembersAsStatic",
            Justification = "This non-static member is needed for data binding purposes.")]
        public MainViewModel Main
        {
            get { return ServiceLocator.Current.GetInstance<MainViewModel>(); }
        }
        public ConnexionViewModel ConnexionView
        {
            get { return ServiceLocator.Current.GetInstance<ConnexionViewModel>(); }
        }
        public InscriptionViewModel InscriptionView
        {
            get { return ServiceLocator.Current.GetInstance<InscriptionViewModel>(); }
        }
    }
}

Here my App.xaml

<Application
    x:Class="TeysserApp.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:views="clr-namespace:TeysserApp.Views"
    xmlns:vm="clr-namespace:TeysserApp.ViewModels"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone">

<Application.Resources>
    <vm:ViewModelLocator x:Key="Locator" />
    <ResourceDictionary>
        <DataTemplate DataType="{x:Type vm:ConnexionViewModel}">
            <view:ConnexionView />
        </DataTemplate>
        <DataTemplate DataType="{x:Type vm:InscriptionViewModel}">
            <view:InscriptionView />
        </DataTemplate>
    </ResourceDictionary>
    <local:LocalizedStrings xmlns:local="clr-namespace:TeysserApp" x:Key="LocalizedStrings"/>
</Application.Resources>

    <Application.ApplicationLifetimeObjects>
        <!--Objet requis qui gère les événements de durée de vie pour l'application-->
        <shell:PhoneApplicationService
            Launching="Application_Launching" Closing="Application_Closing"
            Activated="Application_Activated" Deactivated="Application_Deactivated"/>
    </Application.ApplicationLifetimeObjects>

</Application>

Thanks for your help.

Upvotes: 3

Views: 177

Answers (2)

Eldho
Eldho

Reputation: 8263

In MVVM Light 5 Laurent has introduce NavigationService

public ViewModelLocator()
{
    ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);

    var navigationService = this.CreateNavigationService();

    SimpleIoc.Default.Register<INavigationService>(() => navigationService);

    SimpleIoc.Default.Register<IDialogService, DialogService>();

    SimpleIoc.Default.Register<MainViewModel>();
    SimpleIoc.Default.Register<DetailsViewModel>();
}

private INavigationService CreateNavigationService()
{
  var navigationService = new NavigationService();
  navigationService.Configure("Details", typeof(DetailsPage));
  // navigationService.Configure("key1", typeof(OtherPage1));

//From a working project.
navigationService.Configure("tnc", new System.Uri("/Views/TncAgreement.xaml", System.UriKind.Relative));


 return navigationService;
}

Your ViewModel

public class MainViewModel : ViewModelBase
{

 private INavigationService navigationService;

 public RelayCommand DetailsCommand { get; set; }

 public MainViewModel(INavigationService navigationService)
 {
     this.navigationService = navigationService;

      //Show Terms and condition agreement;
      navigationService.NavigateTo("tnc");

     DetailsCommand = new RelayCommand(() =>
    {
        navigationService.NavigateTo("Details", "My data");
    });
 }
}

Similar SO Answer

Upvotes: 2

Ryan Searle
Ryan Searle

Reputation: 1627

When you press the Connexion button the method ExecuteFirstViewCommand() is run however this doesn't exists, you need to change the lambda operation method ExecuteConnexionViewCommand(). If that doesn't solve it then could you debug the code at run-time and see if the CurrentViewModel is being updated.

enter image description here

Make sure it is encapsulated in a resource dictionary!

<Application.Resources>
    <ResourceDictionary>
    </ResourceDictionary>
</Application.Resources>

Upvotes: 0

Related Questions