MVVM ViewModel与View交互,是真正的MVVM吗?

rol*_*lls 2 c# wpf mvp design-patterns mvvm

让我们说例如我们有一个带有2个选项卡和一个文件菜单的WPF窗口.文件菜单有两个项目"隐藏选项卡1","显示选项卡1"

然后该程序具有以下类:MainView.xaml

MainViewModel.cs

然后将"隐藏选项卡1"菜单命令绑定到MainViewModel.cs中包含的HideTab1Command

然后,HideTab1直接与视图交互以隐藏ViewModel中的tab1.

这在技术上不是MVVM行为(更像是MVP)吗?例如,对于真正的MVVM,执行此行为的功能应完全包含在XAML代码中或MainView.xaml.cs中的"代码隐藏"中?

我看到MVVM应用程序和示例一直这样做,但它似乎打破了SRP(单一责任原则).

我看到一些其他应用程序使用HideTab1命令执行相同的操作,只需通过接口IMainView通知视图,然后调用MainView.xaml.cs中的代码

虽然我可以看到代码现在在View中,但这与第一个例子有什么不同?SRM仍然无效,ViewModel告诉View该做什么.

这些示例中的任何一个都是真正的MVVM模式,如果不是,那么实现隐藏/显示"选项卡1"的正确MVVM模式是什么.

请原谅任何对MVVM/MVP的误解,我正在尽力正确地学习这些设计模式.

示例:ShowTab1是一个命令,然后直接操作View.我一直在MVVM项目中看到这一点(许多DevExpress示例)但它似乎没有MVVM的任何好处,因为您的ViewModel直接操纵您的视图.

MainWindow.xaml

<Window x:Class="WpfApplication.MainWindow"
    ...
        <Button Content="Show hidden panels"   Command="{Binding ShowTab1}"/>
        ...
        <TabGroup>...
    ...
</Window>
Run Code Online (Sandbox Code Playgroud)

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();
Run Code Online (Sandbox Code Playgroud)

真正的MVVM将具有ViewModel,仅用于将数据转换为视图所期望的DataContext.所有视图操作都将在View中完成,例如在CodeBehind或XAML中.或者这是不正确的?

Ern*_*rno 5

然后,HideTab1直接与视图交互以隐藏ViewModel中的tab1.

这是程序"打破"MVVM的地方.一个合适的解决方案是让命令更改ViewModel上的属性,例如:ShowTab1

在视图中,您可以将Visibility(使用值转换器)或IsEnabled绑定到此属性.

这样,ViewModel不会直接与View交互.

  • @rolls - 因为视图中的(单元)测试代码非常难.所以我们尽量避免在视图中使用代码. (2认同)
  • @rolls 1.更改视图可以在视图模型的重大更改中完成.这是因为您没有按名称引用控件.2.查看代码很快变得比查看模型代码更复杂.绑定,状态和动画系统有助于查看模型保持简单.3. MVVM允许您编写应用程序级代码,而无需考虑视图的行为. (2认同)