MVVM + ViewModel 调用的 View 特定功能的实现

2024-01-28

这是我想解决的“问题”:

我有许多“仅查看”特定功能,例如:

  • 在运行时更改视图的资源字典(用于将皮肤从黑色更改为蓝色或其他)
  • 保存和恢复 查看特定设置,例如视图大小或用户设置的网格属性
  • ...

所有这些功能都与 ViewModel 无关,因为它们实际上是特定于视图的,并且可能只适合 ViewModel 的一个客户端(视图)(在 ViewModel 拥有多个客户端的情况下)。上面的示例只是我想要实现的大量功能中的两个,因此我需要一个更通用的解决方案,而不是仅适合这两个示例的解决方案。

在考虑解决方案时,我想到了以下两种方法

  • 创建一个继承自 DependancyObject 的 ViewBase。我不喜欢这个解决方案,因为它在某种程度上打破了 MVVM 模式的理念,其中视图没有隐藏代码。为了调用这个方法,我需要在我的 ViewModel 中引用 View,这也否定了关注点分离的想法。
  • 创建 IView 界面。和第一种方法一样脏。每个View都需要实现IView,因此有后台代码。 ViewModel 还需要“以某种方式”知道 IView 实现来调用其方法
  • 将 ViewModel 的属性绑定到视图的触发器、行为、命令。这种方法似乎是最好的,但我认为我的运行速度会受到使用限制,因为某些功能可能无法使用这种方法。例如,仅将资源字典绑定到视图可能不起作用,因为需要合并才能正确显示新资源。再说一次......我只能查看 ViewModel 中的特定功能/信息(如资源字典),但只有 ViewModel 的特定客户端使用此属性。

如果你们中的任何人已经遇到了同样的问题,并且为我的问题找到了一个智能/流畅(并且大部分是通用的;))解决方案,那就太好了。

谢谢


在不引入 View 和 ViewModel 之间耦合的情况下,最简单的方法是使用 Messenger(在某些框架中也称为 Mediator)。 ViewModel 只是广播“更改主题”消息,而 View 则订阅该消息。使用MessengerMVVM Light 的课程,你可以按照这些思路做一些事情:

消息定义

public class ThemeChangeMessage
{
    private readonly string _themeName;
    public ThemeChangeMessage(string themeName)
    {
        _themeName = themeName;
    }

    public string ThemeName { get { return _themeName; } }
}

视图模型

Messenger.Default.Send(new ThemeChangeMessage("TheNewTheme");

查看隐藏代码

public MyView()
{
    InitializeComponent();
    Messenger.Defaut.Register<ThemeChangeMessage>(ChangeTheme);
}

private void ChangeTheme(ThemeChangeMessage msg)
{
    ApplyNewTheme(msg.ThemeName);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MVVM + ViewModel 调用的 View 特定功能的实现 的相关文章

随机推荐