博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用MEF+MVVM light+WCF RIA Service实现的Sellthrough系统
阅读量:6859 次
发布时间:2019-06-26

本文共 6490 字,大约阅读时间需要 21 分钟。

  在csdn上承诺要分享一个使用Silverlight+MVVM+MEF实现一个项目,都过去一个月了,我还没开始。。。

最近试着去参考了很多文章和例子,今天就和大家分享一个简单的Sell Through系统,销售管理的那种。

代码下载:

使用到的MVVM framework:

2010080217080316.jpg

如果你对MEF没概念,建议看看这里:

开发环境介绍下:

VS2010英文旗舰版。

MS SQL Server2008 。

一个做零售类型的公司,最基本的几个主档有哪些? 首先是产品(product),是的,它是基础。然后围绕它的有商店(Shop),销售人员(sales),价格(Price),代理商(dealer),以及区域(主要有Province和City)。OK,有了这些基本的思想我们就可以看看它们的关系了。

 2010080217083234.jpg

数据模块的创建(Entity Data Model )

首先我们需要创建一个空的ADO.NET Entity Data Model,然后添加上面的Model进去。

 2010080217092244.jpg

如果你还没来得及学习Entity Framework 4我建议你可以从这里开始学点基础。

上面的Sellthrough.edmx创建好以后,接下来我们来添加Model以及它们的关系。

在设计模式下的空白处右键,点击添加可以看到添加Model的页面,我们添加一个Model叫Products。

2010080217093585.jpg 

接下来是为Products这个Model添加属性字段。分析下它主要应该有code,name,launchdate,createuser,createdate。添加到上面的Model后:

 2010080217102019.jpg                   

接着是创建其它表,都是以Products为中心,具体的创建过程我这里就不详细描述了。

创建好Models后,我们需要创建model之间的对应关系。以省份和城市之间1:N的关系创建为例说明如何创建:

 在Entity model的空白处右键,选择’Add->association’,如下图:

 2010080217103175.jpg

选择好第一个entity和第二个entity,默认的是1:N关系,就直接选择OK,创建完毕。

最终创建好的Entity data model如下:

 2010080217103921.jpg

那数据库呢?我们还没有数据库呢。还是得找空白地方,右键,选择’Generate Database from Model…’,如下图:

 2010080217104669.jpg

按照提示一步一步操作,就可以生成Sellthrough.edmx.sql,在选择数据库时注意下,因为我们需要新建一个数据库所以要选择New connection:

 2010080217110397.jpg

输入数据库名称’sellthrough’,提示你是否新增数据库,选择Yes:

 2010080217110987.jpg

完成上面的操作后,数据库脚本就会自动生成了。如下图:

 2010080217111815.jpg

接下来在SQL Server Manage Studio中打开这个脚本,执行下,数据库就OK了。

 2010080217112914.jpg

Domain Service的创建

在创建好数据库后,接下来我们来创建Domain Services。

有点点击这个project,选择新增,找到Domain Service控件,命名为SellThroughService,点击下一步:

 2010080217120148.jpg

选中这些实体后点击OK,Domain Service就创建完成。

到这里服务器端的工作基本上完成了。

接下来我们来看看如何设计客户端的结构。

 2010080217122152.jpg

Nicholas.SilverlightSellThrough.Data 是服务器端数据源的扩展部分,Data.Web工程中的WCF  Ria Service会连接到这个工程。同时它还包含一些验证方式的扩展功能等。

例如,Product,我们需要有它字段的验证功能,这些功能就写在Nicholas.SilverlightSellThrough.Data中。

 2010080217123256.jpg

Nicholas.SilverlightSellThrough.Common 主要存放了一些通用的方法和接口等。

例如Model的接口, ISellThroughModel.cs。

ViewModelTypes.cs中以常量方式定义了所有的ViewModel。方便后面的工程队ViewModel部分的操作。

Nicholas.SilverlightSellThrough.Model 是为MVVM模式定义的Model部分。

 2010080217132014.jpg

目前我们先定义AddNewProduct方法,RemoveProduct,SaveChangeAsync来实现产品的增删改操作。

Nicholas.SilverlightSellThrough.ViewModel:MVVM模式中的ViewModel部分定义在这个工程中。

目前我只定义了三个ViewModel:

 2010080217170412.jpg

它们分别实现全部产品的展示,新增产品和修改产品的功能。

最后一个是Nicholas.SilverlightSellThrough:很明显了它就是MVVM中存放View的部分,你可以把所有的View放到View文件夹。

 

 了解了整个架构后,

给大家介绍几个MVVM Light的概念

1. RelayCommand:

Silverlight 4中有了Command这个概念,使得MVVM的模式更加容易。你只需要在ViewModel中定义好你的RelayCommand,然后在View中通过Command来绑定ViewModel中定义好的RelayCommand。

2.Messager

在MVVM Light Toolkit中有个Messager类,就是靠它来让ViewModel和View来通信的。在这个项目中我们定义了AppMessages类来作为通用的一个通信类。

 

 
using
System;
using
System.IO;
using
System.Windows.Media.Imaging;
using
GalaSoft.MvvmLight.Messaging;
using
Nicholas.SilverlightSellThrough.Data.Web;
namespace
Nicholas.SilverlightSellThrough.Common
{
///
<summary>
///
class that defines all messages used in this application
///
</summary>
public
static
class
AppMessages
{
enum
MessageTypes
{
RaiseError,
PleaseConfirm,
EditProduct,
SubmitChanges,
StatusUpdate,
CancelChanges,
ExpriedProduct
}
public
static
class
RaiseErrorMessage
{
public
static
void
Send(Exception ex)
{
Messenger.Default.Send
<
Exception
>
(ex, MessageTypes.RaiseError);
}
public
static
void
Register(
object
recipient, Action
<
Exception
>
action)
{
Messenger.Default.Register
<
Exception
>
(recipient,MessageTypes.RaiseError,action);
}
}
public
static
class
PleaseConfirmMessage
{
public
static
void
Send(DialogMessage dialogMessage)
{
Messenger.Default.Send
<
DialogMessage
>
(dialogMessage,MessageTypes.PleaseConfirm);
}
public
static
void
Register(
object
recipient, Action
<
DialogMessage
>
action)
{
Messenger.Default.Register
<
DialogMessage
>
(recipient, MessageTypes.PleaseConfirm, action);
}
}
public
static
class
StatusUpdateMessage
{
public
static
void
Send(DialogMessage dialogMessage)
{
Messenger.Default.Send
<
DialogMessage
>
(dialogMessage, MessageTypes.StatusUpdate);
}
public
static
void
Register(
object
recipient, Action
<
DialogMessage
>
action)
{
Messenger.Default.Register
<
DialogMessage
>
(recipient, MessageTypes.StatusUpdate, action);
}
}
public
static
class
EditProductMessage
{
public
static
void
Send(Products product)
{
Messenger.Default.Send
<
Products
>
(product, MessageTypes.EditProduct);
}
public
static
void
Register(
object
recipient, Action
<
Products
>
action)
{
Messenger.Default.Register
<
Products
>
(recipient, MessageTypes.EditProduct, action);
}
}
public
static
class
SubmitChangesMessage
{
public
static
void
Send()
{
Messenger.Default.Send
<
Boolean
>
(
true
, MessageTypes.SubmitChanges);
}
public
static
void
Register(
object
recipient, Action
<
Boolean
>
action)
{
Messenger.Default.Register
<
Boolean
>
(recipient,MessageTypes.SubmitChanges,action);
}
}
public
static
class
CancelChangesMessage
{
public
static
void
Send()
{
Messenger.Default.Send
<
Boolean
>
(
true
, MessageTypes.CancelChanges);
}
public
static
void
Register(
object
recipient, Action
<
Boolean
>
action)
{
Messenger.Default.Register
<
Boolean
>
(recipient,MessageTypes.CancelChanges,action);
}
}
public
static
class
ExpriedProduct
{
public
static
void
Send()
{
Messenger.Default.Send
<
Boolean
>
(
true
, MessageTypes.ExpriedProduct);
}
public
static
void
Register(
object
recipient, Action
<
Boolean
>
action)
{
Messenger.Default.Register
<
Boolean
>
(recipient,MessageTypes.ExpriedProduct,action);
}
}
}
}

 

 

3. ICleanup接口:

当显示某个View时,先调用Cleanup方法清除数据:

 

在View中显示所有产品:

首先在数据库中插入几条product数据:

 2010080217162831.jpg

我们的目的就是使用MVVM模式把这些数据显示在DataGrid中。

第一步需要在Model中添加GetAllProductsAsync方法:

 public void GetAllProductsAsync()         {
            PerformQuery
(Context.GetProductsQuery(),GetAllProductsComplete);         }

 

第二步是在ViewModel工程中添加AllProductsViewModel:

 2010080217161431.jpg

在public Commands部分用到的就是上面提到的RelayCommand方法,submitCommand,CancelCommand等。它的作用好比是你在一个xaml页面中添加几个

Submit按钮和Cancel按钮,然后写在它后台的事件。

Load products的代码在ViewModel的构造函数中:

 2010080217154222.jpg

注意这里有个selectionchangedCommand,从名字上看得出来它主要是为了让View页面知道当前选中的是哪个product。

第三步也是最后一步就是添加View:

创建一个View,添加一个datagrid,数据绑定如下:

 2010080217151869.jpg

注意中间有个trigger,当selectionChanged事件发生时,执行ViewModel中的SelectionChangedCommand方法。

到目前为止我们还未用到MEF,也轮到它登场了。它让程序的扩展性真的是非常好。

在view的后台代码.cs文件中,首先需要使用MEF把AllProductsViewModel导入到View中:

 [Import(ViewModelTypes.AllProductsViewModel)]         public object ViewModel         {
            set             {
                DataContext = value;             }         }

 

然后在构造函数中使用CompositionInitializer来把ViewModel加载到页面。

   if (!ViewModelBase.IsInDesignModeStatic)             {                // Use MEF to load the view model                 CompositionInitializer.SatisfyImports(this);             }

 

最后一步别忘了,使用cleanup接口把当前的这个ViewModel从Messager管道中移除。

运行下看看效果:

 2010080217150522.jpg

上面有提到使用那个trigger来设定当前选中的product。那么我们可以使用这个trigger来让当鼠标选中某一行数据时下面显示它的详细信息,并且我们可以编辑它,也就是Editproduct部分。

也是添加Model部分的代码,ModelView部分的代码,最后添加一个View。

效果:

 2010080217145430.jpg

修改后保存信息,就可以同步更新到服务器端。

最后是新增页面:

 2010080217144322.jpg

具体的实现方法你可以看我提供的源代码。

转载地址:http://ofxyl.baihongyu.com/

你可能感兴趣的文章
Netty学习大纲
查看>>
OC中的私有方法
查看>>
20060427: 部分汉化Together Workflow Editor
查看>>
CentOS中配置VNC Server
查看>>
Table '.\mysql\proc' is marked as crashed and should be repaired 报错
查看>>
分享几段JavaScript
查看>>
C++中的多态和Objective-C中的“多态”
查看>>
js基础五
查看>>
构建执法阅读笔记01
查看>>
【Update】C# 批量插入数据 SqlBulkCopy
查看>>
剑指offer:合并两个排序的链表
查看>>
1602液晶显示实验
查看>>
HTTP慢速DOS(slow http denial of service attack)
查看>>
图片水印
查看>>
Quart2D的基本介绍
查看>>
Lua点号和冒号区别
查看>>
STL基础
查看>>
有没有人要贪吃蛇的代码,然而有....................
查看>>
Spring Data JPA 进阶
查看>>
linux的top命令参数详解
查看>>