WPF MVVM实现

时间:2013-03-11 16:44:22

标签: wpf mvvm

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

但是,我必须处理的项目有一个MVVM的实现,看起来与我读过的非常不同(也许不正确,不确定)。

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

此类ResourceDictionary背后的代码包含所有DependencyProperty和Commands(ViewModel没有其他类)。此外,类(后面的代码)有些如何从Windows.Controls.Control类继承。

这是正确的实施吗?如果不是,你认为这是什么原因证明这是一个错误的实施。

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

  1. 将视图实现为ResourceDictionary不正确,而资源不适用于创建自定义视图。
  2. 代码背后的代码最少是MVVM的一个重要方面,它允许松散耦合的架构。
  3. 由于所有视图都继承自Windows.Controls.Control,因此编写视图的单元测试用例会很困难。
  4. 我是否正确或有其他原因导致此实现不正确(或者我错了,这可能是在WPF中实现MVVM的一种方式。)

    非常感谢您的观点。

    以下是示例代码:(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是一个允许将命令逻辑委托给作为参数传递的方法的类。

1 个答案:

答案 0 :(得分:2)

MVVM的主要目的是允许对每一层进行全面测试,而无需“更高”的层。

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

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