如何在 UWP 中实例化具有构造函数的页面?

Posted

技术标签:

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

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

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

【问题讨论】:

【参考方案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,这确实是我想要推入堆栈的状态。同样,这让我觉得这是我遇到过的最糟糕的导航架构之一。

以上是关于如何在 UWP 中实例化具有构造函数的页面?的主要内容,如果未能解决你的问题,请参考以下文章

C++:如何在结构中定义类实例。类具有参数化构造函数[重复]

Activator.CreateInstance - 如何创建具有参数化构造函数的类的实例

继承中子类构造函数相关问题

如何在java中动态实例化具有不同数量参数的java类?

android:如何使用属性集构造函数实例化我的自定义视图

实例化对象和构造函数之间的关系