MVVM在系统中如何应用实现

MVVM在TOPWELL中的应用

MVVM概念

MVVM严格来说,并不是一种框架,而是一个设计的模式

MVVM即model(实体)+View(界面)+ViewModel(逻辑),model层负责建立数据实体,保障数据加载,是View中数据绑定的基本元素(但不是说View中去绑定Model实例)。View层不多说,强烈建议使用Microsoft Expression Blend进行界面设计,所有的数据展示及事件都采用绑定形式,这样设计人员就与开发人员彻底分离了。ViewModel层是联系View层与Model层的桥梁,View层所有的数据绑定都直接指向ViewModel。这里的model, View , ViewModel都是客户端silverlight应用,可以建立多个silverlight应用库项目已进行系统结构上的分割。

MVVM优点

MVVM模式和MVC模式一样,主要目的是分离视图(View)和模型(Model)。

  • 1. 低耦合。视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的"View"上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。
  • 2. 可重用性。你可以把一些视图逻辑放在一个ViewModel里面,让很多view重用这段视图逻辑。
  • 3. 独立开发。开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页面设计,使用Expression Blend可以很容易设计界面并生成xaml代码。
  • 4. 可测试。界面素来是比较难于测试的,而现在测试可以针对ViewModel来写

MVVM在TOPWELL的应用

首先开发环境要安装VS2012 然后再安装MVVMLIght Tookit 开发工具。

1.新建项目->Silverlight->MVVM->SimpleMVVMSilverlight

 

2.新的解决方案会生成一个MVVM架构的程序

 

3.MVVM架构的实现

1.Model

l  新建一个Models文件夹(如果项目里没有的话)当然在MVVMLight里已经创建好Model文件夹了。

l  创建一个Model类并且继承ModelBase<TModel>

public class Customer : ModelBase[d1] <Customer>

l  用MVVMprop代码段插入支持双向的数据绑定的属性们。

 

   public int CustomerId

        {

            get { return _customerId; }

            set

            {

                _customerId = value;

                NotifyPropertyChanged(m => m.CustomerId);[d2] 

            }

        }

 

2.Service

创建一个服务代理接口里面包含的方法包括删除、修改、查询、插入(CRUD),把它放在

Services文件夹里。

public interface IItemListServiceAgent[d3] 

    {

        // 查询

        void GetItems(Action<List<Item>, Exception> completed);

 

        // 插入

        void AddItem(Item item);

 

        // 删除

        void RemoveItem(Item item);

 

        // 保存

        void SaveChanges(Action<Exception> completed);

 

        // 撤销

        void RejectChanges();

    }

创建一个实现服务代理接口的类,把它添加到Services文件夹里。

 

[ServiceAgentExport(typeof(IItemListServiceAgent), AgentType = AgentType.Mock)]

    public class MockItemListServiceAgent [d4] : IItemListServiceAgent

    {

        // 模拟数据

        List<Item> mockItems = MockItems.GetItems();

 

        // 查询

        public void GetItems(Action<List<Item>, Exception> completed)

        {

     

            var bw = new BackgroundWorker();

 

            bw.DoWork += (s, ea) =>

                {

                    Thread.Sleep(TimeSpan.FromSeconds(2));

 

                    ea.Result = mockItems;

                };

 

            bw.RunWorkerCompleted += (s, ea) =>

                {

                    if (ea.Error != null)

                        completed(null, ea.Error);

                    else

                        completed((List<Item>)ea.Result, null);

                };

 

            bw.RunWorkerAsync();

        }

 

        // 插入

        public void AddItem(Item item)

        {

            mockItems.Add(item);

        }

 

        //删除

        public void RemoveItem(Item item)

        {

            mockItems.Remove(item);

        }

 

        // TODO: 实现保存

        public void SaveChanges(Action<Exception> completed)

        {

            MessageBox.Show("SaveChanges not implemented");

        }

 

        // TODO: 实现撤销

        public void RejectChanges()

        {

            MessageBox.Show("RejectChanges not implemented");

        }

    }

3.ViewModel

新建一个类派生于ViewModelBase<TViewModel>或ViewModelDetailBase

   <TViewModel, TModel>到ViewModels文件夹里。

l  把服务接口代理给构造函数

l  调用服务代理的方法来执行CRUD操作

l  也可以添加一个绑定的属性

 public class CustomerViewModel [d5] : ViewModelDetailBase<CustomerViewModel,     Customer>

    {

        // 构造函数

        public CustomerViewModel() { }

 

        //定义服务代理接口

        ICustomerServiceAgent serviceAgent;

 

        public CustomerViewModel(ICustomerServiceAgent serviceAgent)

        {

            this.serviceAgent = serviceAgent;

        }

 

         //数据集

        private ObservableCollection[d6] < Customer > items;

        public ObservableCollection< Customer > Items

        {

            get { return items; }

            set

            {

                items = value;

                NotifyPropertyChanged(m => m.Items);

            }

        }

        // 显示层要绑定的方法

        public void NewCustomer()

        {

            base.Model = serviceAgent.CreateCustomer();

        }

 

    }

 

4.Locator

用MvvMLocator代码段来添加需要代理的ViewModels到Locators文件夹。

 

  public class ViewModelLocator[d7] 

    {

        // 根据需求创建CustomerViewModel

        public CustomerViewModel CustomerViewModel

        {

            get

            {

              ICustomerServiceAgent serviceAgent = new MockCustomerServiceAgent();

              return new CustomerViewModel(serviceAgent);

            }

        }

    }

5.View

用Silverlight User Controls,Pages or Child Windows创建一个View到Views文件夹里。

首先要把静态资源里的Locators绑定到View里的DataContext

DataContext="{Binding Source={StaticResource Locator}, Path=CustomerViewModel}"

在View上的单个元素需要指定一个在ViewModel里的属性(绑定源设置到DataContext)

<TextBox Grid.Row="0" Grid.Column="1" Height="30"

        Text="{Binding Path=Model.CustomerId}" />

<Button Content="New Customer" Grid.Row="3" Grid.ColumnSpan="2"

                Height="30" Width="100">

            <i:Interaction.Triggers>

                <i:EventTrigger EventName="Click">

                    <ei:CallMethodAction

[d8]                             TargetObject="{Binding}"

                            MethodName="NewCustomer"[d9] />

                </i:EventTrigger>

            </i:Interaction.Triggers>

        </Button>

MVVM总结

  • MVVMLight,它是一种MVVM的实现。自然它不是唯一的一种实现,但现在大家公认的是,它是比较好的一个实现。就我个人的体会来说,我用过微软提供的Prism中的MVVM特性,但老实说,可能Prism的目标太大了,所以在MVVM这个具体的点上,实在不是那么好用。
  • 不是说Prism不好,它与MVVMLight严格来说,不是一个重量级的产品。MVVMLight专注与MVVM的实现,自然更加灵活。
  • 用MVVM这种架构可以有效的分离表现层和功能层,增强它们之间的松散耦合性,使得美工人员和设计人员各自专注自己的领域,而且这种模式可以最大限度的开发表现层的东西,表现层的方式也可以用WPF、WP8来实现,是非常方便的架构。

 [d1]using SimpleMvvmToolkit;

 [d2]Model里必须添加该属性

 [d3]服务代理接口

 [d4]实现服务接口的类

 [d5]ViewModel

 [d6]用该集合的原因是成员发生改变后会自动通知系统

 [d7]定位器

 [d8]需要引用如下

xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"

 xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"

 

 [d9]NewCustomer是ViewModel里的方法NewCustomer()

posted @ 2015-05-03 12:21  HelloTiTi  阅读(336)  评论(0编辑  收藏  举报