如何在 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 中创建页面?
您可以将Frame
的Content
设置为您自己创建的实例,而不是尝试根据其类型导航到该页面:
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,一般情况下如果需要Page
和ViewModel
结合,可以这样:
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++:如何在结构中定义类实例。类具有参数化构造函数[重复]