在Prism.Forms中将ViewModel绑定到XAML视图

5
在Xamarin.Forms中,可以通过在标记中使用<ContentPage.BindingContext>标签来指定XAML页面要使用的ViewModel。我所能看到的唯一优点是,在与ViewModel相关联的{Binding}属性值时,我在XAML中可以获得关于VM属性/命令的智能感知功能。与Prism.Forms将视图与ViewModel绑定的更加灵活的方法相比,这样做的唯一优点就在于此。
再次强调,Prism.Forms有更好的方式来绑定视图和ViewModel,但当我使用它们时,我通常无法在XAML页面中获得智能感知功能,这实际上对于复杂的视图/ViewModel非常有帮助。
我认为在Prism.Forms的场景中也可以使用<ContentPage.BindingContext>标签,但这感觉像是打破了Prism想要进行视图到ViewModel绑定的方式。
另外,我担心我的ViewModel会被不必要地实例化两次:一次是Xamarin.Forms创建它时,另一次是Prism进行绑定时。不确定是否正确... 同样,我可以想象一种情况,即我希望在不同的时间将我的视图绑定到不同的ViewModel上; 例如,在Android与iOS上使用不同的VM类。Prism让我这样做,但我担心在存在<ContentPage.BindingContext>标签时无法实现这一点。
有没有一种支持/推荐的方法来仅针对设计时间(即智能感知)在我的XAML中标识我的ViewModel,而在运行时由Prism的视图到视图模型绑定逻辑发生?我认为我希望完全忽略<ContentPage.BindingContext>标签,除非我正在使用Visual Studio编辑XAML。
编辑:我的问题是错误的,因为我期望看到的XAML视图智能感知功能不是由Visual Studio提供的,而是由JetBrains的ReSharper提供的。下面描述的解决方案确实增加了预期的IntelliSense功能,但仅在安装了ReSharper(或可能存在其他具有此功能的Visual Studio插件)的开发环境中才有效。
2个回答

2
虽然我不能说我听说过如何最好处理这个问题的共识,但我至少可以给你一个答案。来自Microsoft / Xamarin的工具仍然非常新,作为稳定版本,不幸的是,它似乎不支持动态加载ViewModels。我已经在GitHub上为Prism创建了一个问题,您可以在此处关注。

同时,如果您需要使绑定更加强类型化以便Xamarin Forms预览器可以找到ViewModel,则建议设置AutoWire=false,以便Prism不会再次创建ViewModel。

尽管很痛苦,但有时处于前沿(Xaml预览器仍然是),意味着要做出牺牲,并且不得不打破规则和模式来使事情正常运行。希望这有所帮助。


目前,我并不需要Xamarin XAML预览器的支持,只需要在我的视图模型中获得属性的Intellisense。所以,我认为你有一个很好的建议——使用Xamarin.Forms的“视图模型绑定”技术(使用ContentPage.BindingContext),然后将AutoWire设置为false。我想我唯一担心的是这种方法对于基于Prism/Unity的构造函数注入的视图模型可能无法正常工作(因为X.F创建了VM实例,而不是Prism)。我可以自己尝试一下,但只是想知道是否有人对我不使用Prism View-to-ViewModel绑定有任何警告。 - Jeremy Ellis
目前的环境没有直接的工具来支持链接视图和视图模型。因此,智能感知和预览器都无法真正使用它们。话虽如此,问题的产生是由于在预览器完成之前无法真正开始任何实际工作,因此发布了该问题。希望这有助于澄清。 - Dan Siegel
谢谢。我非常感激你的帮助和信息。只是回应一下我的评论:在我的XAML视图中使用ContentPage.BindingContext标记是不可行的,因为它要求我的ViewModel类具有无参数构造函数;而且当ViewModel实例被创建时,会调用该构造函数,而不是我的启用Prism的构造函数,例如INavigationService等可注入项。所以,这是一个不能接受的问题,我不能使用ContentPage.BindingContext标记。我希望有一种方法可以使该标记仅在VStudio中受到尊重,而不是在编译/运行时。比如在XAML中添加一些注释之类的东西。 - Jeremy Ellis
我已经创建了一个Gist,你可以使用它。我想要明确的是,我并不是说这是一个很好的策略。然而,我相信它可能为你实现目标提供一种方法。 - Dan Siegel

2
以下是Dan的回答很有帮助,但Atsushi Nakamura提出了一个更好的解决方案 - 在这里:启用IntelliSense以在Prism for Xamarin.Forms博客中查看ViewModel成员
其实,他的方法是(1)为视图模型创建一个虚假的“设计时”服务定位器——对于每个视图模型类型返回null;然后(2)将此服务定位器引用为XAML视图的静态绑定,作为页面的BindingContext。这在设计时提供了IntelliSense(当存在ReSharper或类似的Visual Studio插件时);但在运行时,服务定位器返回null,并且Prism执行其典型的视图到视图模型绑定。
根据在Prism存储库上创建的问题上的讨论,上述方法将被添加到官方的Prism for Xamarin.Forms文档中,作为提供设计时数据的推荐方式。请在此处查看该讨论:相关的Prism GitHub问题 因此,这解决了我的问题,并增加了我所寻找的设计时 IntelliSense 。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接