【问题标题】:MVVM - view logic: view vs viewmodel [closed]MVVM - 视图逻辑:视图与视图模型 [关闭]
【发布时间】:2018-08-02 04:35:39
【问题描述】:

“应该”视图逻辑通常驻留在哪里?在视图中(包括后面的代码)还是在视图模型中?

根据逻辑,我了解用于修改视图(使其动态化)、更改其元素属性的任何内容:Visibility、IsEnabled、Content 等,基于一些条件 .

我在选择正确的陈述之间挣扎:

  1. ViewModel 负责所有视图“属性”,如果视图需要一些逻辑 - 这应该是 viewmodel 的工作。

  2. View 是一个 viewmodel 展示,viewmodel 只需要最低限度的暴露模型,因此逻辑应该是视图的一部分。

视图中的逻辑。

一个例子,显示一些文本:

<Grid Visibility="{Binding TextAvailable, Converter=...}">
    <TextBlock Text="{Binding Text}" Visibility="{Binding TextOk, Converter=...}" />
</Grid>

通过查看这个 xaml,您知道 viewmodel 中有 2 个属性:TextAvailable 和 TextOk,用于有条件地显示 Text。

同样可以使用数据触发器来实现。方式无关,重点是:逻辑在视图中。必须彻底浏览视图才能理解两者:逻辑和实现。

视图模型中的逻辑。

Xaml 更简单:

<TextBlock Text="{Binding Text}" Visibility="{Binding ShowText, Converter=...}" />

并且逻辑在视图模型中:

public bool ShowText => TextAvailable && TextOk;

但这需要通知支持,通常订阅/取消订阅事件(如果确定性取消订阅很复杂,则使用弱事件),以便能够告诉视图OnPropertyChanged(nameof(ShowText))如果任何相关属性发生更改.因此,实现很好地分布在许多方法/属性中。


我个人更喜欢简单的视图模型和相当复杂的视图(xaml),充满逻辑。最近我found a way 让逻辑看起来真的很酷(没有额外的元素,更容易看到)。

我了解这两种方法都可以使用什么,因此问题是相当基于意见的,但我不想在我的软件中以疯狂的比例混合这两种方法。哪种方式更干净并且会更好地被另一个 MVVM 程序员接受?我应该更喜欢什么,为什么?

【问题讨论】:

  • 因此问题是基于意见的。确切地。我们真的无法判断哪种方法在客观上会更好。在我看来,如果您打算在另一个视图中重用某个逻辑,它应该在视图模型中实现。否则它应该在视图中。
  • @Rekshino,棘手的问题。因为它是 UI 元素(它被设计为视图) - 它是 view。我明白你的意思,两者都只是类(视图通常是 xaml,但也可以包含代码)。所以我的问题可能听起来像“在哪里保留一些代码”(就像你认为它真的很重要)。从design 的角度来看,这很重要,我想改进。更好的设计意味着易于:支持、扩展、理解、解释等。
  • @ZoharPeled:不是真的——ViewModel 应该做 UI 逻辑,并将业务逻辑委托给另一层。 View 负责任何可见的东西,所以它可以包含 C#,只要是关于渲染和样式的。
  • @Sinatr - 你关于(弱)事件的 cmets 无法说服我,你总是需要一些东西来让 ViewModel 保持最新状态,无论你在哪里与 View 划清界限。跨度>
  • MVVM 的目标是保持 View 的简洁性,并在 ViewModel 中提供一个“抽象的、不显眼的”UI,这样可以更容易地进行测试。

标签: c# wpf mvvm


【解决方案1】:

我认为答案是做任何你觉得舒服的事情。我不认为一种方法在客观上比另一种更好。

我猜在纯 MVVM 场景中,ViewModel 不知道它的视图,也不知道它的数据将如何显示。在实践中,我认为这种情况很少遇到。大多数情况下,在编写 ViewModel 代码时,您会很好地了解其数据将如何显示和交互:换句话说,您将知道 View 将是什么样子,以及它将如何表现.

鉴于此,我认为在 ViewModel 中放置一些 UI 逻辑不是问题。我的意思不是直接操作视图中的 UI 元素。相反,在 ViewModel 上具有 View 将绑定到的属性,例如示例中的 Boolean 属性。逻辑越复杂,我就越有可能将它放在 ViewModel 中,因为尽管您可以通过可见性转换器和数据触发器在 View 中执行逻辑,但 XAML 可能会变得非常冗长。这并不是说我从不使用这些 XAML 功能,只是我通常会将它们用于更简单的逻辑。

说到底,ViewModel 是为了支持 View:本质上是为它提供 View 的 UI 元素可以绑定到的属性,从而提供两者可以通信的管道。您的选择,基于您要实现的 MVVM 的纯度,是您希望 ViewModel 支持多少 View,以及您希望 View 隔离多少。

【讨论】:

    【解决方案2】:

    在我看来

    2.View是viewmodel的展示,viewmodel只需要最少的暴露模型,逻辑应该是view的一部分。

    听起来更正确。

    什么属于“最低限度”取决于业务逻辑要求(例如必须显示警告,因为法律要求,此类属性将属于 VM)和 设计师的天赋。所以业务逻辑不属于视图!

    问题“如果您有一个 UIElementA 作为 UIElementB 的 DataContext,那么 UIElementA 是属于 View 还是属于 ViewModel?”显示,从 UIElementA 的角度来看,UIElementB 可以被视为 VM,但 UIElementB 确实不是 VM。
    所以一些作为 DataContext 的类(也不依赖于表示框架)可以而且应该放在视图层(OP迫使我重新考虑一些类的分配)。

    总结一下:
    ViewModel 中不太依赖 UI 的逻辑更好,但在合理的范围内。

    【讨论】:

      猜你喜欢
      • 2010-10-28
      • 1970-01-01
      • 2012-06-08
      • 1970-01-01
      • 2010-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多