我正在使用 WinRT Caliburn.Micro 开发 Windows 应用商店应用程序游戏,并且我依赖导航框架。
我有游戏设置(定义玩家)和实际游戏的 View 模型。从设置导航到游戏时,我想将玩家集合传递给游戏 View 模型。我该怎么做?
从示意图上看,我的 View 模型目前看起来像这样:
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);
}
}
理想情况下,我想调用 InitializeScoreBoard
来自 GameViewModel
构造函数,但据我所知,不可能通过 SetupGameViewModel.Players
收藏到GameViewModel
构造函数。
INavigationService.NavigateToViewModel<T>
(扩展)方法可选地采用 [object] parameter
参数,但此参数似乎没有到达导航到的 View 模型构造函数。而且我不知道如何显式调用 GameViewModel.InitializeScoreBoard
来自 SetupGameViewModel.StartGame
的方法方法之一,因为 GameViewModel
在此阶段尚未初始化。
最佳答案
好的,就放在那里吧,Caliburn.Micro
对 WP8 和 WinRT 有统一的导航:
NavigationService.UriFor<TargetViewModel>().WithParam(x => x.TargetProperty, ValueToPass).Navigate();
并且您可以为多个参数链接WithParam
。现在有一些限制,并非所有类型都通过,我不太确定确切原因是什么,但这与导航在 WinRT 中的工作方式有关。在 Caliburn.Micro
discussion section 的某个地方提到过它.
无论如何,您可以通过这种方式导航。不过不要依赖构造函数,它会调用 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
没有't work for me, was always null
), 所以最坏的情况/解决方法是,例如,在导航之前将 Players
列表序列化为临时文件,然后将文件路径作为字符串传递到 GameViewModel
中进行反序列化。
框架中有更多人参与漫游 SO,他们可能会为您提供更有值(value)的见解。
关于c# - 如何使用 WinRT Caliburn.Micro 将参数传递给导航 View 模型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15251867/