c# - 如何使用 WinRT Caliburn.Micro 将参数传递给导航 View 模型?

标签 c# windows-runtime windows-store-apps caliburn.micro

我正在使用 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 的某个地方提到过它.

无论如何,您可以通过这种方式导航。不过不要依赖构造函数,它会调用 OnInitializeOnActivate。所以,只是将其切入示例:

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);
    }
}

但在实践中,我不认为传递像这样的复杂构造(类的集合等)会起作用。

更多原始类型工作得很好(intstringDateTime 等,但是例如 URI 没有't work for me, was always null), 所以最坏的情况/解决方法是,例如,在导航之前将 Players 列表序列化为临时文件,然后将文件路径作为字符串传递到 GameViewModel 中进行反序列化。

框架中有更多人参与漫游 SO,他们可能会为您提供更有值(value)的见解。

关于c# - 如何使用 WinRT Caliburn.Micro 将参数传递给导航 View 模型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15251867/

相关文章:

c# - aspnet_compiler.exe 有什么特别之处吗?

c# - Silverlight 应用程序中的 RIA 服务代码生成

c# - 如何快速刷新ADO.NET实体数据模型?

c# - 与对象绑定(bind)

c# - 在展开嵌套的 "Dispose"语句时处理 "using"抛出的异常

windows - 获取Windows 8/RT的音频样本

c# - Caliburn Micro WinRT 导航和导体

xaml - 有没有一种简单的方法可以对 ListView 中的项目进行重新排序

windows-store-apps - 在 Windows 8.1 GridView 中设置组边距

c# - Windows 10 中的 Monogame 鼠标仅在移动后感觉有压力