【问题标题】:Bind ViewModel to XAML View in Prism.Forms将 ViewModel 绑定到 Prism.Forms 中的 XAML 视图
【发布时间】:2017-08-03 20:50:43
【问题描述】:

在 Xamarin.Forms 中,可以通过 <ContentPage.BindingContext> 标记在标记内指定要与 XAML 页面一起使用的 ViewModel。我可以看到这样做的唯一优势 - 与 Prism.Forms 将视图绑定到 ViewModels 的更灵活的方式相比 - 然后我在 XAML 中获得了关于 VM 属性的 IntelliSense /commands 添加我的{Binding} 属性值时。

同样,Prism.Forms 有更好的方法来绑定视图和ViewModels,但是当我使用它们时,我通常不会在 XAML 页面中获得 IntelliSense - 这实际上是对复杂的 View/ViewModel 很有帮助。

我看不出有任何理由不能在 Prism.Forms 场景中使用 <ContentPage.BindingContext> 标签。但这感觉就像我正在“打破”Prism 想要做View-to-ViewModel 绑定的方式。

另外,我担心我的ViewModel 会被不必要地实例化两次,一次是在 Xamarin.Forms 创建它时;还有一次当 Prism 进行绑定时。不确定这是否正确......另外,我可以看到一个场景,我想在不同的时间将我的视图绑定到不同的ViewModels;例如,Android 与 iOS 的不同 VM 类。 Prism 允许我这样做,但我担心它不适用于存在 <ContentPage.BindingContext> 标签。

是否有支持/推荐的方式来识别我的 XAML 中的 ViewModel 仅用于设计时目的(即用于智能感知)但 Prism 的视图到视图模型绑定逻辑发生在运行时?我想我希望 <ContentPage.BindingContext> 标记被完全忽略,除非我在 Visual Studio 中编辑 XAML。

编辑:我上面的问题是不正确的,因为我期望看到的 XAML 视图 IntelliSense 不是由 Visual Studio 提供的,而是由 JetBrains ReSharper 提供的。下面描述的解决方案确实添加了预期的 IntelliSense 功能,但仅在安装了 ReSharper 的开发环境中(或者可能有其他 Visual具有此功能的 Studio 插件)。

【问题讨论】:

    标签: forms xaml xamarin mvvm prism


    【解决方案1】:

    以下 Dan 的回答很有帮助,但 Atsushi Nakamura 描述了一个更好的解决方案 - 这里:Enable IntelliSense for ViewModel members with Prism for Xamarin.Forms blog

    基本上,他的方法是 (1) 为视图模型创建一个虚假的“设计时”服务定位器 - 为每个 ViewModel 类型返回 null;然后 (2) 在 XAML 视图中将此服务定位器引用为页面的 BindingContext 的静态绑定。这会在设计时提供 IntelliSense(当存在 ReSharper 或类似的 Visual Studio 插件时);但在运行时服务定位器返回 null,并且 Prism 执行其典型的 View-to-ViewModel 绑定。

    根据对 GitHub 上 Prism 存储库中创建的问题的讨论,上述方法将添加到官方 Prism for Xamarin.Forms 文档中,作为提供设计时数据的推荐方式。在此处查看该讨论:related Prism GitHub issue

    这样就解决了我的问题并添加了我正在寻找的设计时 IntelliSense

    【讨论】:

      【解决方案2】:

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

      同时,如果您需要使绑定的类型更强,以便 Xamarin Forms Previewer 可以找到 ViewModel,那么我建议设置 AutoWire=false,这样 Prism 就不会再次创建 ViewModel。

      要承认,有时处于最前沿(Xaml Previewer 仍然如此)虽然很痛苦,但意味着做出牺牲并且必须打破规则和模式才能使事情顺利进行。希望对您有所帮助。

      【讨论】:

      • 目前,我不是在寻找 Xamarin XAML Previewer 支持,只是对我的视图模型上的属性进行智能感知。所以,我认为您有一个很好的建议 - 使用 Xamarin.Forms“视图模型绑定”技术(使用 ContentPage.BindingContext),然后设置 AutoWire=false。我想我对这种方法的唯一担心是我的视图模型上基于 Prism/Unity 的构造函数注入将不起作用(因为 X.F 正在创建 VM 实例,而不是 Prism)。我可以自己尝试一下,但只是想知道是否有人对我有任何关于不使用 Prism View-to-ViewModel 绑定的警告。
      • 该环境目前没有直接的工具来支持链接 View 和 ViewModel。因此,IntelliSense 和 Previewer 都不能真正使用它们。也就是说,创建的问题是由于在预览器完成之前无法开始实际工作,因此发布了问题。希望这有助于澄清。
      • 谢谢。我非常感谢您的帮助和信息。只是为了回应我自己的评论:在我的 XAML 视图中使用 ContentPage.BindingContext 标记是不行的,因为它希望我的 ViewModel 类有一个无参数的构造函数;并且在创建 ViewModel 实例时调用它。我的启用 Prism 的构造函数带有 INavigationService 等可注入物。所以,这是一个交易破坏者,我不能使用 ContentPage.BindingContext 标记。我希望有某种方法可以使该标签仅受 VStudio 尊重,而不是在编译/运行时。就像 XAML 中的一些符号之类的东西。
      • 我已经创建了一个您可以使用的Gist。我想明确一点,我并不是说这是一个很好的策略。但是,我相信它可能会为您提供实现目标的技巧。
      猜你喜欢
      • 1970-01-01
      • 2017-12-14
      • 2017-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-15
      • 1970-01-01
      相关资源
      最近更新 更多