How to pass a parameter to the navigation view model using WinRT Caliburn.Micro?

I am developing a Windows Store application using WinRT Caliburn.Micro and I rely on a navigation framework.

I have viewing models for customizing the game (identifying players) and the actual game. When you go from installation to game, I want to transfer the collection of players to the game view model. How can i do this?

Basically, my models currently look like this:

public class SetupGameViewModel : NavigationViewModelBase
{
    public SetupGameViewModel(INavigationService ns) : base(ns) { }

    public IObservableCollection<Player> Players { get; set; }

    public void StartGame()
    {
        // This is as far as I've got...
        base.NavigationService.NavigateToViewModel<GameViewModel>();

        // How can I pass the Players collection from here to the GameViewModel?
    }
}

public class GameViewModel : NavigationViewModelBase
{
    public GameViewModel(INavigationService ns) : base(ns) { }

    public ScoreBoardViewModel ScoreBoard { get; private set; }

    public void InitializeScoreBoard(IEnumerable<Player> players)
    {
        ScoreBoard = new ScoreBoardViewModel(players);
    }
}

Ideally, I would like to call InitializeScoreBoardfrom the constructor GameViewModel, but as far as I could tell, it is impossible to pass the collection SetupGameViewModel.Playersto the constructor GameViewModel.

INavigationService.NavigateToViewModel<T> (extension) [object] parameter, , , , . , GameViewModel.InitializeScoreBoard SetupGameViewModel.StartGame, GameViewModel .

+5
3

, , . , NavigateToViewModel<T>(object) .

Caliburn Micro MSDN , "" , .

SetupGameViewModel.StartGame :

public void StartGame()
{
    base.NavigationService.Navigated += NavigationServiceOnNavigated;
    base.NavigationService.NavigateToViewModel<GameViewModel>(Players);
    base.NavigationService.Navigated -= NavigationServiceOnNavigated;
}

NavigationServiceOnNavigated :

private static void NavigationServiceOnNavigated(object sender, NavigationEventArgs args)
{
    FrameworkElement view;
    GameViewModel gameViewModel;
    if ((view = args.Content as FrameworkElement) == null || 
        (gameViewModel = view.DataContext as GameViewModel) == null) return;

    gameViewModel.InitializeScoreBoard(args.Parameter as IEnumerable<Player>);
}

, , , , .

+4

, , Caliburn.Micro WP8 WinRT:

NavigationService.UriFor<TargetViewModel>().WithParam(x => x.TargetProperty, ValueToPass).Navigate();

WithParam . , , , , , WinRT. - Caliburn.Micro.

, . , OnInitialize OnActivate. , :

NavigationService.UriFor<DetailsViewModel>().WithParam(x => x.Id, SelectedDetailsId).Navigate();

DetailsViewModel:

protected override void OnInitialize()
{
    //Here you'll have Id property initialized to 'SelectedDetailsId' from the previous screen.
}

, :

NavigationService.UriFor<GameViewModel>().WithParam(x => x.Players, Players).Navigate();

, :

public class GameViewModel
{
    public GameViewModel(INavigationService ns) : base(ns) 
    { 
       //It would probably be good to initialize Players here to avoid null
    }

    public ScoreBoardViewModel ScoreBoard { get; private set; }

    public IObservableCollection<Player> Players {get;set;}

    protected void OnInitialize()
    {
        //If everything goes as expected, Players should be populated now.
        ScoreBoard = new ScoreBoard(Players);
    }
}

, , , ( ..) .

(int, string, DateTime .., , , URI , null), / , Players GameViewModel.

, SO, .

+6

Win Store Apps ViewModels NavigationService. Silverlight , . Win Store.

In your case, something like the following should work. In StartGame (), the NavigationService is used to call the GameViewModel. The list of players is passed as a simple parameter. By convention, this parameter will be assigned to the property parameter of the target ViewModel.

public class SetupGameViewModel : Screen 
{
    private readonly INavigationService _navigationService;

    public MainPageViewModel(INavigationService navigationService)
    {
        _navigationService = navigationService;
    }

    public IObservableCollection<Player> Players { get; set; }

    public void StartGame() 
    {
        _navigationService.NavigateToViewModel<GameViewModel>(Players);
    }

    ...
}


public class GameViewModel : Screen
{   
    private IObservableCollection<Player> _parameter;

    public IObservableCollection<Player> Parameter
    {
        get { return _parameter; }
        set
        {
            if (value.Equals(_parameter)) return;
            _parameter = value;
            NotifyOfPropertyChange(() => Parameter);
        }
    }

    protected override void OnActivate()
    {
        // do something with the player list
        // ...
    }

    ...
}

More information on this subject can be found here: http://wp.qmatteoq.com/using-caliburn-micro-with-universal-windows-app-navigation/

+2
source

All Articles