Should a ViewModel in MVVM reference the View?

后端 未结 4 476
生来不讨喜
生来不讨喜 2020-12-10 03:27

In the MVVM (Model-View-ViewModel) pattern should the ViewModel reference the view. I would think that it should not. But how should the following scenario be handeled? I ha

相关标签:
4条回答
  • 2020-12-10 04:03

    I find that it's often a helpful compromise to expose an interface on the View that handles View-specific functionality. This is a good way to handle things that are awkward to accomplish with pure binding, such as instructing the form to close, opening a file dialog (though this often gets put in its own service interface) or interacting with controls not designed well for data binding (such as the example you provided.)

    Using an interface still keeps the View and ViewModel largely decoupled and enables you to mock the specific IView during testing.

    0 讨论(0)
  • 2020-12-10 04:21

    In "pure" MVVM, the ViewModel shouldn't really reference the View. It's often convenient, however, to provide some form of interface in the View whereby the ViewModel can interact with it.

    However, I've found that I almost never do that anymore. The alternative approach is to use some form of attached property or blend behavior within your View, and bind it to your ViewModel properties. This allows you to keep the View logic 100% within the View. In addition, by creating a behavior for this, you create a reusable type that can be used to handle this in every ViewModel->View interaction. I strongly prefer this approach over having any View logic within the ViewModel.

    In order to demonstrate this technique, I wrote a sample for the Expression Code Gallery called WindowCloseBehavior. It demonstrates how you can use a Behavior within the View bound to properties in the ViewModel to handle controlling a Window's life-cycle, including preventing it from being closed, etc.

    0 讨论(0)
  • 2020-12-10 04:23

    Reed and Dan covered the general approach but in reference to your specific case, TabControl is an ItemsControl and so can bind its ItemsSource to a data collection in your ViewModel representing the set of tabs to display. The UI for each type of tab can then be represented by a DataTemplate specific to the data type of an item (either using DataType or a DataTemplateSelector). You can then add or remove data items as needed from your VM and have the tabs update automatically without the VM knowing anything about the TabControl.

    0 讨论(0)
  • 2020-12-10 04:28

    One of us is missing something obvious. Your tab control is an ItemsControl. You should bind the ItemsSource of your tab control to an ovservable collection in your view model. When you handle the command in your view model to add a tab, you simply add a new element to this collection and, voila, you've added a new tab to the control.

    0 讨论(0)
提交回复
热议问题