-1

我刚刚开始使用WPFMVVM 模式。我浏览了一些与 MVVM 相关的材料。

但是,我必须从事的项目有一个 MVVM 的实现,它似乎与我读过的非常不同(可能也不正确,不确定)。

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

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

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

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

  1. 实现视图ResourceDictionary是不正确的,资源不是用于创建自定义视图。
  2. 在后面的代码中包含最少的代码是 MVVM 的重要方面之一,它允许松散耦合的架构。
  3. 由于所有视图都继承自 Windows.Controls.Control,因此为视图编写单元测试用例会很困难。

我是正确的还是有其他一些原因导致这个实现不正确(或者我错了,这可能是在 MVVM 中实现 MVVM 的一种方式WPF)。

您的意见受到高度赞赏。

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

<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Presentation"
>
<Style TargetType="{x:Type local:FirstControl}">
    <Setter Property="IsTabStop" Value="False"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:FirstControl}">
                <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" Height="490" DataContext="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Mode=OneTime}">
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="TEST TEXT" FontWeight="DemiBold"/>

                        <Button Command="{Binding Path=CloseCommand, Mode=OneTime}"
                                        Width="48" Height="30"/>
                    </StackPanel>
                </ScrollViewer>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

代码背后:

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); }
        }
    }
}

希望这可以帮助。

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

4

1 回答 1

2

MVVM 的主要目的是让每一层都得到充分的测试,而不需要“更高”的层。

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

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

于 2013-03-11T18:08:59.180 回答