c# - 让 ViewModel 调用 Actions 而不是执行命令和发布事件?

标签 c# mvvm

在这个假设的问题中,假设 ViewModel 发布了一个 View 订阅的相当复杂的事件。然后, View 根据该事件中的状态操作多个屏幕元素。例如,使几个按钮可见/隐藏,或启用/禁用,或者可能启动 Storyboard。

// purely as an example:
public class SomeEvent
{
    public bool ShouldShowAddButton { get; set; }

    public bool ShouldShowDeleteButton { get; set; }

    public bool AddButtonEnabled { get; set; }

    public bool DeleteButtonEnabled { get; set; }
}

由于虚拟机对 View 一无所知,因此它实际上无法进入并执行这些操作,而是依赖于事件。我认为标准的 MVVM 实践。 (另一种选择是让这些项目中的每一个都成为自己发布的事件,一个接一个地发送。)

但是,如果 VM 可以在不了解 View 的情况下调用 View 怎么办?
public class MyViewModel
{
    public Action OnShowAddButton { get; set; }
    public Action OnShowDeleteButton { get; set; }
    ...etc

    private void OnSomeStateChange()
    {
        // here, we'd normally publish the SomeEvent class
        // instead, we could just call OnShowAddButton (or whatever) instead
    }
}

public class MyView
{
    public MyView()
    {
        this.myViewModel.OnShowAddButton = () => ...;
        ...etc
    }
}

除了不是 MVVM 设计的“典型”之外,是否有理由对此表示不满?据我所知,它仍然保持正确的分离水平。

最佳答案

我认为这种变体将一点 MVC 与一点 MVVM 混合在一起,尽管两者都不是。所以,Model-View通过将模型直接注入(inject) View 实现,然后通过事件发送某种命令,在您的提案中解决了部分模式。

然后您需要解决或绕过View-Model通过在模型中提供可以由 View 直接设置的属性,或者通过在 View 中公开一些事件并在模型中执行相同类型的注入(inject)来实现模式的一部分。

我认为它会变得丑陋。即使模型只是一组可观察的实体并且您从其他地方控制它们( Controller ?:))。

我已经可以看到代码,无数的事件和属性混合在一起......但这一切都取决于你的 UI 将变得多复杂,你将拥有多少 View 以及它们将变得多复杂。在具有 10 多个按钮和/或输入的 View 中,我认为采用这种方法是一个坏主意。

我说,只要您没有专用的 MVVM 基础架构,例如 WPF 或 HTML,就没有必要实现自己的基础架构。仅使用手动编码的框架是无法达到如此美妙的分离程度的。您需要一些支持才能将 UI 代码与模型完全分离、进行绑定(bind)等。

也许您可以对要使用它的内容发表更多评论。如果您需要它用于客户端框架(如 HTML/JS)或 Windows 窗体实现,那么可能有一些您可以使用的专用解决方案,或者更好的是,您可以采用一些更简单的方法。

这一切都来自一个在 ASP.NET Web 窗体之上实现了 MVP 变体的人。如果我只能让时间倒流。

关于c# - 让 ViewModel 调用 Actions 而不是执行命令和发布事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16778780/

相关文章:

c# - C#中开启泛型类型继承动态识别

c# - 如果我不处置我的 IDataReader,我的连接是否会返回到池中?

c# - 多个 if 语句或 else-if 语句

c# - 如何访问另一个控件的 viewModel

wpf - WPF DataGrid 中的动态列生成

c# - 在 C# 中,如何根据这些对象的一个​​或多个属性比较两个对象列表?

c# - 使用 AudioVideoCaptureDevice 在 Windows Phone 8 中显示当前视频?

mvvm - 如何在ListView Xamarin表单中检测可点击标签的位置

c# - 在 WPF 中的远程桌面连接 (RDP) 后重新加载 View

c# - IDataErrorInfo 结合 MVVM Light 消息重新附加