首页 > 解决方案 > MVVM 事件处理程序属于哪里

问题描述

我正在编写一个简单的 MVVM 应用程序来研究正确的代码设计。完成它需要一段时间,但事情进展顺利。

我有一个关于如何处理事件的问题,以及代码应该放在 ViewModel 中还是放在代码隐藏中。

首先,绑定事件有2种技术,一种是使用Blend Interactivity DLL绑定到一个命令,另一种是使用MethodBindingExtension类。

使用交互 DLL,它允许使用 EventArgs 转换器将事件参数转换为与 UI 无关的类型,该类型仅包含我们需要的数据。我不认为 MethodBindingExtension 这样做,但它更灵活。但是,当您需要设置事件参数值时,我想这个事件参数转换器将无济于事?(或者它可能允许将值转换回来,尚未检查这些类)

我喜欢使用 MethodBindingExtension,现在我的 ViewModel 中有这段代码。我不喜欢它的是我正在使用特定的 UI 类型,目前这没什么大不了的,但从理论上讲,也许它可以改进。

我该怎么办?将其移动到代码隐藏中?将其保留在 ViewModel 中并使用 args 转换器?就这样放着?

public void Window_DropFile(DragEventArgs e) {
    if (e.Data.GetDataPresent(DataFormats.FileDrop)) {
        string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
        foreach (string file in files) {
            ReadScriptFile(file);
        }
    }
}

public void Window_PreviewDragOver(DragEventArgs e) {
    e.Effects = DragDropEffects.All;
    e.Handled = true;
}

public void Header_PreviewLeftMouseButtonDown(IScriptViewModel sender, MouseButtonEventArgs e) {
    if (sender == SelectedItem && sender.CanEditHeader && !sender.IsEditingHeader) {
        sender.IsEditingHeader = true;
        e.Handled = true;
    }
}

标签: c#wpfmvvmevent-handling

解决方案


一般来说:

您的 MVVM 视图模型应该只包含数据和命令。当然有很多例外,但请记住,基本上,它应该只包含与视图相关的命令和项目。

当事件处理程序应用于组件时,我看到很多关于此的困惑。事情是; 当您在视图模型中放置 UI 组件的事件处理程序时,视图模型将绑定到视图的实际实现(使用 UI 组件),而不是一般的“视图”。

根据经验; 你应该能够复制过去的视图模型并在另一个实现中使用它,它应该只是编译。它不应该包含对 UI 元素本身的引用,或者通过事件处理等间接引用。


所以,是的,您应该将这些事件处理程序放在代码隐藏中,或者在视图/XAML 中找到能够处理它的框架或组件。从这样的事件中调用命令完全没问题。更实用的方法是:将它们放在最有效的地方,并使您的代码最易读/可维护的地方。如果您了解 MVVM 的概念,您将最大限度地减少这些混合模型的出现,这通常已经足够好了。


推荐阅读