WCF+EF 实战四:UI层MVP模式处理

来源:互联网 发布:vue.js radio 编辑:程序博客网 时间:2024/05/17 05:08

在本系列的第一篇中,我们曾经描述了本系统的整个实现结构,可以查看第一篇。

在客户端的实现我们将采用MVP模式来实现,就是将客户端再分为二层,UIpresenter,

UI主要是定义界面的元素及响应客户的操作。Presenter主要是对UI层响应客户端操作的业务处理。关于MVP的一些知识,如果不太清楚可以查看http://blog.csdn.net/greystar/archive/2008/12/01/3418307.aspx

 

MVP中的Model我们不需要实现了,因为WCF服务将会给我们提供相应的model.

下面我们新建一个类库Demo. Presentation,同时添加上次创建的WCF的服务的引用。(先要运行Demo.同时注意要点下图的高级,将返回的集合类型设为泛型List

 

 

由于我们的UI业务相当的简单,就是对Employee对象进行增删改查。因此首先我们定义

MVP中的View接口

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using Demo.Presentation.WCFService;

namespace Demo.Presentation

{

    public delegate void VoidEventHandler();

 

    public interface IUserView

    {

        /// <summary>

        /// 当前员工

        /// </summary>

        Employee CurrentEmployee { get; set; }

        /// <summary>

        /// 员工列表

        /// </summary>

        List<Employee> Users { set; }

        /// <summary>

        /// 新增事件

        /// </summary>

        event VoidEventHandler OnAddNewEmp;

        /// <summary>

        /// 删除

        /// </summary>

        event VoidEventHandler OnDeleteEmp;

        /// <summary>

        /// 更新

        /// </summary>

        event VoidEventHandler OnUpdateEmp;

 

        /// <summary>

        /// 初始事件

        /// </summary>

        event VoidEventHandler PrepareView;

    }

 

    /// <summary>

    /// 定义员工业务的操作

    /// </summary>

    public interface IUserPresenter

    {

        void AddNewUser();

        void DeleteUser();

        List<Employee> GetUsers();

        void UpdateUser();

    }

}

 

Presenter的真正实现:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using Demo.Presentation.WCFService;

namespace Demo.Presentation

{

    public class UserPresenter:IUserPresenter

    {

        private IUserView view = null;

        public UserPresenter(IUserView View)

        {

            view = View;

            view.PrepareView += new VoidEventHandler(view_PrepareView);

            view.OnAddNewEmp += new VoidEventHandler(AddNewUser);

            view.OnDeleteEmp += new VoidEventHandler(DeleteUser);

            view.OnUpdateEmp += new VoidEventHandler(UpdateUser);

        }

 

        void view_PrepareView()

        {

            view.Users = GetUsers();

        }

 

        #region IUserPresenter 成员

 

        public void AddNewUser()

        {

            using (EmployeeServiceClient client = new EmployeeServiceClient())

            {

                view.CurrentEmployee= client.Add(view.CurrentEmployee);

            }

        }

 

        public void DeleteUser()

        {

            using (EmployeeServiceClient client = new EmployeeServiceClient())

            {

                client.Delete(view.CurrentEmployee);

            }

        }

 

        public List<Employee> GetUsers()

        {

            using (EmployeeServiceClient client = new EmployeeServiceClient())

            {

                return client.GetEmployees();

            }

        }

 

        public void UpdateUser()

        {

            using (EmployeeServiceClient client = new EmployeeServiceClient())

            {

                client.Update(view.CurrentEmployee);

            }

        }

 

        #endregion

    }

    }

}

现在我们来实现客户端的UI。当然UI要响应用户的操作,会调用到Demo. Presentation。但其本身不会直接处理任何数据。

添加一个window类库 Demo.UI

 

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;

using Demo.Presentation.WCFService;

using Demo.Presentation;

namespace Demo.UI

{

    public partial class Form1 : Form,IUserView

    {

 

        IUserPresenter presenter = null;

        BindingSource bs = null;

        public Form1()

        {

            InitializeComponent();

            presenter = new UserPresenter(this);

            this.PrepareView();//初始化视图

        }

 

 

        #region IUserView 成员

        Employee _currentEmployee = null;

        public Employee CurrentEmployee

        {

            get

            {

                return _currentEmployee;

            }

            set

            {

                _currentEmployee = value;

            }

        }

 

        public List<Employee> Users

        {

            set {

                bs = new BindingSource();

                bs.DataSource = value;

                this.dataGridView1.DataSource = bs;

           

            }

        }

 

        public event VoidEventHandler OnAddNewEmp;

 

        public event VoidEventHandler OnDeleteEmp;

 

        public event VoidEventHandler OnUpdateEmp;

 

        public event VoidEventHandler PrepareView;

 

        #endregion

 

        private void cmdDelete_Click(object sender, EventArgs e)

        {

            if (SelectedEmployee != null)

            {//可以先确认一下是否删除

                OnDeleteEmp();

                bs.Remove(_currentEmployee);//完成后将对象从界面中移除

            }

 

        }

 

        private void cmdRefresh_Click(object sender, EventArgs e)

        {

            PrepareView();

        }

 

        private void cmdAdd_Click(object sender, EventArgs e)

        {

            _currentEmployee = new Employee();

            //将此对象传到其他窗口,完成编辑

            OnAddNewEmp();

            bs.Add(_currentEmployee); //新增完成后_currentEmployee对象就是从服务器传回来的对象,有状态,下次更新就不会有问题。

            //同时加入到界面中

        }

 

        private void cmdUpdate_Click(object sender, EventArgs e)

        {

            if (SelectedEmployee != null)

            {

                //此处可以将CurrentUser对象传给其他的窗体进行编辑。

                //省略

                OnUpdateEmp();

            }

        }

        /// <summary>

        /// 判断网格是否有选择的

        /// </summary>

        Employee SelectedEmployee

        {

            get

            {

                if (dataGridView1.SelectedRows.Count == 0)

                    return null;

                _currentEmployee = this.dataGridView1.SelectedRows[0].DataBoundItem as Employee;

                return _currentEmployee;

            }

        }

       

    }

}

我们的界面实现了IUserView接口,在界面里只处理最基本的一些操作,而数据访问的实现实际是是由IUserPresenter来完成的。当有用户操作时,只需引发一些相关的事件。如果要进行UI的移植,那么相应的工作量将会大大的减少。

同时将刚才在Demo.Presentation里的app.config复制到Demo.UI里,此时你可以运行程序了。当然你要记得先运行Demo.WCFHost,再运行Demo.UI

 

仅仅是一个DEMO相对来说比较的简单,实际在使用EF时真的很难用。很多最终的SQL语句我发觉都不是自己想要的那种简单的。搞得太复杂了。网上的资料也比较少,同时也遇到了很多的难题。以后我会讲一下EF中遇到的问题。

 

本示例的源码下载:http://download.csdn.net/source/831860