MVVM ViewModel范围

时间:2011-02-25 23:27:48

标签: wpf mvvm

我还是MVVM的新手并且有一个问题。

我的观点非常复杂。它将有一些图表,网格,组合框等。其中一些将绑定到不同的数据。我的理解是每个视图都有一个与之关联的视图模型。因此,在这种情况下,我的视图模型最终将变得非常大,因为它需要具有视图中的每个组件将绑定到的数据。如果视图很复杂,这就是它必须的方式吗?

此外,我习惯于在控件中添加事件处理程序,只是处理事件。在MVVM方式中,我该如何处理事件?例如,我一直坚持如何以MVVM方式正确处理图表的鼠标移动事件或网格选择更改事件。

感谢您的任何提示。

4 个答案:

答案 0 :(得分:2)

我部分同意@Rich和@Elad Katz。在我们的应用程序中,我们使用MainViewModel,它具有表示子ViewModel的属性。如

public class MainViewMod
{
    public SomeViewModel ContentViewModel
    {
         get;
         set;
    }
    public StatusBarViewModel StatusBarViewModel
    {
         get;
         set;
    }
}

MainView从MainView获取它的DataContext。假设MainView是一个窗口,它有一个<ContentControl Content="{Binding ContentViewModel}" /><ContentControl Content="{Binding StatusBarViewModel}" />

不同的ContentControls在MainView的可视化树内“实时”存在。

不同的ViewModel不需要彼此了解。只要viewModel之间的关系松散,我就不会发现子视图模型存在问题。我的经验法则是StatusViewModel可以访问MainViewModel。在某些情况下,StatusViewModel可以访问ContentViewModel,但只能通过MainViewModel,但要保持最低限度。但请记住@Elad所说的不要让他们彼此依赖太多。

说到事件,我在ViewModel中直接访问evens所需的场景并不多。假设您有一个包含listView的视图,您需要获取或设置所选项目。在这种情况下,我会向ViewModel添加一个属性,即SelectedItem,并将该属性绑定到listviews的SelectedItem。这样,youg可以从viewmodel访问所选项目。

请记住,视图的代码隐藏没有问题。在某些情况下,您必须使用代码隐藏。但是,我建议不要在代码隐藏中订阅事件,因为它们很难找到(比如20个视图中有一个有代码隐藏,因此查找代码隐藏任何视图以找到任何代码都是不自然的在那里了解正在发生的事情)。如果对元素使用事件,请使用其他答案中提到的命令绑定,或者在XAML中订阅事件。在某些情况下,如果我需要访问viewmodel,我更喜欢使用附加行为。

答案 1 :(得分:1)

通常,如果ViewModel太大,则表明您的视图分离不够好,并且您应该使用多个View&amp; ViewModel来处理这种情况。

我实际上建议反对@Rich关于子视图模型的内容。我已经看过很多次使用它并且它很受欢迎,但我认为虽然它保留了MVVM背后的想法,但它在更大的方案中没有帮助,即ViewModel变得彼此依赖。 ViewModels应尽可能彼此分开,就像是应用程序中的唯一内容一样。

答案 2 :(得分:0)

事件通常通过绑定到ICommand来处理。由于控件上通常只有一组有限的属性可以绑定到ICommand,因此有一些框架允许您动态地将操作附加到您将使用事件的命令。我使用了AttachedCommandBehavior,效果很好。如果这对你不起作用,我相信还有其他人。

就过度生长的ViewModel问题而言,您可以经常在另一个视图中使用子ViewModel。例如,如果您有列表控件,则它们通常可以绑定到绑定到外部定义的DataTemplate的更轻量级ViewModel的集合。当您的代码文件失去控制时,这通常可以很好地分离。

答案 3 :(得分:0)

创建一个可以集中其他虚拟机的viewModel是我认为是一个例外的选择。 MVVM可以使用 Mediator 设计模式,这是一种行为模式,致力于在两个对象(view和viewModel)之间传输数据并可以根据所需逻辑代表它们执行方法。 中介者模式可以在处理视图对其绑定/观察的响应时保持对ViewModel的关注。