【问题标题】:How do you instantiate Pages that have constructors in UWP?如何在 UWP 中实例化具有构造函数的页面?
【发布时间】:2020-03-29 20:57:41
【问题描述】:

我想使用 UWP 中的导航功能。不幸的是,Navigate 方法的参数是一个类型,而不是一个页面的实例。看起来这种类型的激活是在幕后完成的。我质疑设计决策,但我的直接问题是我所有的 MVVM 表单都是用视图模型实例化的。通常我使用依赖注入容器创建页面。

当页面具有 DI 构造函数时,如何在 UWP 中使用 Navigate 方法创建页面?

【问题讨论】:

    标签: dependency-injection uwp


    【解决方案1】:

    当这些页面具有 DI 构造函数时,当它们与 Navigate 方法一起使用时,如何在 UWP 中创建页面?

    您可以将FrameContent 设置为您自己创建的实例,而不是尝试根据其类型导航到该页面:

    rootFrame.Content = new YourPage(yourDependency);
    

    另一种选择是确保所有页面都有一个默认的无参数构造函数,并将依赖项注入其他地方,例如@Richard Zhang - MSFT 建议的 OnNavigatedTo 方法。

    【讨论】:

    • 我得出的结论是,UWP 中的导航架构只是大脑受损。它可以用于快速的爱好程序,但它完全没有达到商业应用的目的。
    • 是的,但我认为它会随着时间变得更好。
    • @Going-gone 奇怪的是,在 Xamarin.Forms 中,他们使用页面实例进行导航。解决了我试图让它仅使用页面类型作为导航参数的几个问题。
    • 对于这个问题上可能发生的其他任何人:UWP 中的导航架构不值得努力学习。我花了两天时间试图让 MVVM 和 DI 一起工作,每解决一个问题都会产生两个新问题。我终于把它扔出窗外,在一天之内编写了我自己的 MVVM/DI 导航器。
    • @Quarkly 请分享这个自定义导航器:P 我一直在为桌面应用程序中带有枢轴的多层菜单而苦苦挣扎。
    【解决方案2】:

    在 UWP 中,Frame.Navigate 的导航参数是Type,而不是实例。这真是一个设计。

    其实在UWP中导航不需要实例,也不需要DI,一般情况下如果需要PageViewModel结合,可以这样:

    1.在页面构造函数中初始化ViewModel

    框架

    MyFrame.Navigate(typeof(MyPage));
    

    我的页面

    private MyViewModel vm;
    public MyPage()
    {
        this.InitializeComponent();
        vm = new MyViewModel();
    }
    

    2。导航时通过传参初始化ViewModel

    框架

    var vm = new MyViewModel();
    MyFrame.Navigate(typeof(MyPage), vm);
    

    我的页面

    private MyViewModel vm;
    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        if(e.Parameter!=null && e.Parameter is MyViewModel _vm)
        {
            vm = _vm;
            // do other things
        }
    }
    

    如果要复用页面,可以开启页面缓存,它会保存当前页面状态(包括ViewModel),下次导航到页面时使用缓存,避免重复创建@987654332 @。

    public MyPage()
    {
        this.InitializeComponent();
        NavigationCacheMode = NavigationCacheMode.Enabled;
    }
    

    最好的问候。

    【讨论】:

    • 感谢您的回复,但这一定是 .NET 历史上最愚蠢的设计决策之一。这是谁的主意?它同时面对 DI 和 MVVM。这也使得 UWP 的导航架构几乎毫无用处。
    • 进入Navigation栈的参数必须是视图模型的状态,不能是新建的视图模型。例如,我想用 Fred 的用户导航到 UserView。如果我使用 UserViewModel 参数导航到 UserView,那么原始视图模型将被放入堆栈并且没有地方存储 Fred,这确实是我想要推入堆栈的状态。同样,这让我觉得这是我遇到过的最糟糕的导航架构之一。
    猜你喜欢
    • 1970-01-01
    • 2010-11-20
    • 1970-01-01
    • 2020-01-06
    • 2017-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多