我最近开始使用Xamarin和MVVM进行开发,我遇到了一个问题,我真的不知道如何解决。
我将View
中的事件绑定到ViewModel
中的ICommand
属性。但是这些事件应该能够触发例如DisplayAlert
或Navigation.PushAsync
调用。
现在我知道这些问题有一些解决方法,但是在ViewModel
中引用Navigation
对象不会违反ViewModel
的预期用途,它对View
一无所知?
我真的很想保持一个严格的、纯粹的 MVVM 模式,那么我该如何实现呢?
编辑
感谢您的回答。我搜索了更多,发现了这篇博文中提到的一些Xamarin.forms
库,这似乎有所帮助。
我将尝试棱镜,它有一个Navigation Service
和一个Page Dialog Service
.
编辑 02
否则,您可以使用消息传递中心,如@Julien所述。
您提出的问题在 MVVM 世界中很常见,这会将其变成固执己见的话题。一些开发人员认为您应该首先在页面/视图 - V 之间导航,另一些开发人员认为您应该首先在视图模型 - VM 之间导航。两者都有自己的优点和缺点,WWW上有很多关于它的资源。
我建议熟悉这两种不同的方法,然后决定使用哪一种。您可以检查现有的 MVVM 框架,了解它们如何解决此问题。幸运的是,这个话题非常有趣,所以你应该享受调查之旅。
很可能没有适合不同类型项目的灵丹妙药。请记住这一点。
祝你好运!
@EvZ答案很好。您必须检查常见的 MVVM 实践...
无论如何,如果你真的不想使用这些模式,你可以使用事件(有时,在某些场景中,它可能很有用......看看下面的示例代码(代码很简单,但你可以在页面上分解UI"函数",使其更干净......
除了事件之外,您还可以使用 Xamarin MessagingCenter将视图连接到其 ViewModel(参考:Xamarin MessagingCenter 文档。
即:
/// <summary>
/// My view model class
/// </summary>
public class MyVM : INotifyPropertyChanged
{
// VM logic
// ...
// events
private event EventHandler<string> OnRequestShowDialog;
// calling event
public void BusinessMethod()
{
// ...
OnRequestShowDialog?.Invoke(this, "Business method completed successfully...");
}}
/// <summary>
/// My page class
/// </summary>
public class MyPage : ContentPage
{
public MyPage()
{
// New VM
BindingContextChanged += (sender, args) =>
{
// Connect to your VM's events here
(this.BindingContext as MyVM).OnRequestShowDialog += (e, message) => {
this.DisplayAlert("info", args, "ok");
};
};
}
}
希望它能给你一些想法...