简体   繁体   中英

MVVM ViewModel interacting with View, is it true MVVM?

Lets say for example we have a single WPF window with 2 tabs and a file menu. The file menu has two items "Hide Tab 1", "Show Tab 1"

The program then has the following classes: MainView.xaml

MainViewModel.cs

"Hide tab 1" menu command is then bound to HideTab1Command which is contained within MainViewModel.cs

HideTab1 then directly interacts with the View to hide tab1 from within the ViewModel.

Is this technically not MVVM behaviour (more like MVP)? Eg for true MVVM the functionality to perform this behavior should be contained entirely in XAML code or in "code behind" within MainView.xaml.cs ?

I see MVVM applications and examples that do this all the time, however it seems to break the SRP (Single Responsibility Principle).

I see some other applications that do the same with the HideTab1 command simply notifying the view via an interface IMainView which then calls code within MainView.xaml.cs

Whilst I can see that the code is now within the View how is this really any different from the first example? The SRP is still voided with the ViewModel telling the View what to do.

Are either of these examples true MVVM patterns and if not what would be the correct MVVM pattern to achieve hiding/showing "tab 1".

Please forgive any misunderstandings of what MVVM/MVP are, I am doing my best to learn these design patterns correctly.

Example: ShowTab1 is a command that then directly manipulates the View. I see this in MVVM projects all the time (Lots of DevExpress examples) yet it does not appear to have any of the benefits of MVVM as your ViewModel is directly manipulating your view.

MainWindow.xaml

<Window x:Class="WpfApplication.MainWindow"
    ...
        <Button Content="Show hidden panels"   Command="{Binding ShowTab1}"/>
        ...
        <TabGroup>...
    ...
</Window>

MainWindowViewMode.cs

public class MainViewModel 
{
    IMainView mainView;
    public MainViewModel()
    {
        ShowTab1 = new ShowTab1Command(this);
        mainView = ... (set this to a reference to the view)
    }

    public ICommand ShowTab1 { get; set; }
}

public class ShowTab1Command: ICommand
{
    private readonly MainViewModel _model;
    public ShowTab1Command(MainViewModel model)
    {
        _model = model;            
    }
    void ICommand.Execute(object parameter)
    {
         _model.mainView.TabGroup1MakeVisible();
    }
    bool ICommand.CanExecute(object parameter)
    {
        return true;
    }

        public event EventHandler CanExecuteChanged;

   public interface IMainView{
       public void TabGroup1MakeVisible();

A true MVVM would have a ViewModel purely for converting data into the DataContext that the view expects. All view manipulation would be done in the View eg in CodeBehind or XAML. Or is this incorrect?

HideTab1 then directly interacts with the View to hide tab1 from within the ViewModel.

This is where the program 'breaks' MVVM. A proper solution would be to have the command change a property on the ViewModel, say: ShowTab1

In the view you would bind the Visibility (using a value converter) or IsEnabled to this property.

This way the ViewModel doesn't interact with the View directly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM