wpfmvvm实现

wpfmvvm实现,wpf,mvvm,Wpf,Mvvm,我刚刚开始在MVVM模式中使用WPF。我已经阅读了一些与MVVM相关的资料 然而,我必须处理的项目有一个MVVM的实现,它似乎与我读到的非常不同(可能也不正确,不确定) 该实现将所有视图(控件或窗口)实现为ResourceDictionary,其中视图中的所有控件都位于“Style”元素中 此类ResourceDictionary的代码具有所有DependencyProperty和命令(ViewModel没有其他类)。此外,这些类(代码隐藏)如何继承Windows.Controls.Contro

我刚刚开始在MVVM模式中使用
WPF
。我已经阅读了一些与MVVM相关的资料

然而,我必须处理的项目有一个MVVM的实现,它似乎与我读到的非常不同(可能也不正确,不确定)

该实现将所有视图(控件或窗口)实现为ResourceDictionary,其中视图中的所有控件都位于“Style”元素中

此类ResourceDictionary的代码具有所有DependencyProperty和命令(ViewModel没有其他类)。此外,这些类(代码隐藏)如何继承Windows.Controls.Control类

这是正确的实现吗?如果不是,您认为这是错误实现的原因是什么

我可能错了,但我看到的原因如下:

  • 将视图实现为
    ResourceDictionary
    是不正确的,并且资源不用于创建自定义视图
  • 在代码隐藏中包含最少的代码是MVVM的一个重要方面,它允许松散耦合的体系结构
  • 由于所有视图都继承自Windows.Controls.Control,因此很难为这些视图编写单元测试用例
  • 我是正确的还是有其他一些原因导致此实现不正确(或者我是错误的,这可能是在
    WPF
    中实现MVVM的一种方法)

    非常感谢你的意见

    下面是一个示例代码:(XAML)

    
    

    代码隐藏:

    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Input;
    
    namespace Presentation
    {
        /// <summary>
        /// View-model
        /// </summary>
        public class FirstControl : Control
        {
            static FirstControl()
            {
                DefaultStyleKeyProperty.OverrideMetadata(typeof(FirstControl), new FrameworkPropertyMetadata(typeof(FirstControl)));
            }
    
            public FirstControl()
            {
                CloseCommand = new DelegateCommand(OnCloseCommand);
            }
    
            private void OnCloseCommand()
            {
                // Write code to close application.
            }
    
            public static readonly DependencyProperty CloseCommandProperty = DependencyProperty.Register("CloseCommand", typeof(ICommand), typeof(FirstControl));
            public ICommand CloseCommand
            {
                get { return (ICommand)GetValue(CloseCommandProperty); }
                set { SetValue(CloseCommandProperty, value); }
            }
        }
    }
    
    使用系统;
    使用System.Collections.Generic;
    利用制度全球化;
    使用System.Windows;
    使用System.Windows.Controls;
    使用System.Windows.Data;
    使用System.Windows.Input;
    名称空间表示
    {
    /// 
    ///视图模型
    /// 
    公共类控件:控件
    {
    静态控制()
    {
    OverrideMetadata(typeof(FirstControl),new FrameworkPropertyMetadata(typeof(FirstControl));
    }
    公共控制()
    {
    CloseCommand=新的DelegateCommand(OnCloseCommand);
    }
    私有void OnCloseCommand()
    {
    //编写代码关闭应用程序。
    }
    public static readonly dependencProperty CloseCommandProperty=dependencProperty.Register(“CloseCommand”、typeof(ICommand)、typeof(FirstControl));
    公共ICommand CloseCommand
    {
    获取{return(ICommand)GetValue(CloseCommandProperty);}
    set{SetValue(CloseCommandProperty,value);}
    }
    }
    }
    
    希望这有帮助


    DelegateCommand
    是一个允许将命令逻辑委托给作为参数传递的方法的类。

    MVVM的主要目的是允许在不需要“更高”层的情况下对每个层进行全面测试

    您应该能够测试模型,并且在该测试中,您应该能够成功地完成从数据存储中发送和检索数据所需的所有任务。您的模型测试不需要任何视图或视图模型来完成


    您应该能够在不需要任何UI代码或其他视图级代码的情况下测试视图模型。视图模型应该能够在逻辑上完成应用程序需要完成的所有操作,而无需任何用户交互或UI代码。理想情况下,您应该能够使用提供可预测响应的模拟模型类测试ViewModel。

    发布一些示例代码和XAML,我们可以告诉您什么是错的,什么是对的。否则,这只是猜测,我认为将视图放入
    资源字典
    没有任何错误。视图层只是告诉WPF如何绘制不同的应用程序片段(视图模型
    ViewModels
    ),如何存储视图并不重要。但是需要考虑的是,在视图层中是否有应用程序/业务逻辑。在视图后面有特定于UI的代码没有什么错,但是在视图后面的代码中不应该有应用程序逻辑,例如单击命令或应用程序数据。那东西应该在你的房间里ViewModels@Rachel如果你看不到任何问题,只在一个文件中放几十个视图,那么你看不到超过几百行的函数有问题,你看不到无法维护的代码有问题,那么你看不到像病毒一样大量增长的坏代码的问题,不断增长的坏代码,直到它只是一个肿瘤,但数百名开发人员。然后你仍然看不到问题:你从未见过,也不关心。-1:不,MVVM的要点不是测试。这是职责的分离。@StephaneRolland你和我有不同的优先权。SoC导致了可测试代码——对于一个有TDD背景的人来说,SoR如果不可测试就意味着什么。如果责任不分开,你知道代码不容易模仿,所以不可测试。所以你理解我的观点。@StephaneRolland我理解你的观点,只是不理解反对票。如果你有更好的答案,就把它贴出来。
    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Input;
    
    namespace Presentation
    {
        /// <summary>
        /// View-model
        /// </summary>
        public class FirstControl : Control
        {
            static FirstControl()
            {
                DefaultStyleKeyProperty.OverrideMetadata(typeof(FirstControl), new FrameworkPropertyMetadata(typeof(FirstControl)));
            }
    
            public FirstControl()
            {
                CloseCommand = new DelegateCommand(OnCloseCommand);
            }
    
            private void OnCloseCommand()
            {
                // Write code to close application.
            }
    
            public static readonly DependencyProperty CloseCommandProperty = DependencyProperty.Register("CloseCommand", typeof(ICommand), typeof(FirstControl));
            public ICommand CloseCommand
            {
                get { return (ICommand)GetValue(CloseCommandProperty); }
                set { SetValue(CloseCommandProperty, value); }
            }
        }
    }