【问题标题】:MVVM ViewModel and type of property (PresentationCore.dll ) [closed]MVVM ViewModel 和属性类型(PresentationCore.dll)[关闭]
【发布时间】:2016-05-07 04:32:52
【问题描述】:

我们能否在我的 ViewModel 中使用针对 UI /UI 框架的程序集中的类?

今天我就question 进行了讨论,其中一个人非常坚持认为 PresentationCore.dll 中的类不能在 ViewModel 中使用。(似乎他从未使用过 ICommand)但是是这样吗?

据我了解,MVVM 只是 View 和 ViewModel 解耦的一种模式?它没有说明我可以在 ViewModel 中使用什么类型的类,只要它们不创建视图(ViewModel 没有对视图的直接引用或关于视图的特定实现或类型的任何知识)。

请不要回答什么是好的做法,我只是想清楚 MVVM。

【问题讨论】:

  • 从架构的角度来看,您在视图模型中使用的类型定义在哪个程序集中并不重要。实际上,PresentationCore 中的一些类型经常出现在视图模型中,例如 Geometry、Color、Brush、BitmapSource 等。但是,它们都有一个共同点,即它们不是 Visuals。
  • @Clemens 我同意。但是如果我使用一些可视属性而不是创建视图(我只想使用一个函数或说该类的枚举)怎么办?
  • 我已经阅读了来自链接问题的讨论。 @Tseng 只是不明白,从视图模型中解耦视图是什么,看起来有点狂热。反正你的理解是对的。
  • @KyloRen 去做吧!
  • 你可以为所欲为。如果它有意义,并且使您的工作更轻松并且不会损害产品,那么为什么不这样做呢?另外,你不是 Kylo Ren。冒名顶替者。

标签: c# wpf mvvm data-binding binding


【解决方案1】:

请通过以下链接:

The MVVM Pattern

MVVM Basics

属性类型没有这样的限制。此模式仅通过使用 ViewModel 层解耦 View 和 Model。

【讨论】:

    【解决方案2】:

    上一个问题/答案的简单示例:SolidColorBrush

    此类型在两个不同的程序集中声明:Windows.Foundation.UniversalApiContract(UWP 应用)和 PresencationCore.dll (WPF)。它们都是不同的类型,具有不同的命名空间和不同的身份(类型的身份与它的程序集耦合。

    TypeA 程序集 A 与程序集 B 中的类型 A 不同。您不能将 AssemblyA.TypeA 传递给期望 AssemblyB.TypeA 的对象

    为什么重要?

    以那个 ViewModel 为例

    // WPF namespace
    using System.Windows.Media;
    
    public class ExampleViewModel : ViewModelBase
    {
        public SolidColorBrush Color { get; set; }
    }
    

    当您在 WPF 中使用它时,一切都很好并且可以正常工作。现在你想制作一个 UWP 应用程序,这行不通。 UWP 不知道来自 PresentationCore.dll 的 System.Windows.Media.SolidColorBrush。它只知道来自 Windows.Foundation.UniversalApiContract.dll 的Windows.UI.Xaml.Media.SolidColorBrush,即使它们具有相同的方法、相同的参数甚至相同的实现,它们也是不同的。

    更糟糕的是,因为您的 ViewModel 需要 PresentationCore.dll,它必然绑定到 .NET 3.x 或 4.x,而 UWP 是基于 WinRT/Core Framework。

    这是一个紧耦合。现在假设您还想使用 Xamarin(基于单声道的跨平台 .NET 框架)并且 SolidColorBrush 在即 Xamarin.Forms.dll 中(我没有使用过 Xamarin,我不确定它是否有这样的名字)。

    Linux/Mono 版本怎么样?单声道上没有 WPF。控制台应用程序?他们甚至不使用 UI 元素。

    然后你不能绑定它,你最终会复制你的 ViewModel 并复制你的演示逻辑等。

    通过您的“MVVM”方法,您提高了可测试性,但没有归档可重用性和解耦。

    没有规范告诉您:“必须这样做。”。 MVVM 没有规范,它是一种(架构)模式。

    对于上述示例,如果您需要确定颜色,请使用非 ui 特定类型(stringColor 或您自己的颜色类/结构实现)。

    对于视图,您实现了一个“IValueConverter”(例如参见this answer)。

    现在您拥有可以重复使用的漂亮、解耦的代码,并且每个 UI 平台都可以以自己的方式处理颜色。

    而且只需几行代码就可以直接返回SolidColorBrush。最重要的是,您可以在任何地方以及在您创建的每个应用程序中重用ColorToSolidColorBrushValueConverterColorToSolidColorBrushValueConverter 不依赖于您的特定应用程序,您的应用程序/视图模型也不依赖于它。

    写出好的代码并不难,你只需要尝试一下;)

    【讨论】:

    • 通常情况下,您不会/不能在没有条件编译的情况下在 WPF 和 UWP 应用程序之间共享源代码。此外,并非每个视图模型都将用作跨平台。因此,如果我编写 WPF 应用程序,我可以使用对 PresentationFramework 和System.Windows.Media 的引用。如果我编写跨平台的东西,我要么使用一些条件编译,要么将特定于平台的代码放在其他地方。无论如何,这取决于正在编写的项目。
    • @Tseng 你为什么把MVVM放在中心,兜兜转转。问题很简单,就是他们的任何耦合?可能有数百万种不同的方法来设计比 MVVM 或更改 MVVM 更好,但这不是这里的范围。
    • 实现一个简单的IValueConverter 并删除SolidColorBrush 引用并不难。出于完全相同的原因,有一个开箱即用的转换器用于 bool 到可见性(因为可见性只对 WPF 有意义)msdn.microsoft.com/en-us/library/…
    • 因为问题被标记为 MVVM 而不仅仅是 WPF。对于纯 WPF 应用程序,您的答案还可以(即使是您编辑之前的答案)。但是当有人提出问题并将其标记为 MVVM 时,他希望得到符合 MVVM 的答案。而不是接受这一点,你只会让人感到困惑,无法接受在该领域有更多经验的人的答案。而不是仅仅学习如何正确应用 MVVM,您只需继续交谈
    • @Tseng 你又来了。不回答我问的。我现在已经看到了你的思维过程,所以没有必要再听你的了。你现在最好拿出一些关于它的好博客/文章。如果我能从中学到一些东西,我会非常高兴。只是为了您的缘故,问题是“如何有任何违反 MVVM 的耦合?”
    【解决方案3】:

    有时 MVVM 看起来像是具有自己趋势的宗教。 :)

    以下是 MVVM 教派成员之间圣战的主题:

    • 先查看与先查看模型;
    • 不要从视图模型中公开PresentationFramework/WindowsBase 类型;
    • 做/不通过您的视图模型公开模型,并将视图直接绑定到模型;
    • 转换器与视图模型属性;
    • 在视图模型中聚合模型/将模型数据映射到视图模型;
    • 使用事件聚合器/使用服务。

    最危险的是“纯 MVVM”狂热分子。没有人确切知道什么是“纯 MVVM”,但如果你违背了他们的信念,他们就准备好烧死你了。

    MVVM 只是希望您将视图 logic 与视图模型 logic 分开。
    仅此而已

    上面的列表只是一组方法,而不是教条。而且,实际上,它们都适合 MVVM。使用或不使用只是方便和当前项目架构的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-13
      • 1970-01-01
      • 2011-08-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多